move all downloading notifications to InstallManagerService
This keeps DownloaderService tightly focused on downloading, and makes it a lot easier to manage Notifications since InstallManagerService's lifecycle lasts as long as the Notifications, unlike DownloaderService.
This commit is contained in:
parent
67e66a7b0c
commit
08988f2369
@ -1,15 +1,27 @@
|
|||||||
package org.fdroid.fdroid.installer;
|
package org.fdroid.fdroid.installer;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
import android.support.v4.app.TaskStackBuilder;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
import org.fdroid.fdroid.AppDetails;
|
||||||
|
import org.fdroid.fdroid.FDroid;
|
||||||
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.Utils;
|
import org.fdroid.fdroid.Utils;
|
||||||
import org.fdroid.fdroid.data.Apk;
|
import org.fdroid.fdroid.data.Apk;
|
||||||
import org.fdroid.fdroid.data.App;
|
import org.fdroid.fdroid.data.App;
|
||||||
|
import org.fdroid.fdroid.data.AppProvider;
|
||||||
import org.fdroid.fdroid.net.Downloader;
|
import org.fdroid.fdroid.net.Downloader;
|
||||||
import org.fdroid.fdroid.net.DownloaderService;
|
import org.fdroid.fdroid.net.DownloaderService;
|
||||||
|
|
||||||
@ -45,12 +57,19 @@ public class InstallManagerService extends Service {
|
|||||||
public static final String TAG = "InstallManagerService";
|
public static final String TAG = "InstallManagerService";
|
||||||
|
|
||||||
private static final String ACTION_INSTALL = "org.fdroid.fdroid.InstallManagerService.action.INSTALL";
|
private static final String ACTION_INSTALL = "org.fdroid.fdroid.InstallManagerService.action.INSTALL";
|
||||||
|
private static final int NOTIFY_DOWNLOADING = 0x2344;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The collection of APKs that are actively going through this whole process.
|
* The collection of APKs that are actively going through this whole process.
|
||||||
*/
|
*/
|
||||||
private static final HashMap<String, Apk> ACTIVE_APKS = new HashMap<String, Apk>(3);
|
private static final HashMap<String, Apk> ACTIVE_APKS = new HashMap<String, Apk>(3);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The array of active {@link BroadcastReceiver}s for each active APK. The key is the
|
||||||
|
* download URL, as in {@link Apk#getUrl()} or {@code urlString}.
|
||||||
|
*/
|
||||||
|
private final HashMap<String, BroadcastReceiver[]> receivers = new HashMap<String, BroadcastReceiver[]>(3);
|
||||||
|
|
||||||
private LocalBroadcastManager localBroadcastManager;
|
private LocalBroadcastManager localBroadcastManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,11 +92,17 @@ public class InstallManagerService extends Service {
|
|||||||
Utils.debugLog(TAG, "onStartCommand " + intent);
|
Utils.debugLog(TAG, "onStartCommand " + intent);
|
||||||
String urlString = intent.getDataString();
|
String urlString = intent.getDataString();
|
||||||
Apk apk = ACTIVE_APKS.get(urlString);
|
Apk apk = ACTIVE_APKS.get(urlString);
|
||||||
|
|
||||||
|
Notification notification = createNotification(intent.getDataString(), apk.packageName).build();
|
||||||
|
startForeground(NOTIFY_DOWNLOADING, notification);
|
||||||
|
|
||||||
|
registerDownloaderReceivers(urlString);
|
||||||
|
|
||||||
File apkFilePath = Utils.getApkDownloadPath(this, intent.getData());
|
File apkFilePath = Utils.getApkDownloadPath(this, intent.getData());
|
||||||
long apkFileSize = apkFilePath.length();
|
long apkFileSize = apkFilePath.length();
|
||||||
if (!apkFilePath.exists() || apkFileSize < apk.size) {
|
if (!apkFilePath.exists() || apkFileSize < apk.size) {
|
||||||
Utils.debugLog(TAG, "download " + urlString + " " + apkFilePath);
|
Utils.debugLog(TAG, "download " + urlString + " " + apkFilePath);
|
||||||
DownloaderService.queue(this, apk.packageName, urlString);
|
DownloaderService.queue(this, urlString);
|
||||||
} else if (apkFileSize == apk.size) {
|
} else if (apkFileSize == apk.size) {
|
||||||
Utils.debugLog(TAG, "skip download, we have it, straight to install " + urlString + " " + apkFilePath);
|
Utils.debugLog(TAG, "skip download, we have it, straight to install " + urlString + " " + apkFilePath);
|
||||||
sendBroadcast(intent.getData(), Downloader.ACTION_STARTED, apkFilePath);
|
sendBroadcast(intent.getData(), Downloader.ACTION_STARTED, apkFilePath);
|
||||||
@ -85,7 +110,7 @@ public class InstallManagerService extends Service {
|
|||||||
} else {
|
} else {
|
||||||
Utils.debugLog(TAG, " delete and download again " + urlString + " " + apkFilePath);
|
Utils.debugLog(TAG, " delete and download again " + urlString + " " + apkFilePath);
|
||||||
apkFilePath.delete();
|
apkFilePath.delete();
|
||||||
DownloaderService.queue(this, apk.packageName, urlString);
|
DownloaderService.queue(this, urlString);
|
||||||
}
|
}
|
||||||
return START_REDELIVER_INTENT; // if killed before completion, retry Intent
|
return START_REDELIVER_INTENT; // if killed before completion, retry Intent
|
||||||
}
|
}
|
||||||
@ -97,6 +122,142 @@ public class InstallManagerService extends Service {
|
|||||||
localBroadcastManager.sendBroadcast(intent);
|
localBroadcastManager.sendBroadcast(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void unregisterDownloaderReceivers(String urlString) {
|
||||||
|
for (BroadcastReceiver receiver : receivers.get(urlString)) {
|
||||||
|
localBroadcastManager.unregisterReceiver(receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerDownloaderReceivers(String urlString) {
|
||||||
|
BroadcastReceiver startedReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BroadcastReceiver progressReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String urlString = intent.getDataString();
|
||||||
|
Apk apk = ACTIVE_APKS.get(urlString);
|
||||||
|
int bytesRead = intent.getIntExtra(Downloader.EXTRA_BYTES_READ, 0);
|
||||||
|
int totalBytes = intent.getIntExtra(Downloader.EXTRA_TOTAL_BYTES, 0);
|
||||||
|
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
Notification notification = createNotification(urlString, apk.packageName)
|
||||||
|
.setProgress(totalBytes, bytesRead, false)
|
||||||
|
.build();
|
||||||
|
nm.notify(NOTIFY_DOWNLOADING, notification);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BroadcastReceiver completeReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String urlString = intent.getDataString();
|
||||||
|
Apk apk = ACTIVE_APKS.remove(urlString);
|
||||||
|
notifyDownloadComplete(apk.packageName, intent.getDataString());
|
||||||
|
unregisterDownloaderReceivers(urlString);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
BroadcastReceiver interruptedReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String urlString = intent.getDataString();
|
||||||
|
ACTIVE_APKS.remove(urlString);
|
||||||
|
unregisterDownloaderReceivers(urlString);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
localBroadcastManager.registerReceiver(startedReceiver,
|
||||||
|
DownloaderService.getIntentFilter(urlString, Downloader.ACTION_STARTED));
|
||||||
|
localBroadcastManager.registerReceiver(progressReceiver,
|
||||||
|
DownloaderService.getIntentFilter(urlString, Downloader.ACTION_PROGRESS));
|
||||||
|
localBroadcastManager.registerReceiver(completeReceiver,
|
||||||
|
DownloaderService.getIntentFilter(urlString, Downloader.ACTION_COMPLETE));
|
||||||
|
localBroadcastManager.registerReceiver(interruptedReceiver,
|
||||||
|
DownloaderService.getIntentFilter(urlString, Downloader.ACTION_INTERRUPTED));
|
||||||
|
receivers.put(urlString, new BroadcastReceiver[]{
|
||||||
|
startedReceiver, progressReceiver, completeReceiver, interruptedReceiver,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private NotificationCompat.Builder createNotification(String urlString, @Nullable String packageName) {
|
||||||
|
return new NotificationCompat.Builder(this)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setContentIntent(createAppDetailsIntent(0, packageName))
|
||||||
|
.setContentTitle(getNotificationTitle(packageName))
|
||||||
|
.addAction(R.drawable.ic_cancel_black_24dp, getString(R.string.cancel),
|
||||||
|
DownloaderService.createCancelDownloadIntent(this, 0, urlString))
|
||||||
|
.setSmallIcon(android.R.drawable.stat_sys_download)
|
||||||
|
.setContentText(urlString)
|
||||||
|
.setProgress(100, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If downloading an apk (i.e. <code>packageName != null</code>) then the title will indicate
|
||||||
|
* the name of the app which the apk belongs to. Otherwise, it will be a generic "Downloading..."
|
||||||
|
* message.
|
||||||
|
*/
|
||||||
|
private String getNotificationTitle(@Nullable String packageName) {
|
||||||
|
String title;
|
||||||
|
if (packageName != null) {
|
||||||
|
App app = AppProvider.Helper.findByPackageName(
|
||||||
|
getContentResolver(), packageName, new String[]{AppProvider.DataColumns.NAME});
|
||||||
|
title = getString(R.string.downloading_apk, app.name);
|
||||||
|
} else {
|
||||||
|
title = getString(R.string.downloading);
|
||||||
|
}
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PendingIntent createAppDetailsIntent(int requestCode, String packageName) {
|
||||||
|
TaskStackBuilder stackBuilder;
|
||||||
|
if (packageName != null) {
|
||||||
|
Intent notifyIntent = new Intent(getApplicationContext(), AppDetails.class)
|
||||||
|
.putExtra(AppDetails.EXTRA_APPID, packageName);
|
||||||
|
|
||||||
|
stackBuilder = TaskStackBuilder
|
||||||
|
.create(getApplicationContext())
|
||||||
|
.addParentStack(AppDetails.class)
|
||||||
|
.addNextIntent(notifyIntent);
|
||||||
|
} else {
|
||||||
|
Intent notifyIntent = new Intent(getApplicationContext(), FDroid.class);
|
||||||
|
stackBuilder = TaskStackBuilder
|
||||||
|
.create(getApplicationContext())
|
||||||
|
.addParentStack(FDroid.class)
|
||||||
|
.addNextIntent(notifyIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stackBuilder.getPendingIntent(requestCode, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post a notification about a completed download. {@code packageName} must be a valid
|
||||||
|
* and currently in the app index database.
|
||||||
|
*/
|
||||||
|
private void notifyDownloadComplete(String packageName, String urlString) {
|
||||||
|
String title;
|
||||||
|
try {
|
||||||
|
PackageManager pm = getPackageManager();
|
||||||
|
title = String.format(getString(R.string.tap_to_update_format),
|
||||||
|
pm.getApplicationLabel(pm.getApplicationInfo(packageName, 0)));
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
App app = AppProvider.Helper.findByPackageName(getContentResolver(), packageName,
|
||||||
|
new String[]{
|
||||||
|
AppProvider.DataColumns.NAME,
|
||||||
|
});
|
||||||
|
title = String.format(getString(R.string.tap_to_install_format), app.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
int downloadUrlId = urlString.hashCode();
|
||||||
|
NotificationCompat.Builder builder =
|
||||||
|
new NotificationCompat.Builder(this)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setContentTitle(title)
|
||||||
|
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||||
|
.setContentIntent(createAppDetailsIntent(downloadUrlId, packageName))
|
||||||
|
.setContentText(getString(R.string.tap_to_install));
|
||||||
|
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
nm.notify(downloadUrlId, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Install an APK, checking the cache and downloading if necessary before starting the process.
|
* Install an APK, checking the cache and downloading if necessary before starting the process.
|
||||||
* All notifications are sent as an {@link Intent} via local broadcasts to be received by
|
* All notifications are sent as an {@link Intent} via local broadcasts to be received by
|
||||||
|
@ -17,14 +17,11 @@
|
|||||||
|
|
||||||
package org.fdroid.fdroid.net;
|
package org.fdroid.fdroid.net;
|
||||||
|
|
||||||
import android.app.Notification;
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
@ -34,19 +31,11 @@ import android.os.Message;
|
|||||||
import android.os.PatternMatcher;
|
import android.os.PatternMatcher;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v4.app.NotificationCompat;
|
|
||||||
import android.support.v4.app.TaskStackBuilder;
|
|
||||||
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 android.util.Log;
|
||||||
|
|
||||||
import org.fdroid.fdroid.AppDetails;
|
|
||||||
import org.fdroid.fdroid.FDroid;
|
|
||||||
import org.fdroid.fdroid.R;
|
|
||||||
import org.fdroid.fdroid.Utils;
|
import org.fdroid.fdroid.Utils;
|
||||||
import org.fdroid.fdroid.data.App;
|
|
||||||
import org.fdroid.fdroid.data.AppProvider;
|
|
||||||
import org.fdroid.fdroid.data.SanitizedFile;
|
import org.fdroid.fdroid.data.SanitizedFile;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -85,13 +74,9 @@ import java.net.URL;
|
|||||||
public class DownloaderService extends Service {
|
public class DownloaderService extends Service {
|
||||||
private static final String TAG = "DownloaderService";
|
private static final String TAG = "DownloaderService";
|
||||||
|
|
||||||
private static final String EXTRA_PACKAGE_NAME = "org.fdroid.fdroid.net.DownloaderService.extra.PACKAGE_NAME";
|
|
||||||
|
|
||||||
private static final String ACTION_QUEUE = "org.fdroid.fdroid.net.DownloaderService.action.QUEUE";
|
private static final String ACTION_QUEUE = "org.fdroid.fdroid.net.DownloaderService.action.QUEUE";
|
||||||
private static final String ACTION_CANCEL = "org.fdroid.fdroid.net.DownloaderService.action.CANCEL";
|
private static final String ACTION_CANCEL = "org.fdroid.fdroid.net.DownloaderService.action.CANCEL";
|
||||||
|
|
||||||
private static final int NOTIFY_DOWNLOADING = 0x2344;
|
|
||||||
|
|
||||||
private volatile Looper serviceLooper;
|
private volatile Looper serviceLooper;
|
||||||
private static volatile ServiceHandler serviceHandler;
|
private static volatile ServiceHandler serviceHandler;
|
||||||
private static volatile Downloader downloader;
|
private static volatile Downloader downloader;
|
||||||
@ -153,55 +138,6 @@ public class DownloaderService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private NotificationCompat.Builder createNotification(String urlString, @Nullable String packageName) {
|
|
||||||
return new NotificationCompat.Builder(this)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
.setContentIntent(createAppDetailsIntent(0, packageName))
|
|
||||||
.setContentTitle(getNotificationTitle(packageName))
|
|
||||||
.addAction(R.drawable.ic_cancel_black_24dp, getString(R.string.cancel),
|
|
||||||
createCancelDownloadIntent(this, 0, urlString))
|
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_download)
|
|
||||||
.setContentText(urlString)
|
|
||||||
.setProgress(100, 0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If downloading an apk (i.e. <code>packageName != null</code>) then the title will indicate
|
|
||||||
* the name of the app which the apk belongs to. Otherwise, it will be a generic "Downloading..."
|
|
||||||
* message.
|
|
||||||
*/
|
|
||||||
private String getNotificationTitle(@Nullable String packageName) {
|
|
||||||
if (packageName != null) {
|
|
||||||
final App app = AppProvider.Helper.findByPackageName(
|
|
||||||
getContentResolver(), packageName, new String[]{AppProvider.DataColumns.NAME});
|
|
||||||
if (app != null) {
|
|
||||||
return getString(R.string.downloading_apk, app.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return getString(R.string.downloading);
|
|
||||||
}
|
|
||||||
|
|
||||||
private PendingIntent createAppDetailsIntent(int requestCode, String packageName) {
|
|
||||||
TaskStackBuilder stackBuilder;
|
|
||||||
if (packageName != null) {
|
|
||||||
Intent notifyIntent = new Intent(getApplicationContext(), AppDetails.class)
|
|
||||||
.putExtra(AppDetails.EXTRA_APPID, packageName);
|
|
||||||
|
|
||||||
stackBuilder = TaskStackBuilder
|
|
||||||
.create(getApplicationContext())
|
|
||||||
.addParentStack(AppDetails.class)
|
|
||||||
.addNextIntent(notifyIntent);
|
|
||||||
} else {
|
|
||||||
Intent notifyIntent = new Intent(getApplicationContext(), FDroid.class);
|
|
||||||
stackBuilder = TaskStackBuilder
|
|
||||||
.create(getApplicationContext())
|
|
||||||
.addParentStack(FDroid.class)
|
|
||||||
.addNextIntent(notifyIntent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return stackBuilder.getPendingIntent(requestCode, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PendingIntent createCancelDownloadIntent(@NonNull Context context, int
|
public static PendingIntent createCancelDownloadIntent(@NonNull Context context, int
|
||||||
requestCode, @NonNull String urlString) {
|
requestCode, @NonNull String urlString) {
|
||||||
Intent cancelIntent = new Intent(context.getApplicationContext(), DownloaderService.class)
|
Intent cancelIntent = new Intent(context.getApplicationContext(), DownloaderService.class)
|
||||||
@ -254,12 +190,8 @@ public class DownloaderService extends Service {
|
|||||||
protected void handleIntent(Intent intent) {
|
protected void handleIntent(Intent intent) {
|
||||||
final Uri uri = intent.getData();
|
final Uri uri = intent.getData();
|
||||||
final SanitizedFile localFile = Utils.getApkDownloadPath(this, uri);
|
final SanitizedFile localFile = Utils.getApkDownloadPath(this, uri);
|
||||||
final String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
|
|
||||||
sendBroadcast(uri, Downloader.ACTION_STARTED, localFile);
|
sendBroadcast(uri, Downloader.ACTION_STARTED, localFile);
|
||||||
|
|
||||||
Notification notification = createNotification(intent.getDataString(), packageName).build();
|
|
||||||
startForeground(NOTIFY_DOWNLOADING, notification);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
downloader = DownloaderFactory.create(this, uri, localFile);
|
downloader = DownloaderFactory.create(this, uri, localFile);
|
||||||
downloader.setListener(new Downloader.DownloaderProgressListener() {
|
downloader.setListener(new Downloader.DownloaderProgressListener() {
|
||||||
@ -270,17 +202,10 @@ public class DownloaderService extends Service {
|
|||||||
intent.putExtra(Downloader.EXTRA_BYTES_READ, bytesRead);
|
intent.putExtra(Downloader.EXTRA_BYTES_READ, bytesRead);
|
||||||
intent.putExtra(Downloader.EXTRA_TOTAL_BYTES, totalBytes);
|
intent.putExtra(Downloader.EXTRA_TOTAL_BYTES, totalBytes);
|
||||||
localBroadcastManager.sendBroadcast(intent);
|
localBroadcastManager.sendBroadcast(intent);
|
||||||
|
|
||||||
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
|
||||||
Notification notification = createNotification(uri.toString(), packageName)
|
|
||||||
.setProgress(totalBytes, bytesRead, false)
|
|
||||||
.build();
|
|
||||||
nm.notify(NOTIFY_DOWNLOADING, notification);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
downloader.download();
|
downloader.download();
|
||||||
sendBroadcast(uri, Downloader.ACTION_COMPLETE, localFile);
|
sendBroadcast(uri, Downloader.ACTION_COMPLETE, localFile);
|
||||||
notifyDownloadComplete(packageName, intent.getDataString());
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, localFile);
|
sendBroadcast(uri, Downloader.ACTION_INTERRUPTED, localFile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -296,36 +221,6 @@ public class DownloaderService extends Service {
|
|||||||
downloader = null;
|
downloader = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Post a notification about a completed download. {@code packageName} must be a valid
|
|
||||||
* and currently in the app index database.
|
|
||||||
*/
|
|
||||||
private void notifyDownloadComplete(String packageName, String urlString) {
|
|
||||||
String title;
|
|
||||||
try {
|
|
||||||
PackageManager pm = getPackageManager();
|
|
||||||
title = String.format(getString(R.string.tap_to_update_format),
|
|
||||||
pm.getApplicationLabel(pm.getApplicationInfo(packageName, 0)));
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
App app = AppProvider.Helper.findByPackageName(getContentResolver(), packageName,
|
|
||||||
new String[]{
|
|
||||||
AppProvider.DataColumns.NAME,
|
|
||||||
});
|
|
||||||
title = String.format(getString(R.string.tap_to_install_format), app.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
int downloadUrlId = urlString.hashCode();
|
|
||||||
NotificationCompat.Builder builder =
|
|
||||||
new NotificationCompat.Builder(this)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
.setContentTitle(title)
|
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
|
||||||
.setContentIntent(createAppDetailsIntent(downloadUrlId, packageName))
|
|
||||||
.setContentText(getString(R.string.tap_to_install));
|
|
||||||
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
|
||||||
nm.notify(downloadUrlId, builder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendBroadcast(Uri uri, String action, File file) {
|
private void sendBroadcast(Uri uri, String action, File file) {
|
||||||
sendBroadcast(uri, action, file, null);
|
sendBroadcast(uri, action, file, null);
|
||||||
}
|
}
|
||||||
@ -345,19 +240,15 @@ public class DownloaderService extends Service {
|
|||||||
* <p/>
|
* <p/>
|
||||||
* All notifications are sent as an {@link Intent} via local broadcasts to be received by
|
* All notifications are sent as an {@link Intent} via local broadcasts to be received by
|
||||||
*
|
*
|
||||||
* @param context this app's {@link Context}
|
* @param context this app's {@link Context}
|
||||||
* @param packageName The packageName of the app being downloaded
|
* @param urlString The URL to add to the download queue
|
||||||
* @param urlString The URL to add to the download queue
|
|
||||||
* @see #cancel(Context, String)
|
* @see #cancel(Context, String)
|
||||||
*/
|
*/
|
||||||
public static void queue(Context context, String packageName, String urlString) {
|
public static void queue(Context context, String urlString) {
|
||||||
Utils.debugLog(TAG, "Preparing " + urlString + " to go into the download queue");
|
Utils.debugLog(TAG, "Preparing " + urlString + " to go into the download queue");
|
||||||
Intent intent = new Intent(context, DownloaderService.class);
|
Intent intent = new Intent(context, DownloaderService.class);
|
||||||
intent.setAction(ACTION_QUEUE);
|
intent.setAction(ACTION_QUEUE);
|
||||||
intent.setData(Uri.parse(urlString));
|
intent.setData(Uri.parse(urlString));
|
||||||
if (!TextUtils.isEmpty(packageName)) {
|
|
||||||
intent.putExtra(EXTRA_PACKAGE_NAME, packageName);
|
|
||||||
}
|
|
||||||
context.startService(intent);
|
context.startService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +259,7 @@ public class DownloaderService extends Service {
|
|||||||
*
|
*
|
||||||
* @param context this app's {@link Context}
|
* @param context this app's {@link Context}
|
||||||
* @param urlString The URL to remove from the download queue
|
* @param urlString The URL to remove from the download queue
|
||||||
* @see #queue(Context, String, String)
|
* @see #queue(Context, String)
|
||||||
*/
|
*/
|
||||||
public static void cancel(Context context, String urlString) {
|
public static void cancel(Context context, String urlString) {
|
||||||
Utils.debugLog(TAG, "Preparing cancellation of " + urlString + " download");
|
Utils.debugLog(TAG, "Preparing cancellation of " + urlString + " download");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user