It is possible to grant privileges to an already installed application by not requesting the permissions in the "main" app and by creating another application ("stub") using the same android:sharedUserId
, which requests the features. You can then check if the permission-stub application has been installed by checking if
context.checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED
evaluates to true (with context as a valid context and permission as one of the permission strings). If it is true, your stub app has been installed and you may unlock features requireing the permissions granted. If it is false, you just fall back to the basic features.
When designing your app that way you can easily re-introduce the optional permissions into the main apk without having to change any code, for example if you distribute multiple versions.
You can now query privileges from the user by triggering the installation of (one of) your stub application(s). So if your privileges are required after some user input in an activity, launch the apk to pop up if the privilege has not been granted (of course you may put an explanatory activity in front of it), and execute the feature when coming back from the package manager or when the permission was granted before. You may as well put the option to enable or disable permissions somewhere in your preferences or a firstrun dialog.
For lazy people (like me) a short summary on how to bring the package installer up: Create an Intent
using Intent.ACTION_VIEW
for a file://
-URI using the Type "application/vnd.android.package-archive"
. Assets and Ressources do not work directly, you could for example bundle it as asset and copy it to the cache folder or similar.
Warning: This answer might not comply with the Google Play ToS, as this method has some uninstallation issues (might leak apps, see below) expecially when uninstalling via third-party mechanisms (like Google Play, as the user does not see the helper apps using these methods) and as optional privileges cannot get displayed in the play store afaik.
For the uninstallation issues I'd recommend to use names like "MyApp: XXX permissions", given the application name is "MyApp", so the user can easily remove them all in alphabetically listed lists. Alternately, if you can live with the stub applications getting more complex, use ACTION_PACKAGE_REMOVED as mentioned here.