Now displays a notification when download is complete, unless use is already on the app details screen, in which case it pops up the installer immediately

This commit is contained in:
Toby Kurien 2015-09-05 11:54:17 +02:00 committed by Peter Serwylo
parent 13e54ced07
commit ef40b5f3db
3 changed files with 118 additions and 16 deletions

View File

@ -389,6 +389,7 @@
<string name="perm_costs_money">this may cost you money</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="tap_to_install">Download completed, tap to install</string>
<string name="perms_new_perm_prefix">NEW: </string>
<string name="perms_description_app">Provided by %1$s.</string>

View File

@ -10,6 +10,8 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import org.fdroid.fdroid.AppDetails;
import org.fdroid.fdroid.ProgressListener;
@ -68,6 +70,7 @@ public class AsyncDownloader extends AsyncDownloadWrapper {
@Override
public void download() {
// Check if the download is complete
if ((downloadId = isDownloadComplete(context, appId)) > 0) {
// clear the notification
dm.remove(downloadId);
@ -80,19 +83,25 @@ public class AsyncDownloader extends AsyncDownloadWrapper {
} catch (IOException e) {
listener.onErrorDownloading(e.getLocalizedMessage());
}
return;
}
downloadId = isDownloading(context, appId);
if (downloadId >= 0) return;
// Check if the download is still in progress
if (downloadId < 0) {
downloadId = isDownloading(context, appId);
}
// set up download request
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(remoteAddress));
request.setTitle(appName);
request.setDescription(appId); // we will retrieve this later from the description field
// Start a new download
if (downloadId < 0) {
// set up download request
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(remoteAddress));
request.setTitle(appName);
request.setDescription(appId); // we will retrieve this later from the description field
this.downloadId = dm.enqueue(request);
}
this.downloadId = dm.enqueue(request);
context.registerReceiver(receiver,
new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
/**
@ -161,6 +170,12 @@ public class AsyncDownloader extends AsyncDownloadWrapper {
@Override
public void attemptCancel(boolean userRequested) {
try {
context.unregisterReceiver(receiver);
} catch (Exception e) {
// ignore if receiver already unregistered
}
if (userRequested && downloadId >= 0) {
dm.remove(downloadId);
}
@ -191,6 +206,31 @@ public class AsyncDownloader extends AsyncDownloadWrapper {
return null;
}
/**
* Extract the download title from a given download id.
* @param context
* @param downloadId
* @return - title or null if not found
*/
public static String getDownloadTitle(Context context, long downloadId) {
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadId);
Cursor c = dm.query(query);
try {
if (c.moveToFirst()) {
// we use the description column to store the app id
int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_TITLE);
return c.getString(columnIndex);
}
} finally {
c.close();
}
return null;
}
/**
* Get the downloadId from an Intent sent by the DownloadManagerReceiver
* @param intent
@ -267,4 +307,29 @@ public class AsyncDownloader extends AsyncDownloadWrapper {
return -1;
}
/**
* Broadcast receiver to listen for ACTION_DOWNLOAD_COMPLETE broadcasts
*/
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
long dId = getDownloadId(intent);
String appId = getAppId(context, dId);
if (listener != null && dId == downloadId && appId != null) {
// our current download has just completed, so let's throw up install dialog
// immediately
try {
context.unregisterReceiver(receiver);
} catch (Exception e) {
// ignore if receiver already unregistered
}
// call download() to copy the file and start the installer
download();
}
}
}
};
}

View File

@ -1,15 +1,21 @@
package org.fdroid.fdroid.receiver;
import android.app.DownloadManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import org.fdroid.fdroid.AppDetails;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.net.AsyncDownloader;
/**
* Receive notifications from the Android DownloadManager
* Receive notifications from the Android DownloadManager and pass them onto the
* AppDetails activity
*/
public class DownloadManagerReceiver extends BroadcastReceiver {
@Override
@ -18,12 +24,42 @@ public class DownloadManagerReceiver extends BroadcastReceiver {
long downloadId = AsyncDownloader.getDownloadId(intent);
String appId = AsyncDownloader.getAppId(context, downloadId);
// pass the download manager broadcast onto the AppDetails screen and let it handle it
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);
context.startActivity(appDetails);
if (appId == null) {
// bogus broadcast (e.g. download cancelled, but system sent a DOWNLOAD_COMPLETE)
return;
}
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
// 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 = AsyncDownloader.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())) {
// pass the notification click onto the AppDetails screen and let it handle it
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);
context.startActivity(appDetails);
}
}
}