//安装APK命令
public static final String SHELL_INSTALL = "pm install -r ";
//启动APK命令 am start -n 包名/.Activity类名,
//假如SplashActivity所在包路径为在com.xx.xx.ui下则为
public static final String SHELL_START = "am start -n com.xx.xx/.ui.SplashActivity";
//path为安装包所在绝对路径 安装并启动
String[] commands = new String[]{SHELL_INSTALL+path,SHELL_START};
ShellUtils.execCommand(commands,true);
ShellUtils是一个执行adb shell命令的工具类. 链接:Android ShellUtils
此种安装是收不到安装广播的
经过测试,这种不需要系统签名也可以
签名相关文件
platform.x509.pem、platform.pk8 位于Android系统源码/build/target/product/security/目录
SignApk.jar需要编译产出,代码位于Android系统源码/build/tools/signapk/目录下,编译后位于/out/host/linux-x86/framework目录下
把3个文件和未签名APKcopy到同一文件夹,执行命令,输出系统签名后的 out.apk
java -jar signapk.jar platform.x509.pem platform.pk8 unsigned.apk out.apk
参考:Android 系统签名实现的三种方式
使用ProcessBuild 执行pm 安装命令
/**
* 静默安装
*
* @param apkPath
* @return
*/
public static boolean installClientApp(String packageName,String apkPath) {
Process process = null;
BufferedReader successResult = null;
BufferedReader errorResult = null;
StringBuilder successMsg = new StringBuilder();
StringBuilder errorMsg = new StringBuilder();
try {
//7.0以前版本使用
// process = new ProcessBuilder("pm", "install", "-r", //apkPath).start();
//7.0以后版本使用 BuildConfig.APPLICATION_ID
process = new ProcessBuilder("pm", "install", "-i", packageName, "-r", apkPath).start();
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String s;
while ((s = successResult.readLine()) != null) {
successMsg.append(s);
}
while ((s = errorResult.readLine()) != null) {
errorMsg.append(s);
}
} catch (Exception e) {
} finally {
try {
if (successResult != null) {
successResult.close();
}
if (errorResult != null) {
errorResult.close();
}
} catch (Exception e) {
}
if (process != null) {
process.destroy();
}
}
Log.e("result", "" + errorMsg.toString() + ",successMsg=" + successMsg);
// Toast.makeText(context," "+successMsg , Toast.LENGTH_LONG).show();
//如果含有“success”单词则认为安装成功
return successMsg.toString().equalsIgnoreCase("success");
}
如果想安装后启动,可以设定广播
//主要就是通过,安装程序之前,启动一个定时任务,任务发送一个广播,广播收到之后,启动程序
Intent ite = new Intent(this, StartLaunchReceiver.class);
ite.setAction("install_and_start");
PendingIntent SENDER = PendingIntent.getBroadcast(this, 0, ite,
PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager ALARM = (AlarmManager) getSystemService(ALARM_SERVICE);
ALARM.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 15*1000,SENDER);
//install
installClientApp(Utils.getContext().getPackageName(),path)
静态声明广播:
广播类:
public class StartLaunchReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase("install_and_start")) {
Intent intentStart = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
}
}
}
还有2种 反射和AccessibilityService的方法