Better handle download errors from DownloadManager
Rebased and squashed from !141.
This commit is contained in:
parent
6eddfb8b97
commit
2642c14cb7
@ -344,6 +344,7 @@
|
|||||||
<string name="uninstall_update_confirm">Do you want to replace this app with the factory version?</string>
|
<string name="uninstall_update_confirm">Do you want to replace this app with the factory version?</string>
|
||||||
<string name="uninstall_confirm">Do you want to uninstall this app?</string>
|
<string name="uninstall_confirm">Do you want to uninstall this app?</string>
|
||||||
<string name="tap_to_install">Download completed, tap to install</string>
|
<string name="tap_to_install">Download completed, tap to install</string>
|
||||||
|
<string name="download_error">Download unsuccessful</string>
|
||||||
|
|
||||||
<string name="perms_new_perm_prefix">New: </string>
|
<string name="perms_new_perm_prefix">New: </string>
|
||||||
<string name="perms_description_app">Provided by %1$s.</string>
|
<string name="perms_description_app">Provided by %1$s.</string>
|
||||||
|
@ -12,7 +12,9 @@ import android.os.Build;
|
|||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.Utils;
|
import org.fdroid.fdroid.Utils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -68,9 +70,22 @@ public class AsyncDownloaderFromAndroid implements AsyncDownloader {
|
|||||||
public void download() {
|
public void download() {
|
||||||
isCancelled = false;
|
isCancelled = false;
|
||||||
|
|
||||||
|
// check if download failed
|
||||||
|
if (downloadManagerId >= 0) {
|
||||||
|
int status = validDownload(context, downloadManagerId);
|
||||||
|
if (status > 0) {
|
||||||
|
// error downloading
|
||||||
|
dm.remove(downloadManagerId);
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onErrorDownloading(context.getString(R.string.download_error));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the download is complete
|
// Check if the download is complete
|
||||||
if ((downloadManagerId = isDownloadComplete(context, uniqueDownloadId)) > 0) {
|
if ((downloadManagerId = isDownloadComplete(context, uniqueDownloadId)) > 0) {
|
||||||
// clear the notification
|
// clear the download
|
||||||
dm.remove(downloadManagerId);
|
dm.remove(downloadManagerId);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -313,6 +328,35 @@ public class AsyncDownloaderFromAndroid implements AsyncDownloader {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if download was valid, see issue
|
||||||
|
* http://code.google.com/p/android/issues/detail?id=18462
|
||||||
|
* From http://stackoverflow.com/questions/8937817/downloadmanager-action-download-complete-broadcast-receiver-receiving-same-downl
|
||||||
|
* @return 0 if successful, -1 if download doesn't exist, else the DownloadManager.ERROR_... code
|
||||||
|
*/
|
||||||
|
public static int validDownload(Context context, long downloadId) {
|
||||||
|
//Verify if download is a success
|
||||||
|
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||||
|
Cursor c = dm.query(new DownloadManager.Query().setFilterById(downloadId));
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (c.moveToFirst()) {
|
||||||
|
int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
|
||||||
|
|
||||||
|
if (status == DownloadManager.STATUS_SUCCESSFUL) {
|
||||||
|
return 0; //Download is valid, celebrate
|
||||||
|
} else {
|
||||||
|
return c.getInt(c.getColumnIndex(DownloadManager.COLUMN_REASON));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
c.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1; // download doesn't exist
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Broadcast receiver to listen for ACTION_DOWNLOAD_COMPLETE broadcasts
|
* Broadcast receiver to listen for ACTION_DOWNLOAD_COMPLETE broadcasts
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.fdroid.fdroid.receiver;
|
package org.fdroid.fdroid.receiver;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.app.DownloadManager;
|
import android.app.DownloadManager;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
@ -7,16 +8,20 @@ import android.app.PendingIntent;
|
|||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.support.annotation.StringRes;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
|
||||||
import org.fdroid.fdroid.AppDetails;
|
import org.fdroid.fdroid.AppDetails;
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
|
import org.fdroid.fdroid.net.AsyncDownloader;
|
||||||
import org.fdroid.fdroid.net.AsyncDownloaderFromAndroid;
|
import org.fdroid.fdroid.net.AsyncDownloaderFromAndroid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receive notifications from the Android DownloadManager and pass them onto the
|
* Receive notifications from the Android DownloadManager and pass them onto the
|
||||||
* AppDetails activity
|
* AppDetails activity
|
||||||
*/
|
*/
|
||||||
|
@TargetApi(9)
|
||||||
public class DownloadManagerReceiver extends BroadcastReceiver {
|
public class DownloadManagerReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
@ -30,28 +35,18 @@ public class DownloadManagerReceiver extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
|
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
|
||||||
// show a notification the user can click to install the app
|
int status = AsyncDownloaderFromAndroid.validDownload(context, downloadId);
|
||||||
Intent appDetails = new Intent(context, AppDetails.class);
|
if (status == 0) {
|
||||||
appDetails.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
// successful download
|
||||||
appDetails.setAction(intent.getAction());
|
showNotification(context, appId, intent, downloadId, R.string.tap_to_install);
|
||||||
appDetails.putExtras(intent.getExtras());
|
} else {
|
||||||
appDetails.putExtra(AppDetails.EXTRA_APPID, appId);
|
// download failed!
|
||||||
|
showNotification(context, appId, intent, downloadId, R.string.download_error);
|
||||||
|
|
||||||
PendingIntent pi = PendingIntent.getActivity(
|
// clear the download to allow user to download again
|
||||||
context, 1, appDetails, PendingIntent.FLAG_ONE_SHOT);
|
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||||
|
dm.remove(downloadId);
|
||||||
// launch LocalRepoActivity if the user selects this notification
|
}
|
||||||
String downloadTitle = AsyncDownloaderFromAndroid.getDownloadTitle(context, downloadId);
|
|
||||||
Notification notif = new NotificationCompat.Builder(context)
|
|
||||||
.setContentTitle(downloadTitle)
|
|
||||||
.setContentText(context.getString(R.string.tap_to_install))
|
|
||||||
.setSmallIcon(R.drawable.ic_stat_notify)
|
|
||||||
.setContentIntent(pi)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
nm.notify((int)downloadId, notif);
|
|
||||||
} else if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(intent.getAction())) {
|
} else if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(intent.getAction())) {
|
||||||
// pass the notification click onto the AppDetails screen and let it handle it
|
// pass the notification click onto the AppDetails screen and let it handle it
|
||||||
Intent appDetails = new Intent(context, AppDetails.class);
|
Intent appDetails = new Intent(context, AppDetails.class);
|
||||||
@ -62,4 +57,30 @@ public class DownloadManagerReceiver extends BroadcastReceiver {
|
|||||||
context.startActivity(appDetails);
|
context.startActivity(appDetails);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showNotification(Context context, String appId, Intent intent, long downloadId,
|
||||||
|
@StringRes int messageResId) {
|
||||||
|
// show a notification the user can click to install the app
|
||||||
|
Intent appDetails = new Intent(context, AppDetails.class);
|
||||||
|
appDetails.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
appDetails.setAction(intent.getAction());
|
||||||
|
appDetails.putExtras(intent.getExtras());
|
||||||
|
appDetails.putExtra(AppDetails.EXTRA_APPID, appId);
|
||||||
|
|
||||||
|
PendingIntent pi = PendingIntent.getActivity(
|
||||||
|
context, 1, appDetails, PendingIntent.FLAG_ONE_SHOT);
|
||||||
|
|
||||||
|
// launch LocalRepoActivity if the user selects this notification
|
||||||
|
String downloadTitle = AsyncDownloaderFromAndroid.getDownloadTitle(context, downloadId);
|
||||||
|
Notification notif = new NotificationCompat.Builder(context)
|
||||||
|
.setContentTitle(downloadTitle)
|
||||||
|
.setContentText(context.getString(messageResId))
|
||||||
|
.setSmallIcon(R.drawable.ic_stat_notify)
|
||||||
|
.setContentIntent(pi)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
nm.notify((int)downloadId, notif);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user