Android:关于InstallerPackgeName的二三事

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DrkCore/article/details/76290656

【转载请注明出处】
作者:DrkCore
原文:http://blog.csdn.net/drkcore/article/details/76290656

在应用开发中我们通常会在应用的打包脚本中标注多个渠道,用以统计应用在不同的应用市场中的效果。这当然是一个不错的做法,不过有的时候我们还想要知道用户是通过什么方式安装应用的,此时就需要使用 InstallerPackageName 了:

package android.content.pm;
public abstract class PackageManager {
    /**
     * Retrieve the package name of the application that installed a package. This identifies
     * which market the package came from.
     *
     * @param packageName The name of the package to query
     */
    public abstract String getInstallerPackageName(String packageName);
}

我们可以通过 PackageManager.getInstallerPackageName(String pack) 来获取某个应用安装时使用的安装器的名称。看起来非常的方便但是该方法并不能代替渠道号的作用。

常见的返回值

大部分系统应用和通过 ADB 安装的应用(包括使用 AS 运行安装)会返回 null,而直接打开 APK 安装的则会返回 com.google.android.packageinstaller。以下是一些例子:

Package Installer Desc
com.android.mms null 系统短信服务
com.android.mms.service null 系统短信服务
core.demo null 通过 Adb 直接安装的应用
net.openvpn.openvpn com.google.android.packageinstaller 设备默认安装器
com.baidu.tieba_mini com.google.android.packageinstaller 设备默认安装器
com.netease.cloudmusic com.google.android.packageinstaller 设备默认安装器

产商应用市场

笔者测试的设备是 SAMSUNG S7E 9350,部分系统级应用使用的安装器是三星应用市场,如下:

Package Installer Desc
com.sec.android.app.samsungapps com.sec.android.app.samsungapps 三星应用市场
com.samsung.android.themestore com.samsung.android.themestore 三星主题商店
com.enhance.gameservice com.enhance.gameservice 三星的游戏服务

由此可以合理推测小米、华为等产商也应该会用同样的做法。不过笔者手头并没有这些设备,如果知道的同学欢迎留言告知。

Google Play 和第三方应用市场

Google Play 的安装器名称大部分是 com.android.vending。如果你的统计量比较大的话你可能还会遇到一个名称是 com.google.android.feedback,它代表的是旧版的谷歌市场,不过其占有量现在应该很低了。

Package Installer Desc
com.google.android.gm com.android.vending GooglePlay
com.android.chrome com.android.vending GooglePlay
笔者并没有旧版的谷歌市场 com.google.android.feedback 旧版的谷歌市场

Google Play 毕竟是官家的市场,installer 的返回值是有保证的。但是第三方的市场有可能并不遵守这样的规则。

笔者测试中使用了百度应用市场发现其安装器是 com.google.android.packageinstaller 也就是系统默认的安装器。普通应用想要发起安装 APK 的请求都是通过以下的 Intent 来安装的,此时打开的界面就是默认安装器:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://" + apk), "application/vnd.android.package-archive");

context.startActivity(intent);

猜测原因是因为第三方应用市场在未 Root 的设备中本身也只是普通的应用所以并无权限,而产商应用市场和 Google Play 持有系统签名可以设置自己的安装器名称。

但由于条件原因笔者并未测试过 Root 后开启静默安装的百度市场的行为,如有同学知道的还请告知。

更新版本对 Installer 的影响

先说结论:更新应用会根据安装方法刷新 installerName

笔者设备上的百度地图原本是通过三星应用市场安装的:

这里写图片描述

在使用了百度应用市场更新后其 installer 就变成了默认安装器:

这里写图片描述

笔者也试过用 Google Play 来更新应用,结果和上述结论一致:

这里写图片描述

InstallerName 某种程度上算是实时变化的,这一点和部分数据统计 SDK 比如友盟就不一样。按照友盟的策略应用在一台设备上的渠道号只认准首次安装时的值,就算后期用户手动换了渠道后也是一样。在实际开发中这一点需要注意。

如何修改渠道号

Adb 命令修改

pm install -i installerName file.apk 可以在安装时修改 installerName

该方法可以使用任意的值,比如笔者在测试中就是用了中文作为 installerName:

hero2qltechn:/sdcard $ pm install -i 这个是使用adb写入的包名 app-debug.apk

这里写图片描述

在测试的时候可以使用该方法来验证结果。

代码修改

PackageManager.setInstallerPackage() 可以修改 installerName 但是限制比较多

/**
* Change the installer associated with a given package.  There are limitations
* on how the installer package can be changed; in particular:
* <ul>
* <li> A SecurityException will be thrown if <var>installerPackageName</var>
* is not signed with the same certificate as the calling application.
* <li> A SecurityException will be thrown if <var>targetPackage</var> already
* has an installer package, and that installer package is not signed with
* the same certificate as the calling application.
* </ul>
*
* @param targetPackage The installed package whose installer will be changed.
* @param installerPackageName The package name of the new installer.  May be
* null to clear the association.
*/
public abstract void setInstallerPackageName(String targetPackage, String installerPackageName);

该方法并不要求任何的特殊权限,但是要求调用者要和要修改成的安装器对应的应用要有相同的签名。

实测中 installerPackageName 对应的应用必须已安装,由于签名的原因笔者只能将之设置成自身的名字:

这里写图片描述

其他

关于海外市场的开发者可能知道某些广告 SDK 提供商最近修改了相关政策不再向非 Google Play 下载的应用提供广告。出于好奇笔者找了下其 SDK 发现了如下代码:

这里写图片描述

这里写图片描述

其实现就是获取包名然后再 PackageManager.getInstallerPackageName 的,嗯,看来大家的想法都是差不多的。

参阅资料:

猜你喜欢

转载自blog.csdn.net/DrkCore/article/details/76290656