How to manage installation from Unknown Sources in Android Oreo?
Asked Answered
D

2

27

In Android Oreo (8.0), several changes where made on how to allow the installation of apps from Unknown Sources (from the user's point of view) and to the process of getting permission to install them (from the developer's point of view).

Since I found it particularly hard to find all the steps necessary on the developer side, I thought it to be useful to ask here for the solution and answer the question myself, now that I found the answers, for future reference to those, who are facing the same obstacles.

The answer will include the following questions:

  1. How to check whether I'm allowed to request a package install?
  2. What exact permission do I have to request?
  3. How can I prompt the user to grant this permission?
  4. How do I prompt the user to install a specified .apk?

(If I still miss anything here, I'd be grateful for any additional answers or comments pointing that out.)

Dreamworld answered 14/4, 2018 at 6:51 Comment(2)
Hello, Thanks for the answer, There is one question. My targetSdkVersion is 22 and compileSdkVersion is 26 , How can I check getPackageManager().canRequestPackageInstalls() for this case. the method always returns false.Schatz
@Chirag Savsani: You can't. As stated in my answer below, you have to declare a targetSdkVersion of 26 or higher. Otherwise this method always returns false - it's the intended behaviour. So I'm afraid you won't get around making the necessary changes for a higher targetSdkVersion of your application.Dreamworld
D
68

For starters, your application needs to declare a targetSdkVersion of 26 (API level of Android Oreo) or higher in your build.gradle or AndroidManifest.xml for all this to work.

Then on to answer the questions above:

  1. How to check whether I'm allowed to request a package install?

You can check this using getPackageManager().canRequestPackageInstalls() anywhere in your Activity's code. Note that this method always returns false, if you don't declare the appropriate permission or target the wrong SDK version.

  1. What exact permission do I have to request?

You have to declare Manifest.permission.REQUEST_INSTALL_PACKAGES in your AndroidManifest.xml, like so:

    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
  1. How can I prompt the user to grant this permission?

You can send the user to the appropriate destination, with Intent ACTION_MANAGE_UNKNOWN_APP_SOURCES:

startActivity(new Intent(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES));

You may also send the user more directly to the specific setting for your application, with:

startActivity(new Intent(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:your.application.package")));
  1. How do I prompt the user to install a specified .apk?

Once you made sure you are granted the appropriate permission, you can prompt the user to install your .apk file anywhere in your Activity's code (where this refers to your Activity's Context), using:

Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setDataAndType(FileProvider.getUriForFile(this, "your.application.package.fileprovider", new File("/path/to/your/apk")), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

startActivity(intent);

You may also add intent.putExtra(Intent.EXTRA_RETURN_RESULT, true) and start with startActivityForResult(Intent, int), if you want to know if the installation succeeded, was cancelled or failed.

For information on how to correctly get your .apk file's Uri, see FileProvider.

Dreamworld answered 14/4, 2018 at 6:52 Comment(13)
Hi, Can I be able to make the third party apps or SDKs to install automatically once when Android application gets installed in Phone devices (Oreo)?Irishirishism
For an Instance, Trying to install Ola APK and it is getting installed in Oreo device. GPS third party SDK is calling via OLA Android application. So, GPS SDK should be installed automatically without making a user to allow or deny the unknown apps installation.Irishirishism
@Achiever: Sounds somewhat confusing, but what I understand is you want to install some third-party software on an Android device without user interaction? If that's the case, this answer isn't for you. I guess you would need root access to the user's device (assuming it is rooted) and you would still need to be granted that first (which requires a user interaction).Dreamworld
I have built one Android application. For an Instance, My Android app name is MobileShopping app. I tried to install this MobileShopping app in Oreo Mobile device. Inside MobileShopping app, I have payment SDK which enables banking transactions. In Oreo device, even after installing MobileBanking application, it is asking the permission to install third party app ie. Payment SDK which is already built inside MobileShopping app (as per development)Irishirishism
I need to show the permission granted dialogs to the user only wen I try to install the MobileShopping app in oreo device for the first time. I dont want to show the permission dialog or ask any permissions to the user even for third party apps access which is there inside MobileShopping appIrishirishism
@Achiever: To clarify: 'MobileShopping' app is an application you developed? How is it installed in the first place? Via PlayStore or a third-party app-store? And what exactly is 'Payment SDK'? A library or a seperate app? Did you develop it or someone else? Why do you have to install it afterwards and don't compile it as a dependency of 'Mobile Shopping' app? Anyway, I still don't think this answer is what you're looking for. Maybe you should ask a new question so others can help you, too.Dreamworld
'MobileShopping' app is an application I developed by myself. How is it installed in the first place? - Installed via USB by transferring APK from System folder to mobile device. And , 'Payment SDK' is a seperate app developed by others which APK was compiled when I am trying to build MobileShopping app. Which is present in Assets folder as PaymentSdk.apkIrishirishism
Why do you have to install it afterwards and don't compile it as a dependency of 'Mobile Shopping' app? - Yeah, how to do this? Any idea?Irishirishism
Hello, Thanks for the answer, There is one question. My targetSdkVersion is 22 and compileSdkVersion is 26 , How can I check getPackageManager().canRequestPackageInstalls() for this case. the method always returns false.Schatz
i cannot enable my app using startActivity(new Intent(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:your.application.package"))); it's disabledEyestrain
Confirmed working on Samsung TabActive 2 with Android 9.1. I can understand why they don't want your app to crash if user revokes that permission but I really miss the old days when you'd get an error in logcat when missing a permission. So it was kind of hard to find this solution.Borden
@Dreamworld Regarding #3, Thanks for the useful information and is there any way to have a call back once the user turned ON the permission. I tried to get the return result by intent.putExtra(Intent.EXTRA_RETURN_RESULT, true); along with StartActivityForResult, but it doesn't return me the result. Is there any way to do it?Emmieemmit
@Anish Kumar: No, as far as I know, you can't directly get a feedback on whether the user turned the permission on or not, because your Intent merely shows the appropriate setting to the user, he isn't forced to do anything about it (so a Toast explaining to the user what to actually do there could be useful). If you want to know whether or not you're granted the permission now, you'll just have to check again as in step 1. once the user returns to your Activity.Dreamworld
K
7

From adb shell you can mange app specific permissions using appops. Example:

# To get a list of packagenames that is allowed to install from other sources
appops query-op REQUEST_INSTALL_PACKAGES allow 

# To allow an app install packages from other sources
appops set <package name> REQUEST_INSTALL_PACKAGES deny 

Help text printed when running adb shell appops help:

AppOps service (appops) commands:
  help
    Print this help text.
  set [--user <USER_ID>] <PACKAGE | UID> <OP> <MODE>
    Set the mode for a particular application and operation.
  get [--user <USER_ID>] <PACKAGE | UID> [<OP>]
    Return the mode for a particular application and optional operation.
  query-op [--user <USER_ID>] <OP> [<MODE>]
    Print all packages that currently have the given op in the given mode.
  reset [--user <USER_ID>] [<PACKAGE>]
    Reset the given application or all applications to default modes.
  write-settings
    Immediately write pending changes to storage.
  read-settings
    Read the last written settings, replacing current state in RAM.
  options:
    <PACKAGE> an Android package name.
    <OP>      an AppOps operation.
    <MODE>    one of allow, ignore, deny, or default
    <USER_ID> the user id under which the package is installed. If --user is not
              specified, the current user is assumed.
Kenay answered 14/11, 2019 at 12:11 Comment(1)
There is no way to perform a appops set <package name> REQUEST_INSTALL_PACKAGES allow from an Android app?Vicarial

© 2022 - 2024 — McMap. All rights reserved.