In my app Manifest I have declared the use of the permission:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
and in my code I check if my app can install from unknown sources:
public void reinstallApp(Activity activity, String pathname, int request_code)
{
if (activity.getPackageManager().canRequestPackageInstalls())
{
try
{
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(pathname)), "application/vnd.android.package-archive");
activity.startActivityForResult(intent, request_code);
}
catch (Exception e)
{
LogUtilities.show(this, e);
}
}
else
{
activity.startActivity(new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).setData(Uri.parse(String.format("package:%s", activity.getPackageName()))));
}
}
but the "activity.getPackageManager().canRequestPackageInstalls()" is always returning "false", even if I check the allow install from unknow sources in the selection activity.
What's the issue?
REQUEST_INSTALL_PACKAGES permission provides apps with the ability to install new packages on a user's device. We are committed to preventing abuse on the Android platform and protecting users from apps that self update using any method other than Google Play's update mechanism or download harmful APKs.
Package Manager is a highly powerful application to manage apps, both system and user, installed on an android device.
getPackageManager() is a method of Context. You can use this method inside an Activity (because an Activity is a Context), but if you are calling it elsewhere, you need to pass a Context. In a fragment you may also have access to the getActivity() function, which returns the Acitivity-Context.
queryIntentActivities() returns a list of all activities that can handle the Intent . resolveActivity() returns the "best" Activity that can handle the Intent.
You've to ask for permission first. For that you've to call install permission from unknown sources. I got the answer by just rearranging your code.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!getPackageManager().canRequestPackageInstalls()) {
startActivityForResult(new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES).setData(Uri.parse(String.format("package:%s", getPackageName()))), 1234);
} else {
callInstallProcess();
}
} else {
callInstallProcess();
}
The above code will be in your onCreate() . The you can verify the result.
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1234 && resultCode == Activity.RESULT_OK) {
if (getPackageManager().canRequestPackageInstalls()) {
callInstallProcess();
}
} else {
//give the error
}
}
Where your installation is happening in callInstallProcess();
try
{
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(pathname)), "application/vnd.android.package-archive");
activity.startActivityForResult(intent, request_code);
}
catch (Exception e)
{
LogUtilities.show(this, e);
}
Don't forget to give permission in AndroidManifest.xml
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
As stated here, for getPackageManager().canRequestPackageInstalls()
to work correctly, you have to declare this permission
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
in your AndroidManifest.xml, as you already did, and - most likely the cause of your problem - declare the targetSdkVersion
in your build.gradle or AndroidManifest.xml to be 26 or higher (in other words, your app has to target Android Oreo or above).
Otherwise this method will always return false
, even if the user granted the permission.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With