现在很多应用比如360卫士,很多应用市场都搞后台的静默安装.对于静默安装,首先需要设备已经root了, 不然只能依赖系统自带的安装了.(之前在网上论坛看到有评论说不root也能实现静默安装,但最近了解下还是没研究出来,也许是我研究的不够深入吧,后面继续学习这方面的东西.) ,实现一般使用隐藏的PM接口, 或者shell命令.
关于隐藏api去实现 这篇文章已经写得很仔细,所以这里选择了后者.当然在网上看了不少文章也很多人实现. 所以这里算是总结学习的经验并加入一些修改.尽量完整的记录下来.让我们一起来学习吧~
public class MainActivity extends Activity {
//将某个包名为com.test.install的应用xxx.apk放在手机内置存储的根目录中
private String appPath = "/mnt/sdcard/xxx.apk";
private String appPackgeName = "com.test.install";
private Button btn_ins,btn_unins;
private String cmd_install = "pm install -r "; //静默安装命令
private String cmd_uninstall = "pm uninstall "; //静默卸载命令
String apkLocation = Environment.getExternalStorageDirectory().toString()
+ "/";
private Process process;
private DataOutputStream dos;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_ins = (Button)findViewById(R.id.btn_install);
btn_unins = (Button)findViewById(R.id.btn_uninstall);
//安装
btn_ins.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
install();
}
});
//卸载
btn_unins.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
uninstall();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void install() {
String cmdStr = cmd_install + apkLocation + appPath;
System.out.println("静默安装命令:" + cmdStr);
excute(cmdStr);
}
public void uninstall() {
String cmdStr = cmd_uninstall + appPackgeName;
System.out.println("静默卸载命令:" + cmdStr);
excute(cmdStr);
}
/**
* 检测设备是否已Root
* @return
*/
private boolean ifDeviceRoot(){
boolean result = false;
try {
if ((!new File("/system/bin/su").exists())
&& (!new File("/system/xbin/su").exists())) {
result = false;
return result;
} else {
result = true;
return result;
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
protected int excute(String cmdStr) {
if(ifDeviceRoot()){ //已root
Toast.makeText(MainActivity.this, "设备已Root", 1000).show();
try {
//得到Process对象,这里执行su命令是为了获取root权限.如果没有root权限就无法进行静默安装了.
process = Runtime.getRuntime().exec("su");
dos = new DataOutputStream(
(OutputStream) process.getOutputStream());
// 部分手机Root之后Library path 丢失,导入path可解决该问题
dos.writeBytes((String) "export LD_LIBRARY_PATH=/vendor/lib:/system/lib\n");
cmdStr = String.valueOf(cmdStr);
dos.writeBytes((String) (cmdStr + "\n"));
dos.flush();
dos.writeBytes("exit\n");
dos.flush();
//阻塞进程,等待安装完成
process.waitFor();
//值为0表示进程正常终止,当返回0 表示静默安装已结束
//若返回其他值代表失败,通常表示大于0的对应的未终止异常线程数,比如1就是有1个进程未终止
int result = process.exitValue();
return (Integer) result;
} catch (Exception e) {
e.printStackTrace();
return -1;
}finally{
try {
if (dos != null) {
dos.close();
}
process.destroy();
} catch (Exception e) {
e.printStackTrace();
}
}
}else{
//设备没有root,则调用系统的应用安装页面(请参考上篇文章)
return 0;
}
}
}
整体就是检测设备是否已root,如果已root 则进行静默安装,没root就弹出页面调用系统的安装方法.