21

我计划在亚马逊应用商店和 Google Play 上发布我的应用程序,并且我的应用程序中有一些东西需要根据应用程序是否从亚马逊应用程序商店安装而略有不同。如果我正确理解了该PackageManager.getInstallerPackageName(String packageName)方法,它会告诉我安装我的应用程序的应用程序的名称。正确的?如果是这样,如果我的应用程序是从亚马逊应用商店安装的,有谁知道这种方法返回的值是多少?如果没有,是否有人知道我可以使用其他方法来确定我的应用程序是否是从亚马逊应用商店安装的?

注意:我知道有关 Stack Overflow 的其他问题已经得到回答,这些问题暗示使用 PackageManager.getInstallerPackageName(String packageName)来确定安装我的应用程序的应用程序的名称。但是,在搜索 Stack Overflow 和其他地方时,我无法确定如果应用程序是从亚马逊应用商店安装的,则返回 的值是多少。PackageManager.getInstallerPackageName(String packageName)

4

4 回答 4

24

由于三星没有实现 PackageManager.getInstallerPackageName(),它仍然返回 null。所以使用 PackageManager.getInstalledPackages() 来获取所有的包并搜索 samsungapp 包名“com.sec.android.app.samsungapps”。

商店:

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

代码:

// 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";

}

使用链接变量作为商店链接。

更新:

samsungapps://ProductDetail/com.sec.chaton

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

于 2014-05-22T21:37:07.673 回答
11

好消息!显然,亚马逊商店的最新版本终于PackageManager.getInstallerPackageName()"com.amazon.venezia"Google Play 的"com.android.vending".

较旧的应用程序仍会返回null,我还没有真正验证 API 或安装新商店然后升级旧应用程序是否会设置安装程序。但是安装一个新的应用程序并检查/data/system/packages.xml是否installer正确设置。

于 2013-05-31T17:39:57.703 回答
7

调用PackageManager.getInstallerPackageName(myPackageName),其中myPackageName包的名称(您希望为其确定安装程序的应用程序)提供以下值:

  • null如果应用是从亚马逊应用商店安装的
  • null如果应用程序直接安装在任何应用程序商店之外。
  • com.android.vending如果应用是从 Google Play 安装的。

(感谢@CommonsWare 的指点。)

于 2012-11-08T16:41:43.047 回答
6

您正在尝试确定您自己的应用程序是否已从亚马逊商店安装,因此以下内容与这种情况有关。但是自从你提出这个问题后情况发生了变化,所以这个答案在发布时适用于 2016 年,而不是 2012 年。

如上所述,由大约 2013 年年中之前发布的 Amazon 安装程序版本安装的应用程序在向 getInstallerPackageName() 传递已安装应用程序的包名称时从 getInstallerPackageName() 返回 null。但在那之后,他们开始为这样的电话返回“com.amazon.venezia”。最近,Amazon Underground 应用程序可能会分配第二个安装程序包名称 com.amazon.mshop.android。

因此,如果您认为您可能会在野外遇到那些较旧版本的安装程序,这并不是一个完全可靠的指标,因为只是侧载的应用程序(从本地存储中保存的 APK 安装)通常也会从 getInstallerPackageName( ) 当为其包调用该方法时,因此与那些较旧的亚马逊商店应用程序之一安装的应用程序无法区分。

如果尽管存在此问题,您仍想使用此方法,但又希望避免对具有将安装程序标记为空的较旧安装程序版本的设备产生误报,您可以尝试以下操作:

  • 测试 getInstallerPackageName() 以查看它是否为非空。

  • 如果不为空,则只测试它是否以com.amazon开头,如果是则认为是从亚马逊安装的,如果不是则认为不是从亚马逊安装的。

  • 但如果为 null,则通过迭代设备上的每个包进行额外测试,将遇到的每个包名称提供给 getInstallerPackageName(),查看是否有一个以“com.amazon”开头的包。

    • 如果没有具有该值的值,那么您的 null 值是不明确的,并且您应该认为您没有任何关于您的应用程序是否从亚马逊商店安装(而不是侧面加载)的信息。

    • 但是,如果甚至有一个应用程序具有该安装程序包值,那么您可以假设您的应用程序不是从亚马逊商店安装的,因为可以肯定的是,该设备正在运行标记已安装应用程序的亚马逊商店版本安装程序包名称以“com.amazon”开头,因为实际上至少有一个应用程序不是您的应用程序以这种方式标记 - 这不可能以任何其他方式发生。这意味着您的应用程序的 null 值不是由亚马逊安装程序创建的,而是由其他一些安装程序创建的 - 很可能这意味着您的应用程序是从 APK 的本地副本侧加载的。

于 2016-04-22T07:34:28.703 回答