Skip to content

Commit

Permalink
Merge pull request #126 from hannesa2/BackgroundCheck
Browse files Browse the repository at this point in the history
Background check
  • Loading branch information
hannesa2 authored Dec 10, 2022
2 parents c6b0d87 + 35b1554 commit 0aafd61
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 12 deletions.
1 change: 1 addition & 0 deletions githubAppUpdate/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'com.google.code.gson:gson:2.10'
implementation "androidx.work:work-runtime-ktx:2.7.1"

implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "androidx.appcompat:appcompat:1.5.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.net.Uri
Expand All @@ -13,13 +14,15 @@ import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.coroutineScope
import androidx.preference.PreferenceManager
import androidx.work.*
import info.hannes.github.model.Asset
import info.hannes.github.model.GithubVersion
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Response
import java.util.concurrent.TimeUnit


object AppUpdateHelper {
Expand All @@ -39,7 +42,14 @@ object AppUpdateHelper {
}
}

fun checkForNewVersion(
// silently in background
fun checkForNewVersion(activity: AppCompatActivity, gitRepoUrl: String, repeatTime : Long = 6, timeUnit: TimeUnit = TimeUnit.HOURS) {
val currentVersionName = activity.getVersionName()
DownloadWorker.run(activity, currentVersionName, gitRepoUrl, repeatTime, timeUnit)
}

// with user feedback
fun checkWithDialog(
activity: AppCompatActivity,
gitRepoUrl: String,
callback: ((String) -> Unit)? = null,
Expand Down Expand Up @@ -74,6 +84,34 @@ object AppUpdateHelper {
}
}

internal fun checkForNewVersionSilent(
appContext: Context,
currentVersionName: String,
gitRepoUrl: String
){
try {
val versionList = requestVersionsSync(gitRepoUrl)

versionList.body()?.firstOrNull()?.let { release ->
val assetApk = release.assets.find { it.name.endsWith("release.apk") }

Log.d("AppUpdateHelper", release.tagName + " > " + currentVersionName + " " + (release.tagName > currentVersionName))
val text = "You use version $currentVersionName\n" +
"and there is a new version ${release.tagName}\n"
if (release.tagName > currentVersionName) {
Notify.notification(appContext, text, "New version for '${getAppName(appContext)}'", assetApk, release)
}
}
} catch (e: Exception) {
Log.e("AppUpdateHelper", "git check deliver: ${e.message}")
}
}

private fun requestVersionsSync(gitRepoUrl: String): Response<MutableList<GithubVersion>> {
val client = GithubClient(HttpLoggingInterceptor.Level.BODY)
return client.github.getGithubVersions(gitRepoUrl.user(), gitRepoUrl.repo()).execute()
}

private suspend fun requestVersions(gitRepoUrl: String): Response<MutableList<GithubVersion>> {
val versionList = withContext(Dispatchers.Default) {
val client = GithubClient(HttpLoggingInterceptor.Level.BODY)
Expand All @@ -88,9 +126,10 @@ object AppUpdateHelper {
release: GithubVersion,
assetApk: Asset?
): AlertDialog? {

@Suppress("DEPRECATION")
val dialog = AlertDialog.Builder(activity)
.setTitle("New Version on Github")
.setTitle("New version for ${getAppName(activity)}")
.setMessage(
"You use version \n$currentVersionName\n" +
"and there is a new version \n${release.tagName}\n" +
Expand Down Expand Up @@ -119,4 +158,11 @@ object AppUpdateHelper {
}
return dialog.show()
}

private fun getAppName(context: Context): CharSequence {
val pm = context.applicationContext.packageManager
val appInfo: ApplicationInfo = pm.getApplicationInfo(context.applicationContext.packageName, 0)
return context.applicationContext.packageManager.getApplicationLabel(appInfo)
}

}
63 changes: 63 additions & 0 deletions githubAppUpdate/src/main/java/info/hannes/github/DownloadWorker.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package info.hannes.github

import android.content.Context
import androidx.work.*
import com.google.common.util.concurrent.ListenableFuture
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import java.util.concurrent.TimeUnit

class DownloadWorker(private val appContext: Context, workerParams: WorkerParameters) : CoroutineWorker(appContext, workerParams) {

override suspend fun doWork(): Result = coroutineScope {
// Get the input
val currentVersion = inputData.getString(CURRENT_VERSION)!!
val repoUrl = inputData.getString(REPO_URL)!!

val d = async {
check(currentVersion, repoUrl)
"done"
}
val value = d.await()

// output param is just a test
val outputData = workDataOf(Pair("state", value))
Result.success(outputData)
}

private fun check(currentVersion: String, repoUrl: String) {
AppUpdateHelper.checkForNewVersionSilent(appContext, currentVersion, repoUrl)
}

companion object {
fun run(context: Context, currentVersionName: String, repoUrl: String, repeatTime : Long, timeUnit: TimeUnit): ListenableFuture<MutableList<WorkInfo>> {
val data = workDataOf(
Pair(CURRENT_VERSION, currentVersionName),
Pair(REPO_URL, repoUrl)
)

val constraints = Constraints.Builder()
.setRequiresBatteryNotLow(true)
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresStorageNotLow(true)
.build()

val periodicWorkRequest = PeriodicWorkRequest
.Builder(DownloadWorker::class.java, repeatTime, timeUnit)
.setConstraints(constraints)
.setInputData(data)
.build()

WorkManager.getInstance(context)
.cancelUniqueWork(uniqueWorkName)
WorkManager.getInstance(context)
.enqueueUniquePeriodicWork(uniqueWorkName, ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest)

return WorkManager.getInstance(context).getWorkInfosForUniqueWork(uniqueWorkName)
}

const val CURRENT_VERSION = "CURRENT_VERSION"
const val REPO_URL = "REPO_URL"
private const val uniqueWorkName = "PWD"
}
}
75 changes: 75 additions & 0 deletions githubAppUpdate/src/main/java/info/hannes/github/Notify.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package info.hannes.github

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Build
import androidx.core.app.NotificationCompat
import info.hannes.github.model.Asset
import info.hannes.github.model.GithubVersion

internal object Notify {

private var MessageID = 120
private const val channelId = "chn-01"
private const val channelFireBaseMsg = "Channel appUpdate"

private val pendingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
} else {
PendingIntent.FLAG_UPDATE_CURRENT
}

fun notification(context: Context, messageString: String, notificationTitle: String, assetApk: Asset?, release: GithubVersion) {

//Get the notification manage which we will use to display the notification
val ns = Context.NOTIFICATION_SERVICE
val notificationManager = context.getSystemService(ns) as NotificationManager

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(channelId, channelFireBaseMsg, NotificationManager.IMPORTANCE_LOW)
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.RED
notificationChannel.enableVibration(true)
notificationChannel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)

notificationManager.createNotificationChannel(notificationChannel)
}

//get the notification title from the application's strings.xml file
val contentTitle: CharSequence = notificationTitle

//the message that will be displayed as the ticker
val ticker = "$contentTitle $messageString"

val showUrl = Uri.parse(release.htmlUrl)
val showPendingIntent = PendingIntent.getActivity(context, 0, Intent(Intent.ACTION_VIEW, showUrl), pendingIntentFlags)

//build the notification
val notificationCompat = NotificationCompat.Builder(context, channelId)
.setAutoCancel(true)
.setContentTitle(contentTitle)
.setContentIntent(showPendingIntent)
.setStyle(NotificationCompat.BigTextStyle().bigText(messageString))
.setContentText(messageString)
.setTicker(ticker)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.githib_logo)
.addAction(R.drawable.githib_logo, context.getString(R.string.showRelease), showPendingIntent)

assetApk?.let {
val uriUrl = Uri.parse(it.browserDownloadUrl)
val directPendingIntent = PendingIntent.getActivity(context, 0, Intent(Intent.ACTION_VIEW, uriUrl), pendingIntentFlags)
notificationCompat.addAction(R.drawable.githib_logo, context.getString(R.string.directDownload), directPendingIntent)
}

val notification = notificationCompat.build()

notificationManager.notify(MessageID, notification)
}

}
5 changes: 5 additions & 0 deletions githubAppUpdate/src/main/res/drawable/githib_logo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector android:alpha="0.9" android:height="64dp"
android:viewportHeight="1000" android:viewportWidth="1000"
android:width="64dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M500,22.1c-270.6,0 -490,219.4 -490,490C10,728.6 150.4,912.2 345.1,977c24.5,4.5 33.4,-10.6 33.4,-23.6c0,-11.7 -0.4,-50.3 -0.7,-91.2c-136.3,29.6 -165.1,-57.8 -165.1,-57.8c-22.3,-56.6 -54.4,-71.7 -54.4,-71.7c-44.5,-30.4 3.4,-29.8 3.4,-29.8c49.2,3.4 75.1,50.5 75.1,50.5c43.7,74.9 114.7,53.2 142.6,40.7c4.5,-31.6 17.1,-53.2 31.1,-65.4c-108.8,-12.4 -223.2,-54.4 -223.2,-242.2c0,-53.5 19.1,-97.2 50.4,-131.5c-5,-12.4 -21.9,-62.3 4.8,-129.7c0,0 41.1,-13.2 134.8,50.2c39.1,-10.9 81,-16.3 122.6,-16.5c41.6,0.2 83.6,5.6 122.7,16.5c93.5,-63.5 134.6,-50.2 134.6,-50.2c26.8,67.5 9.9,117.3 4.9,129.7c31.4,34.3 50.4,78 50.4,131.5c0,188.2 -114.6,229.7 -223.8,241.8c17.6,15.2 33.3,45 33.3,90.7c0,65.5 -0.7,118.3 -0.7,134.5c0,13 8.9,28.3 33.7,23.5C849.7,912.1 990,728.5 990,512.1C990,241.5 770.6,22.1 500,22.1z"/>
</vector>
13 changes: 10 additions & 3 deletions sample/src/main/java/info/hannes/github/sample/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,17 @@ class MainActivity : AppCompatActivity() {

AppUpdateHelper.checkForNewVersion(
this,
BuildConfig.GIT_REPOSITORY,
{ msg -> Log.d("result", msg) },
force = true // just to enable debugging, without you can only debug once a day
BuildConfig.GIT_REPOSITORY
)

binding.button.setOnClickListener {
AppUpdateHelper.checkWithDialog(
this,
BuildConfig.GIT_REPOSITORY,
{ msg -> Log.d("result", msg) },
force = true // just to enable debugging, without you can only debug once a day
)
}
}

}
24 changes: 17 additions & 7 deletions sample/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout android:id="@+id/main_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<FrameLayout
android:id="@+id/fragment_main"
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
android:id="@+id/button"
android:layout_gravity="center|center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="check"
tools:ignore="HardcodedText" />
</FrameLayout>

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
Expand All @@ -20,9 +35,4 @@

</com.google.android.material.appbar.AppBarLayout>

<FrameLayout
android:id="@+id/fragment_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

0 comments on commit 0aafd61

Please sign in to comment.