diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f5ee79e1..1a22f63d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -34,6 +34,14 @@ android:name="android.app.lib_name" android:value="" /> + + + + + + \ No newline at end of file diff --git a/app/src/main/java/gallery/memories/NativeX.java b/app/src/main/java/gallery/memories/NativeX.java index f5279280..254a1a79 100644 --- a/app/src/main/java/gallery/memories/NativeX.java +++ b/app/src/main/java/gallery/memories/NativeX.java @@ -2,10 +2,7 @@ package gallery.memories; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; -import android.app.DownloadManager; -import android.content.Context; import android.graphics.Color; -import android.net.Uri; import android.os.Build; import android.util.Log; import android.view.View; @@ -19,26 +16,30 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.collection.ArrayMap; import java.io.ByteArrayInputStream; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import java.util.Map; +import gallery.memories.service.DownloadService; import gallery.memories.service.ImageService; import gallery.memories.service.TimelineQuery; public class NativeX { public static final String TAG = "NativeX"; - AppCompatActivity mActivity; - WebView mWebView; + protected final AppCompatActivity mActivity; + protected final WebView mWebView; - protected ImageService mImageService; - protected TimelineQuery mQuery; + protected final ImageService mImageService; + protected final TimelineQuery mQuery; + public static DownloadService mDlService; public NativeX(AppCompatActivity activity, WebView webView) { mActivity = activity; mWebView = webView; mImageService = new ImageService(activity); mQuery = new TimelineQuery(activity); + mDlService = new DownloadService(activity); } public WebResourceResponse handleRequest(final WebResourceRequest request) { @@ -91,20 +92,7 @@ public class NativeX { @JavascriptInterface public void downloadFromUrl(final String url, final String filename) { - Uri uri = Uri.parse(url); - DownloadManager manager = (DownloadManager) mActivity.getSystemService(Context.DOWNLOAD_SERVICE); - DownloadManager.Request request = new DownloadManager.Request(uri); - request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); - - // Copy all cookies from the webview to the download request - String cookies = android.webkit.CookieManager.getInstance().getCookie(url); - request.addRequestHeader("cookie", cookies); - - // Save the file to external storage - request.setDestinationInExternalPublicDir(android.os.Environment.DIRECTORY_DOWNLOADS, "memories/" + filename); - - // Start the download - manager.enqueue(request); + mDlService.queue(url, filename); } protected WebResourceResponse routerGet(final String path) throws Exception { @@ -122,6 +110,10 @@ public class NativeX { return makeResponse(mQuery.getDays()); } else if (path.matches("/api/days/\\d+$")) { return makeResponse(mQuery.getByDayId(Long.parseLong(parts[3]))); + } else if (path.matches("/api/share/url/.+$")) { + return makeResponse(mDlService.shareUrl(URLDecoder.decode(parts[4], "UTF-8"))); + } else if (path.matches("/api/share/blob/.+$")) { + return makeResponse(mDlService.shareBlobFromUrl(URLDecoder.decode(parts[4], "UTF-8"))); } throw new Exception("Not Found"); diff --git a/app/src/main/java/gallery/memories/service/DownloadBroadcastReceiver.java b/app/src/main/java/gallery/memories/service/DownloadBroadcastReceiver.java new file mode 100644 index 00000000..f0955862 --- /dev/null +++ b/app/src/main/java/gallery/memories/service/DownloadBroadcastReceiver.java @@ -0,0 +1,18 @@ +package gallery.memories.service; + +import android.app.DownloadManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.widget.Toast; + +import gallery.memories.NativeX; + +public class DownloadBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + if (NativeX.mDlService != null) { + NativeX.mDlService.runDownloadCallback(intent); + } + } +} diff --git a/app/src/main/java/gallery/memories/service/DownloadService.java b/app/src/main/java/gallery/memories/service/DownloadService.java new file mode 100644 index 00000000..debf89df --- /dev/null +++ b/app/src/main/java/gallery/memories/service/DownloadService.java @@ -0,0 +1,127 @@ +package gallery.memories.service; + +import android.app.DownloadManager; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.webkit.CookieManager; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.collection.ArrayMap; + +import java.util.Map; + +public class DownloadService { + class DownloadCallback { + public void onComplete(Intent intent) { + } + } + + final AppCompatActivity mActivity; + final Map mDownloads = new ArrayMap<>(); + + public DownloadService(AppCompatActivity activity) { + mActivity = activity; + } + + public void runDownloadCallback(Intent intent) { + if (mActivity.isDestroyed()) return; + + String action = intent.getAction(); + + if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) { + long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0); + synchronized (mDownloads) { + DownloadCallback callback = mDownloads.get(id); + if (callback != null) { + callback.onComplete(intent); + mDownloads.remove(id); + return; + } + } + + Toast.makeText(mActivity, "Download Complete", Toast.LENGTH_SHORT).show(); + } + } + + public long queue(final String url, final String filename) { + Uri uri = Uri.parse(url); + DownloadManager manager = (DownloadManager) mActivity.getSystemService(Context.DOWNLOAD_SERVICE); + DownloadManager.Request request = new DownloadManager.Request(uri); + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE); + + // Copy all cookies from the webview to the download request + String cookies = CookieManager.getInstance().getCookie(url); + request.addRequestHeader("cookie", cookies); + + if (!filename.equals("")) { + // Save the file to external storage + request.setDestinationInExternalPublicDir(android.os.Environment.DIRECTORY_DOWNLOADS, "memories/" + filename); + } + + // Start the download + return manager.enqueue(request); + } + + public Boolean shareUrl(final String url) { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, url); + mActivity.startActivity(Intent.createChooser(intent, null)); + return true; + } + + public Boolean shareBlobFromUrl(final String url) throws Exception { + final long id = queue(url, ""); + final Object sync = new Object(); + + synchronized (mDownloads) { + mDownloads.put(id, new DownloadCallback() { + @Override + public void onComplete(Intent intent) { + synchronized (sync) { + sync.notify(); + } + } + }); + } + + synchronized (sync) { + sync.wait(); + } + + // Get the URI of the downloaded file + String sUri = getDownloadedFileURI(id); + if (sUri == null) { + throw new Exception("Failed to download file"); + } + Uri uri = Uri.parse(sUri); + + // Get MIME type + ContentResolver cR = mActivity.getContentResolver(); + + // Create sharing intent + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType(mActivity.getContentResolver().getType(uri)); + intent.putExtra(Intent.EXTRA_STREAM, uri); + mActivity.startActivity(Intent.createChooser(intent, null)); + + return true; + } + + protected String getDownloadedFileURI(long downloadId) { + DownloadManager downloadManager = (DownloadManager) mActivity.getSystemService(Context.DOWNLOAD_SERVICE); + DownloadManager.Query query = new DownloadManager.Query(); + query.setFilterById(downloadId); + Cursor cursor = downloadManager.query(query); + if (cursor.moveToFirst()) { + int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI); + return cursor.getString(columnIndex); + } + cursor.close(); + return null; + } +}