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