add Stop action to download notifications
This commit is contained in:
parent
ae9364ad7e
commit
8fcf135280
4 changed files with 107 additions and 33 deletions
2
app
2
app
|
@ -1 +1 @@
|
|||
Subproject commit 32c1770c34ecc5e80c5542aeb64ff11312704cea
|
||||
Subproject commit 46bfbd242a841f770a59ec88f9c7fbd94e5a06da
|
|
@ -10,6 +10,7 @@ import android.net.Uri;
|
|||
import android.os.Build;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
|
@ -31,6 +32,8 @@ public class DownloadManager {
|
|||
|
||||
private List<String> completedDownloads = new ArrayList<String>();
|
||||
|
||||
private Map<String, String> downloadIdOutpointsMap = new HashMap<String, String>();
|
||||
|
||||
// maintain a map of uris to writtenBytes, so that we check if it's changed and don't flood RN with update events every 500ms
|
||||
private Map<String, Double> writtenDownloadBytes = new HashMap<String, Double>();
|
||||
|
||||
|
@ -144,7 +147,15 @@ public class DownloadManager {
|
|||
}
|
||||
}
|
||||
|
||||
public void startDownload(String id, String filename) {
|
||||
private Intent getDeleteDownloadIntent(String uri) {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(LbrynetService.ACTION_DELETE_DOWNLOAD);
|
||||
intent.putExtra("uri", uri);
|
||||
intent.putExtra("nativeDelete", true);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public void startDownload(String id, String filename, String outpoint) {
|
||||
if (filename == null || filename.trim().length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -152,20 +163,26 @@ public class DownloadManager {
|
|||
synchronized (this) {
|
||||
if (!isDownloadActive(id)) {
|
||||
activeDownloads.add(id);
|
||||
downloadIdOutpointsMap.put(id, outpoint);
|
||||
}
|
||||
|
||||
createNotificationChannel();
|
||||
createNotificationGroup();
|
||||
|
||||
PendingIntent stopDownloadIntent = PendingIntent.getBroadcast(context, 0, getDeleteDownloadIntent(id), PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
|
||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
|
||||
// The file URI is used as the unique ID
|
||||
builder.setContentIntent(getLaunchPendingIntent(id, context))
|
||||
builder.setColor(ContextCompat.getColor(context, R.color.lbryGreen))
|
||||
.setContentIntent(getLaunchPendingIntent(id, context))
|
||||
.setContentTitle(String.format("Downloading %s", truncateFilename(filename)))
|
||||
.setGroup(GROUP_DOWNLOADS)
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
.setProgress(MAX_PROGRESS, 0, false)
|
||||
.setSmallIcon(android.R.drawable.stat_sys_download);
|
||||
.setSmallIcon(android.R.drawable.stat_sys_download)
|
||||
.setOngoing(true)
|
||||
.addAction(android.R.drawable.ic_menu_close_clear_cancel, "Stop", stopDownloadIntent);
|
||||
|
||||
int notificationId = getNotificationId(id);
|
||||
downloadIdNotificationIdMap.put(id, notificationId);
|
||||
|
@ -194,9 +211,13 @@ public class DownloadManager {
|
|||
if (builders.containsKey(notificationId)) {
|
||||
builder = builders.get(notificationId);
|
||||
} else {
|
||||
PendingIntent stopDownloadIntent = PendingIntent.getBroadcast(context, 0, getDeleteDownloadIntent(id), PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
|
||||
builder.setContentTitle(String.format("Downloading %s", truncateFilename(filename)))
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW);
|
||||
builder.setColor(ContextCompat.getColor(context, R.color.lbryGreen))
|
||||
.setContentTitle(String.format("Downloading %s", truncateFilename(filename)))
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
.setOngoing(true)
|
||||
.addAction(android.R.drawable.ic_menu_close_clear_cancel, "Stop", stopDownloadIntent);
|
||||
builders.put(notificationId, builder);
|
||||
}
|
||||
|
||||
|
@ -213,7 +234,9 @@ public class DownloadManager {
|
|||
.setContentText(String.format("%s", formatBytes(totalBytes)))
|
||||
.setGroup(GROUP_DOWNLOADS)
|
||||
.setProgress(0, 0, false)
|
||||
.setSmallIcon(android.R.drawable.stat_sys_download_done);
|
||||
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||
.setOngoing(false);
|
||||
builder.mActions.clear();
|
||||
notificationManager.notify(notificationId, builder.build());
|
||||
|
||||
if (downloadIdNotificationIdMap.containsKey(id)) {
|
||||
|
@ -258,11 +281,13 @@ public class DownloadManager {
|
|||
.setContentText(String.format("%s", formatBytes(totalBytes)))
|
||||
.setGroup(GROUP_DOWNLOADS)
|
||||
.setProgress(0, 0, false)
|
||||
.setSmallIcon(android.R.drawable.stat_sys_download_done);
|
||||
notificationManager.notify(notificationId, builder.build());
|
||||
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||
.setOngoing(false);
|
||||
builder.mActions.clear();
|
||||
notificationManager.notify(notificationId, builder.build());
|
||||
|
||||
// If there are no more downloads and the group exists, set the icon to stop animating
|
||||
checkGroupDownloadIcon(notificationManager);
|
||||
// If there are no more downloads and the group exists, set the icon to stop animating
|
||||
checkGroupDownloadIcon(notificationManager);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,11 +320,22 @@ public class DownloadManager {
|
|||
return completedDownloads;
|
||||
}
|
||||
|
||||
public String getOutpointForDownload(String uri) {
|
||||
if (downloadIdOutpointsMap.containsKey(uri)) {
|
||||
return downloadIdOutpointsMap.get(uri);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void deleteDownloadUri(String uri) {
|
||||
synchronized (this) {
|
||||
activeDownloads.remove(uri);
|
||||
completedDownloads.remove(uri);
|
||||
|
||||
if (downloadIdOutpointsMap.containsKey(uri)) {
|
||||
downloadIdOutpointsMap.remove(uri);
|
||||
}
|
||||
if (downloadIdNotificationIdMap.containsKey(uri)) {
|
||||
removeDownloadNotification(uri);
|
||||
}
|
||||
|
|
|
@ -123,7 +123,8 @@ public class LbrynetService extends PythonService {
|
|||
}
|
||||
} else if (ACTION_DELETE_DOWNLOAD.equals(action)) {
|
||||
String uri = intent.getStringExtra("uri");
|
||||
LbrynetService.this.deleteDownload(uri);
|
||||
boolean nativeDelete = intent.getBooleanExtra("nativeDelete", false);
|
||||
LbrynetService.this.deleteDownload(uri, nativeDelete);
|
||||
} else if (ACTION_CHECK_DOWNLOADS.equals(action)) {
|
||||
LbrynetService.this.checkDownloads();
|
||||
}
|
||||
|
@ -212,8 +213,10 @@ public class LbrynetService extends PythonService {
|
|||
if (streamManagerReady) {
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("page_size", 100);
|
||||
params.put("status", "stopped");
|
||||
params.put("comparison", "ne");
|
||||
params.put("reverse", true);
|
||||
params.put("sort", "added_on");
|
||||
/*params.put("status", "stopped");
|
||||
params.put("comparison", "ne");*/
|
||||
|
||||
String fileList = Utils.sdkCall("file_list", params);
|
||||
if (fileList != null) {
|
||||
|
@ -266,7 +269,7 @@ public class LbrynetService extends PythonService {
|
|||
File file = new File(downloadPath);
|
||||
Intent intent = createDownloadEventIntent(uri, outpoint, item.toString());
|
||||
intent.putExtra("action", "start");
|
||||
downloadManager.startDownload(uri, file.getName());
|
||||
downloadManager.startDownload(uri, file.getName(), outpoint);
|
||||
|
||||
Context context = getApplicationContext();
|
||||
if (context != null) {
|
||||
|
@ -286,10 +289,45 @@ public class LbrynetService extends PythonService {
|
|||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
|
||||
private void deleteDownload(String uri) {
|
||||
private void deleteDownload(String uri, boolean nativeDelete) {
|
||||
final String outpoint = downloadManager.getOutpointForDownload(uri);
|
||||
if (nativeDelete && outpoint != null) {
|
||||
// send call sdk to delete the file on the corresponding outpoint
|
||||
removeDownloadFromManager(uri);
|
||||
|
||||
(new AsyncTask<Void, Void, String>() {
|
||||
protected String doInBackground(Void... param) {
|
||||
try {
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("outpoint", outpoint);
|
||||
params.put("delete_from_download_dir", true);
|
||||
return Utils.sdkCall("file_delete", params);
|
||||
} catch (ConnectException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void onPostExecute(String response) {
|
||||
// after deletion, remove the download from the download manager
|
||||
Intent intent = createDownloadEventIntent(uri, outpoint, null);
|
||||
intent.putExtra("action", "abort");
|
||||
|
||||
Context context = getApplicationContext();
|
||||
if (context != null) {
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
} else {
|
||||
removeDownloadFromManager(uri);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeDownloadFromManager(String uri) {
|
||||
if (downloadManager.isDownloadActive(uri)) {
|
||||
downloadManager.abortDownload(uri);
|
||||
}
|
||||
|
||||
downloadManager.deleteDownloadUri(uri);
|
||||
}
|
||||
|
||||
|
@ -359,23 +397,13 @@ public class LbrynetService extends PythonService {
|
|||
if (!completed && downloadPath != null) {
|
||||
downloadManager.clearWrittenBytesForDownload(uri);
|
||||
intent.putExtra("action", "start");
|
||||
downloadManager.startDownload(uri, file.getName());
|
||||
downloadManager.startDownload(uri, file.getName(), outpoint);
|
||||
if (context != null) {
|
||||
context.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check download manager uris and clear downloads that may have been cancelled / deleted
|
||||
/*List<String> activeUris = downloadManager.getActiveDownloads();
|
||||
for (int i = 0; i < activeUris.size(); i++) {
|
||||
String activeUri = activeUris.get(i);
|
||||
if (!itemUris.contains(activeUri)) {
|
||||
downloadManager.abortDownload(activeUri);
|
||||
fileListUris.remove(activeUri); // remove URIs from the session that may have been deleted
|
||||
}
|
||||
}*/
|
||||
} catch (JSONException ex) {
|
||||
// pass
|
||||
Log.e(TAG, ex.getMessage(), ex);
|
||||
|
|
|
@ -212,17 +212,28 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac
|
|||
String outpoint = intent.getStringExtra("outpoint");
|
||||
String fileInfoJson = intent.getStringExtra("file_info");
|
||||
|
||||
if (uri == null || outpoint == null || fileInfoJson == null) {
|
||||
|
||||
if (uri == null || outpoint == null || (fileInfoJson == null && !"abort".equals(downloadAction))) {
|
||||
return;
|
||||
}
|
||||
|
||||
String eventName = null;
|
||||
WritableMap params = Arguments.createMap();
|
||||
params.putString("uri", uri);
|
||||
params.putString("outpoint", outpoint);
|
||||
|
||||
ReactContext reactContext = mReactInstanceManager.getCurrentReactContext();
|
||||
if ("abort".equals(downloadAction)) {
|
||||
eventName = "onDownloadAborted";
|
||||
if (reactContext != null) {
|
||||
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
String eventName = null;
|
||||
JSONObject json = new JSONObject(fileInfoJson);
|
||||
WritableMap fileInfo = JSONObjectToMap(json);
|
||||
WritableMap params = Arguments.createMap();
|
||||
params.putString("uri", uri);
|
||||
params.putString("outpoint", outpoint);
|
||||
params.putMap("fileInfo", fileInfo);
|
||||
|
||||
if (DownloadManager.ACTION_UPDATE.equals(downloadAction)) {
|
||||
|
@ -233,7 +244,6 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac
|
|||
eventName = (DownloadManager.ACTION_START.equals(downloadAction)) ? "onDownloadStarted" : "onDownloadCompleted";
|
||||
}
|
||||
|
||||
ReactContext reactContext = mReactInstanceManager.getCurrentReactContext();
|
||||
if (reactContext != null) {
|
||||
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue