Loading app/src/main/java/io/eelo/appinstaller/updates/UpdatesNotifier.kt 0 → 100644 +62 −0 Original line number Diff line number Diff line package io.eelo.appinstaller.updates import android.app.Notification import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context import android.os.Build import android.support.v4.app.NotificationCompat import android.support.v4.app.NotificationManagerCompat import io.eelo.appinstaller.R import io.eelo.appinstaller.utils.Constants class UpdatesNotifier { private fun getNotification(context: Context, numberOfApps: Int, installAutomatically: Boolean): Notification { val notificationBuilder = NotificationCompat.Builder(context, Constants.UPDATES_NOTIFICATION_CHANNEL_ID) notificationBuilder.setSmallIcon(R.drawable.ic_app_updated_on) .priority = NotificationCompat.PRIORITY_DEFAULT if (numberOfApps == 1) { notificationBuilder.setContentTitle(context.resources.getQuantityString( R.plurals.updates_notification_title, 1, numberOfApps)) } else { notificationBuilder.setContentTitle(context.resources.getQuantityString( R.plurals.updates_notification_title, numberOfApps, numberOfApps)) } if (installAutomatically) { notificationBuilder.setContentText(context.getString(R.string.updates_notification_text, Constants.AUTOMATICALLY_INSTALL_UPDATES)) } else { notificationBuilder.setContentText(context.getString(R.string.updates_notification_text, Constants.MANUALLY_INSTALL_UPDATES)) } return notificationBuilder.build() } private fun createNotificationChannel(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val importance = NotificationManager.IMPORTANCE_DEFAULT val channel = NotificationChannel( Constants.UPDATES_NOTIFICATION_CHANNEL_ID, Constants.UPDATES_NOTIFICATION_CHANNEL_TITLE, importance) val notificationManager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) } } fun showNotification(context: Context, numberOfApps: Int, installAutomatically: Boolean) { with(NotificationManagerCompat.from(context)) { createNotificationChannel(context) notify(Constants.UPDATES_NOTIFICATION_ID, getNotification(context, numberOfApps, installAutomatically)) } } } app/src/main/java/io/eelo/appinstaller/updates/model/UpdatesWorker.kt +31 −0 Original line number Diff line number Diff line Loading @@ -2,23 +2,46 @@ package io.eelo.appinstaller.updates.model import android.content.Context import android.os.AsyncTask import android.preference.PreferenceManager import android.util.Log import androidx.work.Worker import androidx.work.WorkerParameters import io.eelo.appinstaller.R import io.eelo.appinstaller.application.model.Application import io.eelo.appinstaller.applicationmanager.ApplicationManager import io.eelo.appinstaller.updates.UpdatesNotifier import io.eelo.appinstaller.utils.Constants class UpdatesWorker(context: Context, params: WorkerParameters) : Worker(context, params), UpdatesWorkerInterface { private val TAG = "UpdatesWorker" private val blocker = Object() private var notifyAvailable = true private var installAutomatically = true private var wifiOnly = false override fun doWork(): Result { Log.i(TAG, "Checking for app updates") val applicationManager = ApplicationManager() applicationManager.start(applicationContext) loadOutdatedApplications(applicationManager) Log.i(TAG, "Ids of apps with pending updates written to file") return Result.success() } private fun loadPreferences() { val preferences = PreferenceManager.getDefaultSharedPreferences(applicationContext) notifyAvailable = preferences.getBoolean(applicationContext.getString( R.string.pref_update_notify_key), true) installAutomatically = preferences.getBoolean(applicationContext.getString( R.string.pref_update_install_automatically_key), true) wifiOnly = preferences.getBoolean(applicationContext.getString( R.string.pref_update_wifi_only_key), false) } private fun loadOutdatedApplications(applicationManager: ApplicationManager) { OutdatedApplicationsFinder(applicationContext.packageManager, this, applicationManager).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Loading @@ -29,7 +52,9 @@ class UpdatesWorker(context: Context, params: WorkerParameters) : Worker(context } override fun onApplicationsFound(applications: ArrayList<Application>) { Log.i(TAG, "${applications.size} app updates found") if (applications.size > 0) { loadPreferences() applicationContext.openFileOutput(Constants.OUTDATED_APPLICATIONS_FILENAME, Context.MODE_PRIVATE).use { applications.forEach { application -> Loading @@ -37,6 +62,12 @@ class UpdatesWorker(context: Context, params: WorkerParameters) : Worker(context } it.close() } if (notifyAvailable) { UpdatesNotifier().showNotification( applicationContext, applications.size, installAutomatically) } } synchronized(blocker) { blocker.notify() Loading app/src/main/java/io/eelo/appinstaller/utils/Constants.kt +5 −0 Original line number Diff line number Diff line Loading @@ -30,4 +30,9 @@ object Constants { // Updates const val OUTDATED_APPLICATIONS_FILENAME = "outdated_applications.txt" const val UPDATES_WORK_NAME = "updates_work" const val UPDATES_NOTIFICATION_ID = 76 const val UPDATES_NOTIFICATION_CHANNEL_ID = "updates_notification" const val UPDATES_NOTIFICATION_CHANNEL_TITLE = "App updates" const val AUTOMATICALLY_INSTALL_UPDATES = "will" const val MANUALLY_INSTALL_UPDATES = "will not" } app/src/main/res/values/strings.xml +5 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,11 @@ <!-- Updates --> <string name="updates_splash_title">All apps are up-to-date</string> <plurals name="updates_notification_title"> <item quantity="one">%1$d app update is available</item> <item quantity="other">%1$d app updates are available</item> </plurals> <string name="updates_notification_text">App updates %1$s be installed automatically.</string> <!-- Settings Fragment --> <string name="preference_updates_title">Updates</string> Loading Loading
app/src/main/java/io/eelo/appinstaller/updates/UpdatesNotifier.kt 0 → 100644 +62 −0 Original line number Diff line number Diff line package io.eelo.appinstaller.updates import android.app.Notification import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context import android.os.Build import android.support.v4.app.NotificationCompat import android.support.v4.app.NotificationManagerCompat import io.eelo.appinstaller.R import io.eelo.appinstaller.utils.Constants class UpdatesNotifier { private fun getNotification(context: Context, numberOfApps: Int, installAutomatically: Boolean): Notification { val notificationBuilder = NotificationCompat.Builder(context, Constants.UPDATES_NOTIFICATION_CHANNEL_ID) notificationBuilder.setSmallIcon(R.drawable.ic_app_updated_on) .priority = NotificationCompat.PRIORITY_DEFAULT if (numberOfApps == 1) { notificationBuilder.setContentTitle(context.resources.getQuantityString( R.plurals.updates_notification_title, 1, numberOfApps)) } else { notificationBuilder.setContentTitle(context.resources.getQuantityString( R.plurals.updates_notification_title, numberOfApps, numberOfApps)) } if (installAutomatically) { notificationBuilder.setContentText(context.getString(R.string.updates_notification_text, Constants.AUTOMATICALLY_INSTALL_UPDATES)) } else { notificationBuilder.setContentText(context.getString(R.string.updates_notification_text, Constants.MANUALLY_INSTALL_UPDATES)) } return notificationBuilder.build() } private fun createNotificationChannel(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val importance = NotificationManager.IMPORTANCE_DEFAULT val channel = NotificationChannel( Constants.UPDATES_NOTIFICATION_CHANNEL_ID, Constants.UPDATES_NOTIFICATION_CHANNEL_TITLE, importance) val notificationManager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) } } fun showNotification(context: Context, numberOfApps: Int, installAutomatically: Boolean) { with(NotificationManagerCompat.from(context)) { createNotificationChannel(context) notify(Constants.UPDATES_NOTIFICATION_ID, getNotification(context, numberOfApps, installAutomatically)) } } }
app/src/main/java/io/eelo/appinstaller/updates/model/UpdatesWorker.kt +31 −0 Original line number Diff line number Diff line Loading @@ -2,23 +2,46 @@ package io.eelo.appinstaller.updates.model import android.content.Context import android.os.AsyncTask import android.preference.PreferenceManager import android.util.Log import androidx.work.Worker import androidx.work.WorkerParameters import io.eelo.appinstaller.R import io.eelo.appinstaller.application.model.Application import io.eelo.appinstaller.applicationmanager.ApplicationManager import io.eelo.appinstaller.updates.UpdatesNotifier import io.eelo.appinstaller.utils.Constants class UpdatesWorker(context: Context, params: WorkerParameters) : Worker(context, params), UpdatesWorkerInterface { private val TAG = "UpdatesWorker" private val blocker = Object() private var notifyAvailable = true private var installAutomatically = true private var wifiOnly = false override fun doWork(): Result { Log.i(TAG, "Checking for app updates") val applicationManager = ApplicationManager() applicationManager.start(applicationContext) loadOutdatedApplications(applicationManager) Log.i(TAG, "Ids of apps with pending updates written to file") return Result.success() } private fun loadPreferences() { val preferences = PreferenceManager.getDefaultSharedPreferences(applicationContext) notifyAvailable = preferences.getBoolean(applicationContext.getString( R.string.pref_update_notify_key), true) installAutomatically = preferences.getBoolean(applicationContext.getString( R.string.pref_update_install_automatically_key), true) wifiOnly = preferences.getBoolean(applicationContext.getString( R.string.pref_update_wifi_only_key), false) } private fun loadOutdatedApplications(applicationManager: ApplicationManager) { OutdatedApplicationsFinder(applicationContext.packageManager, this, applicationManager).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Loading @@ -29,7 +52,9 @@ class UpdatesWorker(context: Context, params: WorkerParameters) : Worker(context } override fun onApplicationsFound(applications: ArrayList<Application>) { Log.i(TAG, "${applications.size} app updates found") if (applications.size > 0) { loadPreferences() applicationContext.openFileOutput(Constants.OUTDATED_APPLICATIONS_FILENAME, Context.MODE_PRIVATE).use { applications.forEach { application -> Loading @@ -37,6 +62,12 @@ class UpdatesWorker(context: Context, params: WorkerParameters) : Worker(context } it.close() } if (notifyAvailable) { UpdatesNotifier().showNotification( applicationContext, applications.size, installAutomatically) } } synchronized(blocker) { blocker.notify() Loading
app/src/main/java/io/eelo/appinstaller/utils/Constants.kt +5 −0 Original line number Diff line number Diff line Loading @@ -30,4 +30,9 @@ object Constants { // Updates const val OUTDATED_APPLICATIONS_FILENAME = "outdated_applications.txt" const val UPDATES_WORK_NAME = "updates_work" const val UPDATES_NOTIFICATION_ID = 76 const val UPDATES_NOTIFICATION_CHANNEL_ID = "updates_notification" const val UPDATES_NOTIFICATION_CHANNEL_TITLE = "App updates" const val AUTOMATICALLY_INSTALL_UPDATES = "will" const val MANUALLY_INSTALL_UPDATES = "will not" }
app/src/main/res/values/strings.xml +5 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,11 @@ <!-- Updates --> <string name="updates_splash_title">All apps are up-to-date</string> <plurals name="updates_notification_title"> <item quantity="one">%1$d app update is available</item> <item quantity="other">%1$d app updates are available</item> </plurals> <string name="updates_notification_text">App updates %1$s be installed automatically.</string> <!-- Settings Fragment --> <string name="preference_updates_title">Updates</string> Loading