How to install applications programmatically without opening Play Store (as Google Drive does)

Android

Android Problem Overview


Today the Google Drive app asked if I wanted to install the new apps Sheets & Docs.

I've accepted, expecting it to open Google Play Store so I could press install.

It didn't. It just showed me the popup with the permissions of each of the apps to confirm the installation, the same that appears when you press "Install" on any app on the Play Store.

I was not aware this could be done.

How can we reproduce this behavior in an app: have a button "Install App XPTO" which doesn't need to open Google Play Store? Just shows the permissions dialog and proceeds to install it via Play Store?


UPDATE:

For those downvoting because they think this is the same as other questions... It's not!

In this case, the APK is not downloaded by Google Drive app and then installed. Google Drive "tells" Play Store to download & install.

That's the API that I'm interested.

To support my case: after pressing INSIDE Google Drive to install the apps without opening Play Store, the download starts. During the download I've opened the Play Store to check and:

enter image description here

The screenshot proves that it isn't Google Drive downloading the APK and the installing it. It's the Play Store.

Android Solutions


Solution 1 - Android

The logs for Google Drive shows that activity responsible for "telling" the Google Play Store to install apps is

com.google.android.apps.docs/com.google.android.apps.docs.app.PhoneskyApplicationInstallerActivity

which, apparently, "tells"

com.android.vending/com.google.android.finsky.billing.lightpurchase.LightPurchaseFlowActivity

to install required packages.

So, theoretically, one could create an intent

Intent intent = new Intent("com.android.vending.billing.PURCHASE");
intent.setClassName("com.android.vending",
        "com.google.android.finsky.billing.lightpurchase.LightPurchaseFlowActivity");
intent.putExtra(EXTRA_NAME, EXTRA_VALUE);
startActivityForResult(intent, 0);

with correct extra values and voilĂ !

However, calling LightPurchaseFlowActivity from non-Google signed app is failing, because they are, again apparently (according to the logs), checking the calling package's signature:

W/Finsky(13209): [1] LightPurchaseFlowActivity.setupFromExternalPurchaseIntent: Called from untrusted package.

So, there, this can not be achieved at this moment.

Solution 2 - Android

Google+ now implements buttons where you can directly download an app (see this link) without clicking the button on the play store site.

The link looks like this: https://play.google.com/store/apps/details?id=com.example.app&rdid=com.example.app&rdot=1&feature=md

If you add the rdid, rdot and feature parameter it works on my phone (if I type it in the browser, not tested with an intent and not tested to update an app, only installing it).

Edit:

I found out that you only need to add the rdid-parameter to the url. Source: http://www.androidb.com/2014/04/increase-app-installs-with-a-single-trick/

Edit2:

Does not work with an intent. :(

Solution 3 - Android

I'd say that the Google Drive has system permissions, just like the Play Store. Probably because it is signed with Google's signature.

If you manage to have the "android.permission.INSTALL_PACKAGES" permission you can call the API (which is not included in the android.jar deployed by SDK Manager, you have to get the hidden APIs from the android.jar in the emulator for instance) to install the applications.

So, basically, unless you have system permissions (by putting your APK into /system/app, signed with OEM certificate or with root) you won't be able to do it.

Source: Already programmed some system apps

--- UPDATE

Of course the play store may have some door that you can use to install any application but that probably requires a permissions that you can't get on your own

Solution 4 - Android

If you know where you have the apk file, you can easily.

File file = new File(dir, "YourApp.apk");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(intent);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionneteinsteinView Question on Stackoverflow
Solution 1 - AndroidozbekView Answer on Stackoverflow
Solution 2 - AndroidManuel AllenspachView Answer on Stackoverflow
Solution 3 - AndroidMiguel RibeiroView Answer on Stackoverflow
Solution 4 - AndroidJotaView Answer on Stackoverflow