diff --git a/F-Droid/AndroidManifest.xml b/F-Droid/AndroidManifest.xml index 779fba7e1..f2683b0a6 100644 --- a/F-Droid/AndroidManifest.xml +++ b/F-Droid/AndroidManifest.xml @@ -450,6 +450,14 @@ + + + + + + + + diff --git a/F-Droid/src/org/fdroid/fdroid/AppDetails.java b/F-Droid/src/org/fdroid/fdroid/AppDetails.java index 83f903849..7b53b151d 100644 --- a/F-Droid/src/org/fdroid/fdroid/AppDetails.java +++ b/F-Droid/src/org/fdroid/fdroid/AppDetails.java @@ -22,6 +22,7 @@ package org.fdroid.fdroid; import android.app.Activity; +import android.app.DownloadManager; import android.bluetooth.BluetoothAdapter; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; @@ -34,6 +35,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import android.database.ContentObserver; +import android.database.Cursor; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; @@ -91,6 +93,7 @@ import org.fdroid.fdroid.installer.Installer; import org.fdroid.fdroid.installer.Installer.AndroidNotCompatibleException; import org.fdroid.fdroid.installer.Installer.InstallerCallback; import org.fdroid.fdroid.net.ApkDownloader; +import org.fdroid.fdroid.net.AsyncDownloader; import org.fdroid.fdroid.net.Downloader; import java.io.File; @@ -361,9 +364,16 @@ public class AppDetails extends AppCompatActivity implements ProgressListener, A private String getAppIdFromIntent() { Intent i = getIntent(); if (!i.hasExtra(EXTRA_APPID)) { + if (i.hasExtra(DownloadManager.EXTRA_DOWNLOAD_ID)) { + // we have been passed a DownloadManager download id, so get the app id for it + long downloadId = i.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); + return AsyncDownloader.getAppId(this, downloadId); + } + Log.e(TAG, "No application ID found in the intent!"); return null; } + return i.getStringExtra(EXTRA_APPID); } @@ -451,6 +461,7 @@ public class AppDetails extends AppCompatActivity implements ProgressListener, A refreshApkList(); refreshHeader(); supportInvalidateOptionsMenu(); + if (downloadHandler != null) { if (downloadHandler.isComplete()) { downloadCompleteInstallApk(); diff --git a/F-Droid/src/org/fdroid/fdroid/net/ApkDownloader.java b/F-Droid/src/org/fdroid/fdroid/net/ApkDownloader.java index 0c22313f8..f8de9a802 100644 --- a/F-Droid/src/org/fdroid/fdroid/net/ApkDownloader.java +++ b/F-Droid/src/org/fdroid/fdroid/net/ApkDownloader.java @@ -197,7 +197,7 @@ public class ApkDownloader implements AsyncDownloadWrapper.Listener { if (canUseDownloadManager(new URL(remoteAddress))) { // If we can use Android's DownloadManager, let's use it, because // of better OS integration, reliability, and async ability - dlWrapper = new AsyncDownloader(context, this, curApk.apkName, remoteAddress, localFile); + dlWrapper = new AsyncDownloader(context, this, curApk.apkName, curApk.id, remoteAddress, localFile); } else { Downloader downloader = DownloaderFactory.create(context, remoteAddress, localFile); dlWrapper = new AsyncDownloadWrapper(downloader, this); diff --git a/F-Droid/src/org/fdroid/fdroid/net/AsyncDownloader.java b/F-Droid/src/org/fdroid/fdroid/net/AsyncDownloader.java index 72c4d2181..3f9f7cfd2 100644 --- a/F-Droid/src/org/fdroid/fdroid/net/AsyncDownloader.java +++ b/F-Droid/src/org/fdroid/fdroid/net/AsyncDownloader.java @@ -6,10 +6,12 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.ParcelFileDescriptor; +import org.fdroid.fdroid.AppDetails; import org.fdroid.fdroid.data.SanitizedFile; import java.io.ByteArrayOutputStream; @@ -30,6 +32,7 @@ public class AsyncDownloader extends AsyncDownloadWrapper { private SanitizedFile localFile; private String remoteAddress; private String appName; + private String appId; private Listener listener; private long downloadId = -1; @@ -43,10 +46,11 @@ public class AsyncDownloader extends AsyncDownloadWrapper { * * @param listener */ - public AsyncDownloader(Context context, Listener listener, String appName, String remoteAddress, SanitizedFile localFile) { + public AsyncDownloader(Context context, Listener listener, String appName, String appId, String remoteAddress, SanitizedFile localFile) { super(null, listener); this.context = context; this.appName = appName; + this.appId = appId; this.remoteAddress = remoteAddress; this.listener = listener; this.localFile = localFile; @@ -63,6 +67,7 @@ public class AsyncDownloader extends AsyncDownloadWrapper { // 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 if (listener != null) { IntentFilter intentFilter = new IntentFilter(); @@ -97,7 +102,10 @@ public class AsyncDownloader extends AsyncDownloadWrapper { private BroadcastReceiver downloadReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (listener == null) return; // no point if no-one is listening + if (listener == null) { + // without a listener, install UI won't come up, so ignore this + return; + } if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) { long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); @@ -135,4 +143,18 @@ public class AsyncDownloader extends AsyncDownloadWrapper { } } }; + + public static String getAppId(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); + if (c.moveToFirst()) { + // we use the description column to store the app id + int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_DESCRIPTION); + return c.getString(columnIndex); + } + + return null; + } } diff --git a/F-Droid/src/org/fdroid/fdroid/receiver/DownloadManagerReceiver.java b/F-Droid/src/org/fdroid/fdroid/receiver/DownloadManagerReceiver.java new file mode 100644 index 000000000..6f08e2323 --- /dev/null +++ b/F-Droid/src/org/fdroid/fdroid/receiver/DownloadManagerReceiver.java @@ -0,0 +1,22 @@ +package org.fdroid.fdroid.receiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import org.fdroid.fdroid.AppDetails; + +/** + * Receive notifications from the Android DownloadManager + */ +public class DownloadManagerReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + // 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); + appDetails.setAction(intent.getAction()); + appDetails.putExtras(intent.getExtras()); + context.startActivity(appDetails); + } +}