Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use PackageManager canRequestPackageInstalls in Android Oreo?

Tags:

android

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?

like image 616
The Matrix Avatar asked Dec 18 '17 16:12

The Matrix


People also ask

What is Android permission Request_install_packages?

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.

What is the use of package manager in Android?

Package Manager is a highly powerful application to manage apps, both system and user, installed on an android device.

How do I find package manager on Android?

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.

What is queryIntentActivities?

queryIntentActivities() returns a list of all activities that can handle the Intent . resolveActivity() returns the "best" Activity that can handle the Intent.


2 Answers

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" />
like image 118
Alexander The Great Avatar answered Sep 19 '22 13:09

Alexander The Great


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.

like image 42
Patneu Avatar answered Sep 19 '22 13:09

Patneu