56

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.

Cœur
  • 37,241
  • 25
  • 195
  • 267
neteinstein
  • 17,529
  • 11
  • 93
  • 123
  • 1
    possible duplicate of [Install Application programmatically on Android](http://stackoverflow.com/questions/4604239/install-application-programmatically-on-android) – Xaver Kapeller May 16 '14 at 12:40
  • 1
    It's not the same. In this case, the APK is not downloaded by Google Drive app and then installed. Google Drive "tells" Play Store to download & install. I'll post a screenshot. – neteinstein May 16 '14 at 12:55
  • Interesting. can you post the answer if you do find something on it? – user2511882 May 16 '14 at 13:21
  • Sure. I'll be glad to. Hope this isn't dismissed as "duplicate" before I find it.. – neteinstein May 16 '14 at 13:24
  • 1
    I've been looking around for a while and I don't think that this is possible. There might be a way, but it's difficult to figure out how this works in the first place. Most likely it is an `Intent` send to the Play Store with some extra telling it to download an app but you would have to reverse engineer the Play Store to figure that out. – Xaver Kapeller May 16 '14 at 13:47
  • 2
    Starred, +1, etc. I'm very interested in this. I will keep looking for a solution. Will test a few things and maybe even take a shot at reverse engineering this :D – Xaver Kapeller May 16 '14 at 14:09
  • what should be in extra name and value? – Tushar Saha Sep 13 '15 at 09:22

4 Answers4

53

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.

ozbek
  • 20,955
  • 5
  • 61
  • 84
  • Just curious, but did you try this? `http://developer.android.com/reference/android/content/Context.html#createPackageContext(java.lang.String, int)` Would it throw a SecurityException? – telkins Aug 18 '14 at 17:07
  • No, I did not try @trevor-e and I did not understand how that fits into the problem. – ozbek Aug 18 '14 at 23:04
  • `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:` The link I sent you allows you to get a context object of another app, and could potentially run that Intent for you. – telkins Aug 19 '14 at 14:08
  • what should be in extra_name and Extra_Value in intent.putExtra – Tushar Saha Sep 13 '15 at 11:24
  • @TusharSaha, it does not matter what you put there. Your attempt will fail with "called from untrusted package" error anyway. – ozbek Sep 13 '15 at 17:19
  • what is new Intent(), setClassName() and putExtra() parameters? – roghayeh hosseini Nov 14 '18 at 14:02
6

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. :(

Manuel Allenspach
  • 12,467
  • 14
  • 54
  • 76
  • 1
    Just need to know if it works also with an Intent. If it does, you might just have nailed it! – neteinstein May 19 '14 at 10:43
  • As per your link from androidb.com, this won't automatically install the app, but only open the installation page (user still needs to confirm it). – Andrew T. Apr 26 '16 at 07:21
3

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

Miguel Ribeiro
  • 8,057
  • 20
  • 51
  • 74
  • I would agree with you but... it's not a system app. I can uninstall it. So this is a new way probably. The permission needed and how it's done is the thing I'm looking forward to know. – neteinstein May 16 '14 at 13:52
  • You can have system permissions in apps that can be uninstalled. All you need is to sign the app using the OEM certificate and the OS will give you those permissions (AFAIK, correct me if I'm wrong) – Miguel Ribeiro May 16 '14 at 22:22
  • Even when your app is considered a system app, it would need the apk already downloaded to call the intent `Intent.ACTION_INSTALL_PACKAGE`. So it wouldn't work for apks that should be downloaded from google play. – Cassio Landim Jun 26 '14 at 17:56
0

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);
Jota
  • 82
  • 1
  • 3