写在前面的一段话:如果你的项目是在各大厂的手机上面使用,那么我劝你放弃.这个静默安装使用于定制的系统上面,当然 你非要在手机上面用,那么就只有无障碍服务这一种方法了,root的手机.........不现实.
经过一段时间的查找资料,静默安装(自动安装)有三种办法:
1 已经root的手机,拿到root权限(年纪大了,不想折腾了 手机也没有刷过了,所以这个方法我没有试过)
2 使用无障碍服务 模拟点击
3 系统级别的APP
下面就这两张方法来实现
1 无障碍服务:
使用无障碍服务的时候,在Github里面找了一圈,找到一个还不错的Demo,地址是:https://github.com/a-voyager/AutoInstaller,代码比较简单 自己看看就能懂 同时这个Demo里面也有root权限安装的方法,封装的很不错,方便调用.但是因为客观情况,我的项目是一个盒子,有些可能没有显示屏,那我就没办法开启无障碍服务了,而且有的显示器分辨率和盒子不匹配,造成模拟点击不准确的问题.所以最后只能放弃了
2 系统级别的应用
首先是查资料,一查看都是说需要Android系统的签名文件(platform.pk8,platform.x509.pem,signapk.jar)这三个文件,签名两个文件是签名文件,最后一个是签名的工具.前面两个文件是需要你在对应的系统源码中去拿到的,最后的签名工具倒是通用的.我手机有两个硬件盒子,一个Android4.4.2,一个Android6.0.1.然后我就找了Android4.4版本的签名文件(因为网上有下载,所以我也就没有下载源码了),下载到的文件是这样的:
然后把你没有签名的app_debug文件放在这个文件夹里面,点击那个test3.bat(其实就是一句命令:java -jar signapk.jar platform.x509.pem platform.pk8 *.apk testsign.apk),就生成了这个testsign.apk文件.这个apk就是已经带系统签名的了.接下来记得在你的mainfest文件里面增加
android:sharedUserId="android.uid.system"
然后发现新版本的时候 判断APP是否为系统APP,是的话就使用第三种方法安装,不是就使用第二种方法安装:
第三种方法安装代码:
/**
* 21 * APK静默安装
* 22 *
* 23 * @param apkPath
* 24 * APK安装包路径
* 25 * @return true 静默安装成功 false 静默安装失败
* 26
*/
public static boolean install45(String apkPath) {
String[] args = {"pm", "install", "-r", apkPath};
String result = apkProcess(args);
Log.e(TAG, "install log:" + result);
if (result != null
&& (result.endsWith("Success") || result.endsWith("Success\n"))) {
return true;
}
return false;
}
/**
* 57 * 应用安装、卸载处理
* 58 *
* 59 * @param args
* 60 * 安装、卸载参数
* 61 * @return Apk安装、卸载结果
* 62
*/
public static String apkProcess(String[] args) {
String result = null;
ProcessBuilder processBuilder = new ProcessBuilder(args);
Process process = null;
InputStream errIs = null;
InputStream inIs = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int read = -1;
process = processBuilder.start();
errIs = process.getErrorStream();
while ((read = errIs.read()) != -1) {
baos.write(read);
}
baos.write('\n');
inIs = process.getInputStream();
while ((read = inIs.read()) != -1) {
baos.write(read);
}
byte[] data = baos.toByteArray();
result = new String(data);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (errIs != null) {
errIs.close();
}
if (inIs != null) {
inIs.close();
}
} catch (Exception e) {
e.printStackTrace();
}
if (process != null) {
process.destroy();
}
}
return result;
}
判断是否为系统APP代码:
public static boolean isSystemApplication(Context context, String packageName){
PackageManager manager = context.getPackageManager();
try {
PackageInfo packageInfo = manager.getPackageInfo(packageName, PackageManager.GET_CONFIGURATIONS);
if((packageInfo.applicationInfo.flags & android.content.pm.ApplicationInfo.FLAG_SYSTEM)!=0){
return true;
}
// 1
if(new File("/data/app/"+packageInfo.packageName+".apk").exists()){
return true;
}
// 2
if(packageInfo.versionName!=null && packageInfo.applicationInfo.uid>10000){
return true;
}
// 3
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return false;
}
最后,还有一个惊喜,我用Android 4.4签名文件签名的apk,在另一个6.0的盒子上面,居然也是系统APP,惊不惊喜.......可能我这边是因为不是各大厂的定制rom,所以签名文件没有改变,我只能这样安慰自己了,同时也告诉你们一下,多试一下说不定会有惊喜呢
签名文件网上已经有了,这边不让我上传了.............