Skip to content

Instantly share code, notes, and snippets.

@emaillenin
Created December 11, 2016 04:54
Show Gist options
  • Save emaillenin/9a0fea5a6924ddb23b8dd620392e745f to your computer and use it in GitHub Desktop.
Save emaillenin/9a0fea5a6924ddb23b8dd620392e745f to your computer and use it in GitHub Desktop.
Download APK using DownloadManager and start installation automatically - Android 7.0 Nougat compatible
public void downloadUpdate() {
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
String destination = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/";
String fileName = "your_app.apk";
destination += fileName;
final Uri uri = Uri.parse("file://" + destination);
File file = new File(destination);
if (file.exists())
file.delete();
DownloadManager.Request request = new DownloadManager.Request(
Uri.parse(getIntent().getStringExtra("url")));
request.setDestinationUri(uri);
dm.enqueue(request);
final String finalDestination = destination;
final BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri contentUri = FileProvider.getUriForFile(ctxt, BuildConfig.APPLICATION_ID + ".provider", new File(finalDestination));
Intent openFileIntent = new Intent(Intent.ACTION_VIEW);
openFileIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
openFileIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
openFileIntent.setData(contentUri);
startActivity(openFileIntent);
unregisterReceiver(this);
finish();
} else {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
install.setDataAndType(uri,
"application/vnd.android.package-archive");
startActivity(install);
unregisterReceiver(this);
finish();
}
}
};
registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
@sajjadintel
Copy link

what is BuildConfig.APPLICATION_ID + ".provider" ?

@sajjadintel
Copy link

I face this error on android N:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference

@SteadEXE
Copy link

SteadEXE commented Jan 16, 2018

Yes, because you need to define a provider in your Manifest.

This is what I use in my AndroidManifest.xml

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/paths"/>
        </provider>

You also need to create a XML that contains paths.
My xml/paths.xml is:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path
        name="internal"
        path="."/>
</paths>

In my code I do:

File apk = new File(getFilesDir(), "update.apk");

Uri uri = FileProvider.getUriForFile(UpdateActivity.this, BuildConfig.APPLICATION_ID + ".fileprovider", apk);

Intent install = new Intent(Intent.ACTION_VIEW, uri)
                                    .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

                            UpdateActivity.this.startActivity(install);

I hope it will help you.

@yeganehaym
Copy link

for me package manager has stopped
what should i do in this status?

@linuxgnuru
Copy link

linuxgnuru commented Mar 27, 2018

if my apk is signed, how can I get it to update? Or is that just not possible?
sorry for that question; I hadn't slept in 30 hours when I asked it...

@sajjadintel
Copy link

permission write storage is necessary or not?

@KarlosPerez
Copy link

This helped me a lot man. Thanks!! you're a lifesaver, two days finding a way to download and install an apk, and only this code worked for me. Just for adding something, for android 7+ you need to set permissions for REQUEST_INSTALL_PACKAGES to work. Thanks again.

@JavidAbbas
Copy link

For me it works, as well. But after download the apk file is not clickable. I download same file using browser, everything is fine.
I tried this also: request.setMimeType("application/vnd.android.package-archive") . But the result is same :(

@utahemre
Copy link

Karlos said the solution of your problem. You have to add REQUEST_INSTALL_PACKAGES to your androidManifest.xml. Without this permission, .apk files are not clickable.

@qureshiayaz29
Copy link

android Q does not expose getExternalStoragePublicDirectory() due to security concern, so it is requested to replace 'getExternalStoragePublicDirectory()' with 'getExternalFilesDir()' for new/old version of android for downloading (i.e. writing) and reading file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment