Add single delete API
parent
93ee281eee
commit
22ed3b3cb0
|
@ -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+$")) {
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue