Can PackageManager.getInstallerPackageName() tell me that my app was installed from Amazon app store?
Asked Answered
C

4

25

I plan on publishing my app on Amazon app store as well as Google Play, and have some things in my app that need to behave slightly different depending on whether the app was installed from Amazon app store or not. If I understood the PackageManager.getInstallerPackageName(String packageName) method correctly, it tells me the name of the application that installed my app. Right? If so, does anyone know what the value returned by this method would be if my app was installed from Amazon app store? If not, does anyone know any other methods I can use to determine whether my app was installed from the Amazon app store?

Note: I am aware of other questions on Stack Overflow which have been answered alluding to the usage of PackageManager.getInstallerPackageName(String packageName) to determine the name of the application that installed my app. However, searching Stack Overflow and elsewhere, I have not been able to determine what the value returned by PackageManager.getInstallerPackageName(String packageName) would be in case the app was installed from the Amazon app store.

Cresol answered 8/11, 2012 at 13:24 Comment(2)
Is it uk.amazon.mShop.android, which is the package name of Amazon Mobile for Android on Google Play?...Cresol
The Amazon Appstore for Android client is not on Google Play. You download it from Amazon. Simply download the client app onto your device, download some other app from their Appstore, then use getInstallerPackageName() to see what shows up. My guess is that this will be the same any app installed by any other means.Induline
C
8

Calling PackageManager.getInstallerPackageName(myPackageName), where myPackageName is the name of the package (of the app for which you wish to determine the installer) gives the following values:

  • null if the app was installed from Amazon app store
  • null if the app was installed directly outside of any app store.
  • com.android.vending if the app was installed from Google Play.

(Thanks @CommonsWare for the pointer.)

Cresol answered 8/11, 2012 at 16:41 Comment(3)
Adil, have you ever tested on the latest Android device with Google Play? As far as I know, the store app is renamed to "com.google.play" instead of "com.android.vending". Which will be returned? Currently, I tested on a real device with "Google Play" app updated from "Android Market". It shows as "com.android.vending". I am not sure if devices coming with the latest "Google Play" app still shows "com.android.vending". I have no such new device. If you can, could you help verify that? ThanksGeotectonic
Hi Lucas, I tested with an Android device running Android Version 4.0.4 and with the latest Google Play version at the time...Cresol
The apparent fact that Amazon or any app store returns null for getInstallerPackageName seems like a complete failure on their part. Considering a user can have both Google Play and Amazon or other stores installed on the same device it would seem that's the only way to distinguish where to make in-app purchases or links to the app within the store. Assuming you don't want to generate multiple apks.Eliseelisee
T
27

Since samsung has not implemented the PackageManager.getInstallerPackageName(), it still returns null. So use the PackageManager.getInstalledPackages() to get all the packages and search for the samsungapp packagename "com.sec.android.app.samsungapps".

Stores:

null - developer
com.android.vending - google play
com.amazon.venezia - amazon app
com.sec.android.app.samsungapps - samsung app store

Code:

// lets start with google play store link
String link = "https://play.google.com/store/apps/details?id=com.hellothupten.capital2countryquiz";

//find out the installer for your app package name.
String installer = getPackageManager().getInstallerPackageName(
        "com.hellothupten.capital2countryquiz");

if (installer == null) {
    List<PackageInfo> installedPackages = getPackageManager()
            .getInstalledPackages(PackageManager.GET_ACTIVITIES);
    for (PackageInfo p : installedPackages) {
        if (p.packageName.contains("samsungapps")) {
            // change to samsung app store link
            link = "http://apps.samsung.com/mars/topApps/topAppsDetail.as?productId=000000840239";
            break;
        }
    }
} else if (installer.contains("amazon")) {
    // change to amazon app store link
    link = "amzn://apps/android?p=com.hellothupten.capital2countryquiz";
} else if (installer.contains("samsung")) {
    // change to samsung app store link. This does not
    // exist..but who knows samsung may implement
    // getInstallerPackageName in future, I assume it will
    // contain a word samsung in its package name.
    link = "http://apps.samsung.com/mars/topApps/topAppsDetail.as?productId=000000840239";

}

Use the link variable as the store link.

Update:

samsungapps://ProductDetail/com.sec.chaton

Samsung: http://developer.samsung.com/android/technical-docs/Samsung-Apps-Deeplink-Guide

Tankage answered 22/5, 2014 at 21:37 Comment(1)
has samsung still not implemented it yet?Malacostracan
F
11

Good news! Apparently the latest version of the Amazon store finally sets PackageManager.getInstallerPackageName() to "com.amazon.venezia" to contrast with Google Play's "com.android.vending".

Older apps will still return null, and I haven't actually verified the API or whether installing the new Store and then upgrading an older app will set the installer. But installing a new app and checking /data/system/packages.xml indicates installer is correctly set.

Forbidding answered 31/5, 2013 at 17:39 Comment(1)
In Redmi Note 3 , this works fine but in HTC returns null. Any ideas ?Cocoa
C
8

Calling PackageManager.getInstallerPackageName(myPackageName), where myPackageName is the name of the package (of the app for which you wish to determine the installer) gives the following values:

  • null if the app was installed from Amazon app store
  • null if the app was installed directly outside of any app store.
  • com.android.vending if the app was installed from Google Play.

(Thanks @CommonsWare for the pointer.)

Cresol answered 8/11, 2012 at 16:41 Comment(3)
Adil, have you ever tested on the latest Android device with Google Play? As far as I know, the store app is renamed to "com.google.play" instead of "com.android.vending". Which will be returned? Currently, I tested on a real device with "Google Play" app updated from "Android Market". It shows as "com.android.vending". I am not sure if devices coming with the latest "Google Play" app still shows "com.android.vending". I have no such new device. If you can, could you help verify that? ThanksGeotectonic
Hi Lucas, I tested with an Android device running Android Version 4.0.4 and with the latest Google Play version at the time...Cresol
The apparent fact that Amazon or any app store returns null for getInstallerPackageName seems like a complete failure on their part. Considering a user can have both Google Play and Amazon or other stores installed on the same device it would seem that's the only way to distinguish where to make in-app purchases or links to the app within the store. Assuming you don't want to generate multiple apks.Eliseelisee
A
6

You are trying to determine whether your own app has been installed from the Amazon store, so the following pertains to that situation. But things have changed since you asked the question, so this answer is valid for 2016 when it was posted, not 2012.

As reported above, apps installed by versions of the Amazon installer released before about the middle of 2013 return null from getInstallerPackageName() when that method is passed the package name of the installed app. But after that time they started to return "com.amazon.venezia" for such a call. And recently, the Amazon Underground app may assign a second installer package name, com.amazon.mshop.android.

So, this is not a completely reliable indicator if you think you might encounter those older versions of the installer in the wild, because an app that is simply sideloaded (installed from a APK held in local storage) will also typically return null from getInstallerPackageName() when that method is called for its package, and thus will be indistinguishable from an app installed by one of those older Amazon store apps.

If, despite this problem, you want to use this approach, but would like to avoid false negatives for devices having the older installer versions that mark the installer as null, you might try the following:

  • Test getInstallerPackageName() to see if it is non-null.

  • If non-null, then just test to see if it starts with com.amazon, and you can believe that it was installed from Amazon if it does, and you can believe that it was not installed from Amazon if it does not.

  • But if null, do an additional test by iterating over every package on the device, feeding each package name encountered to getInstallerPackageName(), looking to see if there is even a single one that starts with "com.amazon".

    • If there are none with that value, then your null value is ambiguous, and you should consider that you do not have any information one way or the other regarding whether your app was installed from the Amazon store (as opposed to side-loaded).

    • But if there is even a single app having that installer package value, then you can assume that your app was not installed from the Amazon store, because it is a safe bet that the device is running a version of the Amazon store that tags installed apps with an installer package name starting with "com.amazon", given that at least one app other than yours was actually tagged that way - which is extremely unlikely to happen in any other way. And that means that the null value for your app was not created by the Amazon installer, but rather, by some other installer - and most probably it means that you app was side-loaded from a local copy of your APK.

Artema answered 22/4, 2016 at 7:34 Comment(1)
Amazon also uses uk.amazon.mShop.androidHluchy

© 2022 - 2024 — McMap. All rights reserved.