前几天jira上的apk自动更新,安装和打开的任务一直在被领导催促,因此也花了点时间把它写出来。
首先,此操作并不适合一般应用,因为对应的机器要root后才可以执行操作。
1.关于如何建立服务去下载一个apk的我就不多述了,这里是阐述apk下载完之后的相关操作。因为goole本身是不会对外开放自动安装的,因此手机也必须先root之后才可以进行自动安装,所用到的便是pm.install了,具体看以下代码:
public class SilentInstall {
/**
* 执行具体的静默安装逻辑,需要手机ROOT。
安装成功返回true,安装失败返回false。
*/
public booleaninstall(String apkPath) {
booleanresult =false;
DataOutputStream dataOutputStream =null;
BufferedReader errorStream =null;
try{
// 申请su权限
Process process = Runtime.getRuntime().exec("su");
dataOutputStream =newDataOutputStream(process.getOutputStream());
// 执行pm install命令
String command ="pm install -r "+ apkPath +"\n";
dataOutputStream.write(command.getBytes(Charset.forName("utf-8")));
dataOutputStream.flush();
dataOutputStream.writeBytes("exit\n");
dataOutputStream.flush();
process.waitFor();
errorStream =newBufferedReader(newInputStreamReader(process.getErrorStream()));
String msg ="";
String line;
// 读取命令的执行结果
while((line = errorStream.readLine()) !=null) {
msg += line;
}
Log.d("TAG","install msg is "+ msg);
// 如果执行结果中包含Failure字样就认为是安装失败,否则就认为安装成功
if(!msg.contains("Failure")) {
result =true;
}
}catch(Exception e) {
Log.e("TAG",e.getMessage(),e);
}finally{
try{
if(dataOutputStream !=null) {
dataOutputStream.close();
}
if(errorStream !=null) {
errorStream.close();
}
}catch(IOException e) {
Log.e("TAG",e.getMessage(),e);
}
}
returnresult;
}
}
接下来就可以直接在相应的地方进行使用啦,
SilentInstall install = new SilentInstall();
final boolean result = install.install(file.getPath());
runOnUiThread(new Runnable() {
@Override
public void run() {
if (result) {
Toast.makeText(getApplicationContext(), "安装成功!", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "安装失败!", Toast.LENGTH_SHORT).show();
}
}
});
这样一来自动安装就完成啦,下面进行最后一步,监听安装完自动打开app,请看以下代码:
public class OpenApkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if (intent.getAction().equals("android.intent.action.PACKAGE_REPLACED")){
Log.e("安装","升级了一个安装包,重新启动此程序");
Intent intents = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
context.startActivity(intents);
System.exit(0);
}
//接收安装广播
if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {
String packageName = intent.getDataString();
Log.e("安装","安装了:" +packageName + "包名的程序");
}
//接收卸载广播
if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) {
String packageName = intent.getDataString();
System.out.println("卸载了:" + packageName + "包名的程序");
}
}
}
最后在清单文件中静态注册以下广播就好啦,
<receiver android:name=".service.OpenApkReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<data android:scheme="package"/>
</intent-filter>
</receiver>
好了,接下来就可以进行测试了。