mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-12-02 01:01:17 +00:00
* Refactor file event finisher into EventProcessor#onItemFinished EventProcessor: Add new unhandled event "FolderWatchStateChanged" * Perform ContentResolver.delete operations asynchronously (fixes #199)
This commit is contained in:
parent
c96786bcb9
commit
ae2e1874a4
1 changed files with 70 additions and 15 deletions
|
@ -1,6 +1,7 @@
|
||||||
package com.nutomic.syncthingandroid.service;
|
package com.nutomic.syncthingandroid.service;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
import android.content.AsyncQueryHandler;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -10,6 +11,7 @@ import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
@ -125,25 +127,27 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "ItemFinished":
|
case "ItemFinished":
|
||||||
String folder = (String) event.data.get("folder");
|
String action = (String) event.data.get("action");
|
||||||
|
String error = (String) event.data.get("error");
|
||||||
|
String folderId = (String) event.data.get("folder");
|
||||||
|
String relativeFilePath = (String) event.data.get("item");
|
||||||
|
|
||||||
|
// Lookup folder.path for the given folder.id if all fields were containted in the event.data.
|
||||||
String folderPath = null;
|
String folderPath = null;
|
||||||
for (Folder f : mRestApi.getFolders()) {
|
if (!TextUtils.isEmpty(action) &&
|
||||||
if (f.id.equals(folder)) {
|
!TextUtils.isEmpty(folderId) &&
|
||||||
folderPath = f.path;
|
!TextUtils.isEmpty(relativeFilePath)) {
|
||||||
|
for (Folder folder : mRestApi.getFolders()) {
|
||||||
|
if (folder.id.equals(folderId)) {
|
||||||
|
folderPath = folder.path;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File updatedFile = new File(folderPath, (String) event.data.get("item"));
|
}
|
||||||
if (!"delete".equals(event.data.get("action"))) {
|
if (!TextUtils.isEmpty(folderPath)) {
|
||||||
Log.i(TAG, "Rescanned file via MediaScanner: " + updatedFile.toString());
|
onItemFinished(action, error, new File(folderPath, relativeFilePath));
|
||||||
MediaScannerConnection.scanFile(mContext, new String[]{updatedFile.getPath()},
|
|
||||||
null, null);
|
|
||||||
} else {
|
} else {
|
||||||
// https://stackoverflow.com/a/29881556/1837158
|
Log.w(TAG, "ItemFinished: Failed to determine folder.path for folder.id=\"" + (TextUtils.isEmpty(folderId) ? "" : folderId) + "\"");
|
||||||
Log.i(TAG, "Deleted file from MediaStore: " + updatedFile.toString());
|
|
||||||
Uri contentUri = MediaStore.Files.getContentUri("external");
|
|
||||||
ContentResolver resolver = mContext.getContentResolver();
|
|
||||||
resolver.delete(contentUri, MediaStore.Images.ImageColumns.DATA + " LIKE ?",
|
|
||||||
new String[]{updatedFile.getPath()});
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "Ping":
|
case "Ping":
|
||||||
|
@ -156,6 +160,7 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener
|
||||||
case "FolderPaused":
|
case "FolderPaused":
|
||||||
case "FolderScanProgress":
|
case "FolderScanProgress":
|
||||||
case "FolderSummary":
|
case "FolderSummary":
|
||||||
|
case "FolderWatchStateChanged":
|
||||||
case "ItemStarted":
|
case "ItemStarted":
|
||||||
case "LocalIndexUpdated":
|
case "LocalIndexUpdated":
|
||||||
case "LoginAttempt":
|
case "LoginAttempt":
|
||||||
|
@ -285,4 +290,54 @@ public class EventProcessor implements Runnable, RestApi.OnReceiveEventListener
|
||||||
// Show notification.
|
// Show notification.
|
||||||
mNotificationHandler.showConsentNotification(notificationId, title, piAccept, piIgnore);
|
mNotificationHandler.showConsentNotification(notificationId, title, piAccept, piIgnore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Precondition: action != null
|
||||||
|
*/
|
||||||
|
private void onItemFinished(String action, String error, File updatedFile) {
|
||||||
|
String relativeFilePath = updatedFile.toString();
|
||||||
|
if (!TextUtils.isEmpty(error)) {
|
||||||
|
Log.e(TAG, "onItemFinished: Error \"" + error + "\" reported on file: " + relativeFilePath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case "delete": // file deleted
|
||||||
|
Log.i(TAG, "Deleting file from MediaStore: " + relativeFilePath);
|
||||||
|
Uri contentUri = MediaStore.Files.getContentUri("external");
|
||||||
|
ContentResolver resolver = mContext.getContentResolver();
|
||||||
|
LoggingAsyncQueryHandler asyncQueryHandler = new LoggingAsyncQueryHandler(resolver);
|
||||||
|
asyncQueryHandler.startDelete(
|
||||||
|
0, // this will be passed to "onUpdatedComplete#token"
|
||||||
|
relativeFilePath, // this will be passed to "onUpdatedComplete#cookie"
|
||||||
|
contentUri,
|
||||||
|
MediaStore.Images.ImageColumns.DATA + " LIKE ?",
|
||||||
|
new String[]{updatedFile.getPath()}
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case "update": // file contents changed
|
||||||
|
case "metadata": // file metadata changed but not contents
|
||||||
|
Log.i(TAG, "Rescanning file via MediaScanner: " + relativeFilePath);
|
||||||
|
MediaScannerConnection.scanFile(mContext, new String[]{updatedFile.getPath()},
|
||||||
|
null, null);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.w(TAG, "onItemFinished: Unhandled action \"" + action + "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LoggingAsyncQueryHandler extends AsyncQueryHandler {
|
||||||
|
|
||||||
|
public LoggingAsyncQueryHandler(ContentResolver contentResolver) {
|
||||||
|
super(contentResolver);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDeleteComplete(int token, Object cookie, int result) {
|
||||||
|
super.onUpdateComplete(token, cookie, result);
|
||||||
|
if (result == 1 && cookie != null) {
|
||||||
|
// ToDo Log.v(TAG, "onItemFinished: onDeleteComplete: [ok] file=" + cookie.toString() + ", token=" + Integer.toString(token));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue