diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 676292b..6e1accd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -88,6 +88,12 @@ + + + + + + () private var lastNotificationId = 0 inner class LocalBinder : Binder() { @@ -39,6 +39,7 @@ class FileOperationService : Service() { } private fun showNotification(message: Int, total: Int): FileOperationNotification { + ++lastNotificationId if (!::notificationManager.isInitialized){ notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager } @@ -49,13 +50,35 @@ class FileOperationService : Service() { } else { Notification.Builder(this) } + val cancelIntent = Intent(this, NotificationBroadcastReceiver::class.java).apply { + val bundle = Bundle() + bundle.putBinder("binder", LocalBinder()) + bundle.putInt("notificationId", lastNotificationId) + putExtra("bundle", bundle) + action = ACTION_CANCEL + } + val cancelPendingIntent = PendingIntent.getBroadcast(this, 0, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT) + val notificationAction = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Notification.Action.Builder( + Icon.createWithResource(this, R.drawable.icon_close), + getString(R.string.cancel), + cancelPendingIntent + ) + } else { + Notification.Action.Builder( + R.drawable.icon_close, + getString(R.string.cancel), + cancelPendingIntent + ) + } notificationBuilder - .setOngoing(true) .setContentTitle(getString(message)) .setContentText("0/$total") .setSmallIcon(R.mipmap.icon_launcher) + .setOngoing(true) .setProgress(total, 0, false) - ++lastNotificationId + .addAction(notificationAction.build()) + notifications[lastNotificationId] = false notificationManager.notify(lastNotificationId, notificationBuilder.build()) return FileOperationNotification(notificationBuilder, lastNotificationId) } @@ -71,6 +94,10 @@ class FileOperationService : Service() { notificationManager.cancel(notification.notificationId) } + fun cancelOperation(notificationId: Int){ + notifications[notificationId] = true + } + private fun copyFile(srcPath: String, dstPath: String, remoteGocryptfsVolume: GocryptfsVolume = gocryptfsVolume): Boolean { var success = true val srcHandleId = remoteGocryptfsVolume.openReadMode(srcPath) @@ -105,6 +132,10 @@ class FileOperationService : Service() { val notification = showNotification(R.string.file_op_copy_msg, items.size) var failedItem: String? = null for (i in 0 until items.size){ + if (notifications[notification.notificationId]!!){ + cancelNotification(notification) + return@Thread + } if (items[i].explorerElement.isDirectory){ if (!gocryptfsVolume.pathExists(items[i].dstPath!!)) { if (!gocryptfsVolume.mkdir(items[i].dstPath!!)) { @@ -133,6 +164,10 @@ class FileOperationService : Service() { val mergedFolders = ArrayList() var failedItem: String? = null for (i in 0 until items.size){ + if (notifications[notification.notificationId]!!){ + cancelNotification(notification) + return@Thread + } if (items[i].explorerElement.isDirectory && gocryptfsVolume.pathExists(items[i].dstPath!!)){ //folder will be merged mergedFolders.add(items[i].explorerElement.fullPath) } else { @@ -146,6 +181,10 @@ class FileOperationService : Service() { } if (failedItem == null){ for (i in 0 until mergedFolders.size) { + if (notifications[notification.notificationId]!!){ + cancelNotification(notification) + return@Thread + } if (!gocryptfsVolume.rmdir(mergedFolders[i])){ failedItem = mergedFolders[i] break @@ -164,6 +203,10 @@ class FileOperationService : Service() { val notification = showNotification(R.string.file_op_import_msg, items.size) var failedIndex = -1 for (i in 0 until items.size) { + if (notifications[notification.notificationId]!!){ + cancelNotification(notification) + return@Thread + } try { if (!gocryptfsVolume.importFile(this, uris[i], items[i].dstPath!!)){ failedIndex = i @@ -191,6 +234,10 @@ class FileOperationService : Service() { val notification = showNotification(R.string.file_op_wiping_msg, uris.size) var errorMsg: String? = null for (i in uris.indices) { + if (notifications[notification.notificationId]!!){ + cancelNotification(notification) + return@Thread + } errorMsg = Wiper.wipe(this, uris[i]) if (errorMsg == null) { updateNotificationProgress(notification, i, uris.size) @@ -240,6 +287,10 @@ class FileOperationService : Service() { val notification = showNotification(R.string.file_op_export_msg, items.size) var failedItem: String? = null for (i in items.indices) { + if (notifications[notification.notificationId]!!){ + cancelNotification(notification) + return@Thread + } failedItem = if (items[i].isDirectory) { recursiveExportDirectory(items[i].fullPath, treeDocumentFile) } else { diff --git a/app/src/main/java/sushi/hardcore/droidfs/file_operations/NotificationBroadcastReceiver.kt b/app/src/main/java/sushi/hardcore/droidfs/file_operations/NotificationBroadcastReceiver.kt new file mode 100644 index 0000000..e10840c --- /dev/null +++ b/app/src/main/java/sushi/hardcore/droidfs/file_operations/NotificationBroadcastReceiver.kt @@ -0,0 +1,19 @@ +package sushi.hardcore.droidfs.file_operations + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent + +class NotificationBroadcastReceiver: BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action == FileOperationService.ACTION_CANCEL){ + intent.getBundleExtra("bundle")?.let { bundle -> + (bundle.getBinder("binder") as FileOperationService.LocalBinder?)?.let { binder -> + val notificationId = bundle.getInt("notificationId") + val service = binder.getService() + service.cancelOperation(notificationId) + } + } + } + } +} \ No newline at end of file