Fixed updater on Android N. Closes #592 (#595)

This commit is contained in:
Bram van de Kerkhof 2016-12-21 00:34:31 +01:00 committed by GitHub
parent 2241a0b2de
commit 7fdd2cacd7
5 changed files with 47 additions and 57 deletions

View file

@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.updater
import android.app.IntentService import android.app.IntentService
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.support.v4.app.NotificationCompat import android.support.v4.app.NotificationCompat
import eu.kanade.tachiyomi.Constants.NOTIFICATION_UPDATER_ID import eu.kanade.tachiyomi.Constants.NOTIFICATION_UPDATER_ID
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@ -36,21 +35,6 @@ class UpdateDownloaderService : IntentService(UpdateDownloaderService::class.jav
} }
context.startService(intent) context.startService(intent)
} }
/**
* Prompt user with apk install intent
* @param context context
* @param file file of apk that is installed
*/
fun installAPK(context: Context, file: File) {
// Prompt install interface
val intent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive")
// Without this flag android returned a intent error!
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
context.startActivity(intent)
}
} }
/** /**
@ -106,7 +90,7 @@ class UpdateDownloaderService : IntentService(UpdateDownloaderService::class.jav
throw Exception("Unsuccessful response") throw Exception("Unsuccessful response")
} }
val installIntent = UpdateNotificationReceiver.installApkIntent(ctx, apkFile.absolutePath) val installIntent = UpdateNotificationReceiver.installApkIntent(ctx, apkFile)
// Prompt the user to install the new update. // Prompt the user to install the new update.
NotificationCompat.Builder(this).update { NotificationCompat.Builder(this).update {

View file

@ -4,6 +4,10 @@ import android.app.PendingIntent
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri
import android.os.Build
import android.support.v4.content.FileProvider
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.Constants.NOTIFICATION_UPDATER_ID import eu.kanade.tachiyomi.Constants.NOTIFICATION_UPDATER_ID
import eu.kanade.tachiyomi.util.notificationManager import eu.kanade.tachiyomi.util.notificationManager
import java.io.File import java.io.File
@ -12,34 +16,14 @@ class UpdateNotificationReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
when (intent.action) { when (intent.action) {
ACTION_INSTALL_APK -> {
UpdateDownloaderService.installAPK(context,
File(intent.getStringExtra(EXTRA_FILE_LOCATION)))
cancelNotification(context)
}
ACTION_DOWNLOAD_UPDATE -> UpdateDownloaderService.downloadUpdate(context,
intent.getStringExtra(UpdateDownloaderService.EXTRA_DOWNLOAD_URL))
ACTION_CANCEL_NOTIFICATION -> cancelNotification(context) ACTION_CANCEL_NOTIFICATION -> cancelNotification(context)
} }
} }
fun cancelNotification(context: Context) {
context.notificationManager.cancel(NOTIFICATION_UPDATER_ID)
}
companion object { companion object {
// Install apk action
const val ACTION_INSTALL_APK = "eu.kanade.INSTALL_APK"
// Download apk action
const val ACTION_DOWNLOAD_UPDATE = "eu.kanade.RETRY_DOWNLOAD"
// Cancel notification action // Cancel notification action
const val ACTION_CANCEL_NOTIFICATION = "eu.kanade.CANCEL_NOTIFICATION" const val ACTION_CANCEL_NOTIFICATION = "eu.kanade.CANCEL_NOTIFICATION"
// Absolute path of apk file
const val EXTRA_FILE_LOCATION = "file_location"
fun cancelNotificationIntent(context: Context): PendingIntent { fun cancelNotificationIntent(context: Context): PendingIntent {
val intent = Intent(context, UpdateNotificationReceiver::class.java).apply { val intent = Intent(context, UpdateNotificationReceiver::class.java).apply {
action = ACTION_CANCEL_NOTIFICATION action = ACTION_CANCEL_NOTIFICATION
@ -47,20 +31,39 @@ class UpdateNotificationReceiver : BroadcastReceiver() {
return PendingIntent.getBroadcast(context, 0, intent, 0) return PendingIntent.getBroadcast(context, 0, intent, 0)
} }
fun installApkIntent(context: Context, path: String): PendingIntent { /**
val intent = Intent(context, UpdateNotificationReceiver::class.java).apply { * Prompt user with apk install intent
action = ACTION_INSTALL_APK *
putExtra(EXTRA_FILE_LOCATION, path) * @param context context
* @param file file of apk that is installed
*/
fun installApkIntent(context: Context, file: File): PendingIntent {
val intent = Intent(Intent.ACTION_VIEW).apply {
val uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file)
else Uri.fromFile(file)
setDataAndType(uri, "application/vnd.android.package-archive")
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
} }
return PendingIntent.getBroadcast(context, 0, intent, 0) cancelNotification(context)
return PendingIntent.getActivity(context, 0, intent, 0)
} }
/**
* Downloads a new update and let the user install the new version from a notification.
*
* @param context the application context.
* @param url the url to the new update.
*/
fun downloadApkIntent(context: Context, url: String): PendingIntent { fun downloadApkIntent(context: Context, url: String): PendingIntent {
val intent = Intent(context, UpdateNotificationReceiver::class.java).apply { val intent = Intent(context, UpdateDownloaderService::class.java).apply {
action = ACTION_DOWNLOAD_UPDATE
putExtra(UpdateDownloaderService.EXTRA_DOWNLOAD_URL, url) putExtra(UpdateDownloaderService.EXTRA_DOWNLOAD_URL, url)
} }
return PendingIntent.getBroadcast(context, 0, intent, 0) return PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
fun cancelNotification(context: Context) {
context.notificationManager.cancel(NOTIFICATION_UPDATER_ID)
} }
} }

View file

@ -45,14 +45,14 @@ class ImageNotificationReceiver : BroadcastReceiver() {
* Called to start share intent to share image * Called to start share intent to share image
* *
* @param context context of application * @param context context of application
* @param path path of file * @param file file that contains image
*/ */
internal fun shareImageIntent(context: Context, path: String): PendingIntent { internal fun shareImageIntent(context: Context, file: File): PendingIntent {
val intent = Intent(Intent.ACTION_SEND).apply { val intent = Intent(Intent.ACTION_SEND).apply {
val uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", File(path)) val uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file)
putExtra(Intent.EXTRA_STREAM, uri) putExtra(Intent.EXTRA_STREAM, uri)
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
type = "image/*" type = "image/*"
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
} }
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
} }
@ -61,15 +61,15 @@ class ImageNotificationReceiver : BroadcastReceiver() {
* Called to show image in gallery application * Called to show image in gallery application
* *
* @param context context of application * @param context context of application
* @param path path of file * @param file file that contains image
*/ */
internal fun showImageIntent(context: Context, path: String): PendingIntent { internal fun showImageIntent(context: Context, file: File): PendingIntent {
val intent = Intent(Intent.ACTION_VIEW).apply { val intent = Intent(Intent.ACTION_VIEW).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION val uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file)
val uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", File(path))
setDataAndType(uri, "image/*") setDataAndType(uri, "image/*")
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
} }
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) return PendingIntent.getActivity(context, 0, intent, 0)
} }
internal fun deleteImageIntent(context: Context, path: String, notificationId: Int): PendingIntent { internal fun deleteImageIntent(context: Context, path: String, notificationId: Int): PendingIntent {

View file

@ -58,11 +58,11 @@ class ImageNotifier(private val context: Context) {
if (!mActions.isEmpty()) if (!mActions.isEmpty())
mActions.clear() mActions.clear()
setContentIntent(ImageNotificationReceiver.showImageIntent(context, file.absolutePath)) setContentIntent(ImageNotificationReceiver.showImageIntent(context, file))
// Share action // Share action
addAction(R.drawable.ic_share_grey_24dp, addAction(R.drawable.ic_share_grey_24dp,
context.getString(R.string.action_share), context.getString(R.string.action_share),
ImageNotificationReceiver.shareImageIntent(context, file.absolutePath)) ImageNotificationReceiver.shareImageIntent(context, file))
// Delete action // Delete action
addAction(R.drawable.ic_delete_grey_24dp, addAction(R.drawable.ic_delete_grey_24dp,
context.getString(R.string.action_delete), context.getString(R.string.action_delete),

View file

@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<paths> <paths>
<external-path name="ext_files" path="." /> <external-path name="ext_files" path="." />
<external-cache-path
name="ext_cache_files"
path="."/>
</paths> </paths>