Add single delete API

pull/653/merge
Varun Patil 2023-05-10 12:47:26 -07:00
parent 93ee281eee
commit 22ed3b3cb0
2 changed files with 73 additions and 8 deletions

View File

@ -2,7 +2,6 @@ package gallery.memories;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import android.app.Activity;
import android.app.DownloadManager; import android.app.DownloadManager;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
@ -16,6 +15,7 @@ import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse; import android.webkit.WebResourceResponse;
import android.webkit.WebView; import android.webkit.WebView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.collection.ArrayMap; import androidx.collection.ArrayMap;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -26,13 +26,13 @@ import gallery.memories.service.TimelineQuery;
public class NativeX { public class NativeX {
public static final String TAG = "NativeX"; public static final String TAG = "NativeX";
Activity mActivity; AppCompatActivity mActivity;
WebView mWebView; WebView mWebView;
protected ImageService mImageService; protected ImageService mImageService;
protected TimelineQuery mQuery; protected TimelineQuery mQuery;
public NativeX(Activity activity, WebView webView) { public NativeX(AppCompatActivity activity, WebView webView) {
mActivity = activity; mActivity = activity;
mWebView = webView; mWebView = webView;
mImageService = new ImageService(activity); mImageService = new ImageService(activity);
@ -112,8 +112,10 @@ public class NativeX {
return makeResponse(mImageService.getPreview(Long.parseLong(parts[3])), "image/jpeg"); return makeResponse(mImageService.getPreview(Long.parseLong(parts[3])), "image/jpeg");
} else if (path.matches("^/image/full/\\d+$")) { } else if (path.matches("^/image/full/\\d+$")) {
return makeResponse(mImageService.getFull(Long.parseLong(parts[3])), "image/jpeg"); return makeResponse(mImageService.getFull(Long.parseLong(parts[3])), "image/jpeg");
} else if (path.matches("^/image/info/\\d+$")) { } else if (path.matches("^/api/image/info/\\d+$")) {
return makeResponse(mQuery.getImageInfo(Long.parseLong(parts[3]))); return makeResponse(mQuery.getImageInfo(Long.parseLong(parts[4])));
} else if (path.matches("^/api/image/delete/\\d+$")) {
return makeResponse(mQuery.delete(Long.parseLong(parts[4])));
} else if (path.matches("^/api/days$")) { } else if (path.matches("^/api/days$")) {
return makeResponse(mQuery.getDays()); return makeResponse(mQuery.getDays());
} else if (path.matches("/api/days/\\d+$")) { } else if (path.matches("/api/days/\\d+$")) {

View File

@ -1,14 +1,22 @@
package gallery.memories.service; package gallery.memories.service;
import android.content.Context; import android.app.Activity;
import android.app.PendingIntent;
import android.content.ContentUris;
import android.database.Cursor; import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.icu.text.SimpleDateFormat; import android.icu.text.SimpleDateFormat;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.IntentSenderRequest;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.collection.ArraySet; import androidx.collection.ArraySet;
import androidx.exifinterface.media.ExifInterface; import androidx.exifinterface.media.ExifInterface;
@ -19,19 +27,31 @@ import org.json.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException; import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
public class TimelineQuery { public class TimelineQuery {
final static String TAG = "TimelineQuery"; final static String TAG = "TimelineQuery";
Context mCtx; AppCompatActivity mCtx;
SQLiteDatabase mDb; SQLiteDatabase mDb;
public TimelineQuery(Context context) { boolean deleting = false;
ActivityResultLauncher<IntentSenderRequest> deleteIntentLauncher;
ActivityResult deleteResult;
public TimelineQuery(AppCompatActivity context) {
mCtx = context; mCtx = context;
mDb = new DbService(context).getWritableDatabase(); mDb = new DbService(context).getWritableDatabase();
deleteIntentLauncher = mCtx.registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), result -> {
synchronized (deleteIntentLauncher) {
deleteResult = result;
deleteIntentLauncher.notify();
}
});
fullSyncDb(); fullSyncDb();
} }
@ -257,6 +277,46 @@ public class TimelineQuery {
} }
} }
public JSONObject delete(long id) throws Exception {
synchronized (this) {
if (deleting) {
throw new Exception("Already deleting another set of images");
}
deleting = true;
}
try {
// Delete file with media store
Uri collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// Delete with media store
Uri uri = ContentUris.withAppendedId(collection, id);
PendingIntent intent = MediaStore.createTrashRequest(mCtx.getContentResolver(), Collections.singletonList(uri), true);
deleteIntentLauncher.launch(new IntentSenderRequest.Builder(intent.getIntentSender()).build());
// Wait for response
synchronized (deleteIntentLauncher) {
deleteIntentLauncher.wait();
}
// Throw if canceled or failed
if (deleteResult.getResultCode() != Activity.RESULT_OK) {
throw new Exception("Delete canceled or failed");
}
} else {
// Delete with media store
Uri uri = ContentUris.withAppendedId(collection, id);
mCtx.getContentResolver().delete(uri, null, null);
}
return new JSONObject().put("message", "ok");
} finally {
synchronized (this) {
deleting = false;
}
}
}
protected void fullSyncDb() { protected void fullSyncDb() {
Uri collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; Uri collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
@ -332,5 +392,8 @@ public class TimelineQuery {
Log.v(TAG, "Inserted file to local DB: " + id + " / " + name + " / " + dayId); Log.v(TAG, "Inserted file to local DB: " + id + " / " + name + " / " + dayId);
} }
} }
// Clean up stale files
mDb.execSQL("DELETE FROM images WHERE flag = 1");
} }
} }