Android 静默安装

Android 静默安装

具有Root权限的安装

设备可以获得root权限
AndroidManifest 权限
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
设置sharedUserId
 <application
 android:sharedUserId="android.uid.system"
 ...
 >
执行adb 安装命令
//安装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

此种安装是收不到安装广播的

经过测试,这种不需要系统签名也可以

无Root权限安装(需要系统签名)

AndroidManifest 权限
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
设置sharedUserId
 <application
 android:sharedUserId="android.uid.system"
 ...
 >
系统签名

签名相关文件

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)

静态声明广播:

    <receiver android:name=".receiver.StartLaunchReceiver">
            <intent-filter>
                <action android:name="install_and_start"/>
            </intent-filter>
    </receiver>

广播类:

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的方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值