最近在做关于静默安装的功能,网上搜了好久,一直没有解决,后来结合各位大神的思路,终于把这个功能完整的实现了,好啦,废话不多说了,开始正文,该方法用的调用android隐藏方法,不需要获取ROOT权限,
首先,要使用静默安装,肯定得添加系统级的签名,(manifest中添加这句:android:sharedUserId="android.uid.system"),后边会介绍怎么给应用加签名的
然后,开始调用android源码中隐藏的类和方法(也就是PackageManager),调用隐藏的方法大概有两种,一种是利用反射,还有一种就是重新编译android源码,网上有牛人重新编译好的.jar,这里就直接拿来用了,以下是Eclipse中的设置步骤:
在此放上需要的类和编译后的jar
1.右键项目,打开Build Path,进入Configure Build Path
2.Add Library,选择User Library,
3.新建一个,取名为framework,
4.Add Exernal JARS...选择上边提到的编译好的jar包
5.添加完成,把framework前边的小框打钩,并且通过Up上移到android源码上边
至此,就可以调用隐藏的方法啦 ~\(≧▽≦)/~啦啦啦
但是需要注意的一些问题
1) 无论是反射还是使用自编译的 stublibrary ,只能解决调用隐藏 API 的问题,而无法越过权限检查。
2)Google 之所以将有些 API 隐藏,有些原因可能是因为这些 API 属于内部逻辑,不想对外暴露,也有可能是 API 接口还未最终确定下来。所以在低版本 Android 上的隐藏 API 不一定能在高版本的 Android 上使用。这点是一定要注意的。也就说隐藏 API 的兼容性比较差。因此利用反射调用隐藏 API 时,一定要注意根据 Android 的版本采用不同的方式去反射。
接下来,我们开始调用:(这里说一下,PackageInstaller这个类里边的方法大家可以看看,自由选择调用就行)
PackageInstaller piInstaller = new PackageInstaller(getApplicationContext());
piInstaller.instatllBatch(updatePath);
别忘记了加权限哟:
<!-- 静默安装所需的权限 -->
<uses-permission android:name="android.permission.INSTALL_LOCATION_PROVIDER" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
如果报错,Project→Clean一下就好
在此添加系统签名需要的工具,大家也可以去网上查查怎么获取,
通过上面两行代码,我们就可以静默安装应用啦,但是,直接运行肯定会报错的,因为我们用到了系统级的签名,没错,就是上边说到的(android:sharedUserId="android.uid.system"),在此我们需要给应用加系统签名
1.项目右键,Android Tools选择 Export Unsigned Application Package,到处未加签名的应用
2.把上边的 platform.pk8,platform.x509.pem,signapk.jar以及未加签名的apk放在同一个文件夹下
3.在cmd中,定位到该文件夹,然后执行 java -jar signapk.jar platform.x509.pem platform.pk8 len.apk newlen_signed.apk (其中 len.apk是未加签名的,newlen_signed是打包后的 )
4.然后把打包后的APK安装在设备上就可以啦,
在这里提醒下大家,使用系统签名并且也用到百度地图的,记得获取系统的数字证书,不然地图会不好使的(这个问题折磨了我好久 %>_<%),
亲测更新的apk不会把用户数据清除,大家放心使用,下边是几个广播,大家可以看看:
<action android:name="android.intent.action.PACKAGE_ADDED" /> 设备上新安装了一个应用程序包
<action android:name="android.intent.action.PACKAGE_REMOVED" />设备上删除了一个应用程序包
<action android:name="android.intent.action.PACKAGE_REPLACED" />设备上升级了一个应用程序包
首先,要使用静默安装,肯定得添加系统级的签名,(manifest中添加这句:android:sharedUserId="android.uid.system"),后边会介绍怎么给应用加签名的
然后,开始调用android源码中隐藏的类和方法(也就是PackageManager),调用隐藏的方法大概有两种,一种是利用反射,还有一种就是重新编译android源码,网上有牛人重新编译好的.jar,这里就直接拿来用了,以下是Eclipse中的设置步骤:
在此放上需要的类和编译后的jar
1.右键项目,打开Build Path,进入Configure Build Path
2.Add Library,选择User Library,
3.新建一个,取名为framework,
4.Add Exernal JARS...选择上边提到的编译好的jar包
5.添加完成,把framework前边的小框打钩,并且通过Up上移到android源码上边
至此,就可以调用隐藏的方法啦 ~\(≧▽≦)/~啦啦啦
但是需要注意的一些问题
1) 无论是反射还是使用自编译的 stublibrary ,只能解决调用隐藏 API 的问题,而无法越过权限检查。
2)Google 之所以将有些 API 隐藏,有些原因可能是因为这些 API 属于内部逻辑,不想对外暴露,也有可能是 API 接口还未最终确定下来。所以在低版本 Android 上的隐藏 API 不一定能在高版本的 Android 上使用。这点是一定要注意的。也就说隐藏 API 的兼容性比较差。因此利用反射调用隐藏 API 时,一定要注意根据 Android 的版本采用不同的方式去反射。
接下来,我们开始调用:(这里说一下,PackageInstaller这个类里边的方法大家可以看看,自由选择调用就行)
PackageInstaller piInstaller = new PackageInstaller(getApplicationContext());
piInstaller.instatllBatch(updatePath);
别忘记了加权限哟:
<!-- 静默安装所需的权限 -->
<uses-permission android:name="android.permission.INSTALL_LOCATION_PROVIDER" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
如果报错,Project→Clean一下就好
在此添加系统签名需要的工具,大家也可以去网上查查怎么获取,
通过上面两行代码,我们就可以静默安装应用啦,但是,直接运行肯定会报错的,因为我们用到了系统级的签名,没错,就是上边说到的(android:sharedUserId="android.uid.system"),在此我们需要给应用加系统签名
1.项目右键,Android Tools选择 Export Unsigned Application Package,到处未加签名的应用
2.把上边的 platform.pk8,platform.x509.pem,signapk.jar以及未加签名的apk放在同一个文件夹下
3.在cmd中,定位到该文件夹,然后执行 java -jar signapk.jar platform.x509.pem platform.pk8 len.apk newlen_signed.apk (其中 len.apk是未加签名的,newlen_signed是打包后的 )
4.然后把打包后的APK安装在设备上就可以啦,
在这里提醒下大家,使用系统签名并且也用到百度地图的,记得获取系统的数字证书,不然地图会不好使的(这个问题折磨了我好久 %>_<%),
亲测更新的apk不会把用户数据清除,大家放心使用,下边是几个广播,大家可以看看:
<action android:name="android.intent.action.PACKAGE_ADDED" /> 设备上新安装了一个应用程序包
<action android:name="android.intent.action.PACKAGE_REMOVED" />设备上删除了一个应用程序包
<action android:name="android.intent.action.PACKAGE_REPLACED" />设备上升级了一个应用程序包