如何知道应用程序是从 google play 还是侧载安装的?

Posted

技术标签:

【中文标题】如何知道应用程序是从 google play 还是侧载安装的?【英文标题】:How to know an application is installed from google play or side-load? 【发布时间】:2012-06-04 06:49:02 【问题描述】:

我需要检测我的应用程序是从 google play 或其他市场安装的,我如何获取此信息?

【问题讨论】:

Google 推出了新的 Sideload Prevention API:developer.android.com/guide/app-bundle/sideload-check?hl=en-419 【参考方案1】:

PackageManager 类提供了getInstallerPackageName 方法,该方法将告诉您安装您指定的包的包名。侧载应用不会包含值。

编辑:注意@mttmllns'answer below 关于亚马逊应用商店。

【讨论】:

@AbhishekB 您使用的是哪个版本的 Android?你在模拟器中吗? @AbhishekB 我不知道找到侧载应用程序起源的方法。我不确定如何跟踪它,因为从技术上讲,它只是一个 APK 文件,它被加载到设备上的某个地方,然后可能通过 PackageManager 安装。 getinstallerPackageName 链接返回服务器错误。所以链接似乎已关闭。 我们可以通过 adb 设置安装包名称。是否有任何其他 api 可以让我们检查应用程序是否通过 playstore 安装。 @MattC 我在中国的百度商店和 Playstore 中安装了相同的应用程序。由于包名相同,在这种情况下如何识别。【参考方案2】:

仅供参考,亚马逊商店的最新版本PackageManager.getInstallerPackageName() 最终将"com.amazon.venezia" 设置为"com.amazon.venezia",并与Google Play 的"com.android.vending" 形成对比。

【讨论】:

无法从 PackageManager 类型中对非静态方法 getInstallerPackageName(String) 进行静态引用 每个应用商店在 Playstore 上都有自己的市场应用,然后安装他们的 apk(包)。 packagemanager getInstaller...() 返回安装给定 apk 的市场应用的包名称。例如。 com.amazon.venezia 是 amazon marketapp 的包名。非常聪明,因为 PlayStore 可以控制哪些市场应用程序是可信的。这是为了最终防止所有不受信任的侧载。注意到新 android 操作系统版本的使用量正在急剧下降。 KitKat 可能会成为事实上的标准。 getInstallerPackageName() 方法在 Redmi Note 3 上返回正确值,但在 HTC 中返回 null。此设备是否依赖? 如果应用程序预安装在设备中,比如说相机、计算器和其他系统应用程序。你会得到空值。 有谁知道亚马逊应用商店如何在没有 root 权限的情况下将 InstallerPackageName 设置为继承包?在最新的 Android 版本(牛轧糖/奥利奥/派)中,传统方式似乎不起作用,您将 PackageInstaller 作为安装应用程序的应用程序。【参考方案3】:

我使用此代码检查构建是从商店下载还是侧载:

public static boolean isStoreVersion(Context context) 
    boolean result = false;

    try 
        String installer = context.getPackageManager()
                                    .getInstallerPackageName(context.getPackageName());
        result = !TextUtils.isEmpty(installer);
     catch (Throwable e)           
    

    return result;

科特林:

  fun isStoreVersion(context: Context) =
    try 
      context.packageManager
        .getInstallerPackageName(context.packageName)
        .isNotEmpty()
     catch (e: Throwable) 
      false
    

【讨论】:

如何在不将应用真正推送到 Google Play 进行测试的情况下进行测试? 我认为这不可能。不过你可以使用私人测试版。 这可能有用medium.com/@pixplicity/… Kotlin 版本应以 isNotEmpty() 结尾 可能不是一个可靠的解决方案。见***.com/a/36299631/1159930【参考方案4】:

如果您正在考虑识别和限制侧载应用。谷歌已经提出了解决问题的解决方案。

您可以按照以下方式关注

项目的build.gradle

buildscript 
 dependencies 
  classpath 'com.android.tools.build:bundletool:0.9.0'
 

App 模块的build.gradle:

implementation 'com.google.android.play:core:1.6.1'

扩展应用程序的类:

public void onCreate() 
if (MissingSplitsManagerFactory.create(this).disableAppIfMissingRequiredSplits()) 
    // Skip app initialization.
    return;

super.onCreate();
.....

通过这种集成,谷歌将自动识别是否缺少任何拆分 apk,并显示一个弹出窗口“安装失败”,它还会重定向到用户可以正确安装应用程序的 Play 商店下载屏幕通过 Google Play 商店。

查看此link 了解更多信息。

希望这会有所帮助。

【讨论】:

我遇到了这个blog 并明白这只有在使用拆分 apk 功能时才有用。并且只有在拆分 apk 无法读取某些依赖项时才有效。对吗? 只有当您的应用支持 App Bundle,如果您的应用支持 Play 商店的传统单一 APK 交付时,这才有用。这行不通。 @Naveen T P 嗨,如果这确实有效,我该如何测试?它让我可以通过 android studio 安装应用程序。

以上是关于如何知道应用程序是从 google play 还是侧载安装的?的主要内容,如果未能解决你的问题,请参考以下文章

从 Google Play 但不是从 Android Studio 运行时出现 NullPointerException

如何在运行时确定应用程序是通过 amazon appstore 还是 Google play 安装的

Google play 如何知道应用安装的国家/地区?

如何评估 Google Play 热门应用?

如果应用是从 Google Play 商店下载的,Android 应用是不是只会收到推送通知? (反应原生博览会)

如何在 Google Play 应用说明中写粗体文字?