Android install .apk file programmatically
Solution 1
I have wrote a code in java with respect to Uri
access exposure for targetSdkVersion >= 24
, please try it in xamarin yourself.
ApkInstaller.java
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.support.v4.content.FileProvider;
import android.util.Log;
import java.io.File;
public class ApkInstaller {
public static void installApplication(Context context, String filePath) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uriFromFile(context, new File(filePath)), "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Log.e("TAG", "Error in opening the file!");
}
}
private static Uri uriFromFile(Context context, File file) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file);
} else {
return Uri.fromFile(file);
}
}
}
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="package.identifier">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application ... >
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>
</manifest>
res/xml/provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_files"
path="." />
</paths>
Usage:
ApkInstaller.installApplication(context, filePath);
Solution 2
STEP-1
First Create xml file inside your res/xml/provider_paths.xml and then
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="files_root"
path="Android/data/${applicationId}" />
<external-path
name="external_files"
path="." />
</paths>
STEP-2
Add this in AndroidManifest.xml file
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<application>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>
STEP-3 Final step
Add this in your Activity class
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri uri = FileProvider.getUriForFile(context,
context.getApplicationContext().getPackageName() + ".provider", new File(apkFilePath));
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
startActivity(intent);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(FileUtils.getFileToUri(BaseActivity.this, new File(apkFilePath)),
"application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
Note: FileProvider only for Android >= Nougat
Using FileProvider you can get other .extension file like capture image uri
Uri uri = FileProvider.getUriForFile(context,
context.getApplicationContext().getPackageName() + ".provider", new File(imageFilePath));
r2b2s
Updated on June 04, 2022Comments
-
r2b2s about 2 years
I'm trying to do an autoupdate function, after a lot of search I've found solution for download .apk file from my server to my device But i'can't launch this file, window to prompt user for install open but close direct.
this is my code
Java.IO.File file = new Java.IO.File(destination); Android.Net.Uri apkURI = Android.Support.V4.Content.FileProvider.GetUriForFile( _context, _context.ApplicationContext.PackageName + ".provider", file); Intent promptInstall = new Intent(Intent.ActionView); //promptInstall.SetDataAndType(apkURI, "application/vnd.android.package-archive"); promptInstall.SetData(apkURI); promptInstall.AddFlags(ActivityFlags.NewTask); promptInstall.AddFlags(ActivityFlags.GrantReadUriPermission); _context.GrantUriPermission(_context.ApplicationContext.PackageName, apkURI, ActivityFlags.GrantReadUriPermission); _context.StartActivity(promptInstall);
I've tryed with a lot of combinaison of flags and Ident.Action like ActionInstallPackage
android version is 8.1
thanks
-
aminography over 5 years@r2b2s: Have you tested it?
-
r2b2s over 5 yearsthanks, but i've already tested this solution, and it's not wotking for me the apk installer windows is launched but immediatly closed... I've scrapped the idea and tried something new, use google play store with tested version
-
roghayeh hosseini about 5 yearsare u test it in android >Oreo?
-
aminography about 5 years@roghayehhosseini: I've tested it on Android
N
, as the problem comes fromN
and later, I think it is OK onO
. -
Sagar almost 5 years@aminography For me it showing dialog
There was a problem while parsing the package
and security exception forandroidx.core.content.FileProvider
I have addedFLAG_GRANT_READ_URI_PERMISSION
flag also