Android:关于InstallerPackgeName的二三事
来源:互联网 发布:好的漫画软件 编辑:程序博客网 时间:2024/05/16 14:38
【转载请注明出处】
作者: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
。以下是一些例子:
产商应用市场
笔者测试的设备是 SAMSUNG S7E 9350,部分系统级应用使用的安装器是三星应用市场,如下:
由此可以合理推测小米、华为等产商也应该会用同样的做法。不过笔者手头并没有这些设备,如果知道的同学欢迎留言告知。
Google Play 和第三方应用市场
Google Play 的安装器名称大部分是 com.android.vending
。如果你的统计量比较大的话你可能还会遇到一个名称是 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
的,嗯,看来大家的想法都是差不多的。
参阅资料:
StackOverFlow: Can PackageManager.getInstallerPackageName() tell me that my app was installed from Amazon app store?
https://stackoverflow.com/questions/13289748/can-packagemanager-getinstallerpackagename-tell-me-that-my-app-was-installed-fStackOverFlow: getInstallerPackageName returns null
https://stackoverflow.com/questions/12593621/getinstallerpackagename-returns-nullCoderWall: Check if an APK is from Google Play
https://coderwall.com/p/fipesa/check-if-an-apk-is-from-google-play
- Android:关于InstallerPackgeName的二三事
- 关于Android的prelink
- 关于android的文件系统
- 关于android的 context
- 关于Android的prelink
- 关于android的应用程序
- 关于android的资料
- 关于android的WebView
- 关于Android的安装
- 关于Android的Crash
- 关于android的ycbcr_422_i
- 关于Android的字体
- 关于Android的字体
- 关于android 的乱七八糟
- 关于Android的Crash
- 关于Android的ListView
- 关于Android的Handler
- 关于android的theme
- (九)View的滑动事件
- java模拟斗地主发牌看牌
- jquery获取select选中值的文本,并赋值给另一个输入框
- eclipse导入项目,项目名出现红叉的情况
- Linux 复习笔记
- Android:关于InstallerPackgeName的二三事
- Atitit 职位的规划与来源 1.1. 职位任命多元化1 1.2. 上级任命1 1.3. 自我推荐1 1.4. 他人推荐,1 1.5. 可以下级选举1 1.6. 缺席任命1 1.7.
- 最简单的原生js别踩白块儿
- 【Bootstrap Table】在指定列中添加下拉框控件,并获取所选值
- Unity c# Unicode 转中文
- 虚拟币开发专题(数字货币编译过程中常见问题)
- 1027. 打印沙漏
- opencv 图像叠加滚动条
- kubernetes从零到有,集群部署使用