Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Download manager, how to get status when its "cancel" from notification bar?

I am using download manger to download file in android. But in the case of when tap on "cancel" button from the notification bar , I am unable to get any broadcast.

I have find only two broadcast :

1.DownloadManager.ACTION_DOWNLOAD_COMPLETE 2.DownloadManager.ACTION_NOTIFICTION_CLICKED

Is there any broadcast by Download manager when its cancel ? If not then please give me any solution how to handle it ?

like image 238
Ankit Saini Avatar asked Nov 07 '22 12:11

Ankit Saini


1 Answers

DownloadManager will write information to database when it handle the user download task. So we can check the status of database to know if a task is canceled.

1. use the api from DownloadManager, polling status periodically

After you enqueue your download task, start the following thread to check.

private static class DownloadQueryThread extends Thread {

    private static final String TAG = "DownloadQueryThread";
    private final WeakReference<Context> context;
    private DownloadManager downloadManager;
    private final DownloadManager.Query downloadQuery;
    private boolean shouldStopQuery = false;
    private boolean downloadComplete = false;
    private static final Object LOCK = new Object();
    private final BroadcastReceiver downloadCompleteBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
                synchronized (LOCK) {
                    shouldStopQuery = true;
                    downloadComplete = true;
                }
            }
        }
    };

    /**
     * Create from context and download id
     * @param context the application context
     * @param queryId the download id from {@link DownloadManager#enqueue(DownloadManager.Request)}
     */
    public DownloadQueryThread(Context context, long queryId) {
        this.context = new WeakReference<>(context);
        this.downloadQuery = new DownloadManager.Query().setFilterById(queryId);
        this.downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
    }

    @Override
    public void run() {
        super.run();
        if (context.get() != null) {
            context.get().registerReceiver(downloadCompleteBroadcastReceiver,
                    new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
        }

        while (true) {

            if (downloadManager != null) {
                Cursor cursor = downloadManager.query(downloadQuery);
                if (cursor != null && cursor.moveToFirst()) {
                    Log.d(TAG, "download running");
                } else {
                    shouldStopQuery = true;
                }
            }

            synchronized (LOCK) {
                if (shouldStopQuery) {
                    if (downloadComplete) {
                        Log.d(TAG, "download complete");
                    } else {
                        Log.w(TAG, "download cancel");
                    }
                    break;
                }
            }

            try {
                sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        if (context.get() != null) {
            context.get().unregisterReceiver(downloadCompleteBroadcastReceiver);
        }
    }
}

2.use ContentObserver to get notified when database changed

The content uri for download manager should be content://downloads/my_downloads, we can monitor the changing of this database. When you start a download with a download id, a row will be created content://downloads/my_downloads/{downloadId}. We can check this cursor to know if this task is canceled or not. If the returned cursor is empty or null, no record found in database, this download task is canceled by user.

// get the download id from DownloadManager#enqueue
getContentResolver().registerContentObserver(Uri.parse("content://downloads/my_downloads"),
            true, new ContentObserver(null) {
                @Override
                public void onChange(boolean selfChange, Uri uri) {
                    super.onChange(selfChange, uri);
                    if (uri.toString().matches(".*\\d+$")) {
                        long changedId = Long.parseLong(uri.getLastPathSegment());
                        if (changedId == downloadId[0]) {
                            Log.d(TAG, "onChange: " + uri.toString() + " " + changedId + " " + downloadId[0]);
                            Cursor cursor = null;
                            try {
                                cursor = getContentResolver().query(uri, null, null, null, null);
                                if (cursor != null && cursor.moveToFirst()) {
                                    Log.d(TAG, "onChange: running");
                                } else {
                                    Log.w(TAG, "onChange: cancel");
                                }
                            } finally {
                                if (cursor != null) {
                                    cursor.close();
                                }
                            }
                        }
                    }
                }
            });
like image 127
alijandro Avatar answered Nov 14 '22 21:11

alijandro