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

隐身守侯 提交于 2019-11-27 12:48:50
Thupten

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

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.

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.)

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!