非ROOT实现静默安装的一些思考与体会,AIDL获取IPackageManager,反射ServiceManager,系统签名


一.install的思考

  • 1.纯手工,点击安装包,安装应用
  • 2.adb安装
//安装
adb install xxx.apk
//卸载
adb uninstall xxx.apk
pm install -r
98        if ("install".equals(op)) {
99            runInstall();
100            return;
101        }
102
103        if ("uninstall".equals(op)) {
104            runUninstall();
105            return;
106        }

743    private void runInstall() {
744        int installFlags = 0;
745        String installerPackageName = null;
746
747        String opt;
748        while ((opt=nextOption()) != null) {
749            if (opt.equals("-l")) {
750                installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
751            } else if (opt.equals("-r")) {
752                installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
753            } else if (opt.equals("-i")) {
754                installerPackageName = nextOptionData();
755                if (installerPackageName == null) {
756                    System.err.println("Error: no value specified for -i");
757                    showUsage();
758                    return;
759                }
760            } else if (opt.equals("-t")) {
761                installFlags |= PackageManager.INSTALL_ALLOW_TEST;
762            } else if (opt.equals("-s")) {
763                // Override if -s option is specified.
764                installFlags |= PackageManager.INSTALL_EXTERNAL;
765            } else if (opt.equals("-f")) {
766                // Override if -s option is specified.
767                installFlags |= PackageManager.INSTALL_INTERNAL;
768            } else {
769                System.err.println("Error: Unknown option: " + opt);
770                showUsage();
771                return;
772            }
773        }
774
775        final Uri apkURI;
776        final Uri verificationURI;
777
778        // Populate apkURI, must be present
779        final String apkFilePath = nextArg();
780        System.err.println("\tpkg: " + apkFilePath);
781        if (apkFilePath != null) {
782            apkURI = Uri.fromFile(new File(apkFilePath));
783        } else {
784            System.err.println("Error: no package specified");
785            showUsage();
786            return;
787        }
788
789        // Populate verificationURI, optionally present
790        final String verificationFilePath = nextArg();
791        if (verificationFilePath != null) {
792            System.err.println("\tver: " + verificationFilePath);
793            verificationURI = Uri.fromFile(new File(verificationFilePath));
794        } else {
795            verificationURI = null;
796        }
797
798        PackageInstallObserver obs = new PackageInstallObserver();
799        try {
800            mPm.installPackageWithVerification(apkURI, obs, installFlags, installerPackageName,
801                    verificationURI, null);
802
803            synchronized (obs) {
804                while (!obs.finished) {
805                    try {
806                        obs.wait();
807                    } catch (InterruptedException e) {
808                    }
809                }
810                if (obs.result == PackageManager.INSTALL_SUCCEEDED) {
811                    System.out.println("Success");
812                } else {
813                    System.err.println("Failure ["
814                            + installFailureToString(obs.result)
815                            + "]");
816                }
817            }
818        } catch (RemoteException e) {
819            System.err.println(e.toString());
820            System.err.println(PM_NOT_RUNNING_ERR);
821        }
822    }
mPm.installPackageWithVerification(apkURI, obs, installFlags, installerPackageName,verificationURI, null);
 mPm.installPackage(Uri.fromFile(new File(apkFilePath)), obs, installFlags,installerPackageName);
IPackageManager mPm;
 mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));

二.IPackageManager.aidl

非ROOT实现静默安装的一些思考与体会,AIDL获取IPackageManager,反射ServiceManager,系统签名-LMLPHP

非ROOT实现静默安装的一些思考与体会,AIDL获取IPackageManager,反射ServiceManager,系统签名-LMLPHP

非ROOT实现静默安装的一些思考与体会,AIDL获取IPackageManager,反射ServiceManager,系统签名-LMLPHP

非ROOT实现静默安装的一些思考与体会,AIDL获取IPackageManager,反射ServiceManager,系统签名-LMLPHP

三.静默安装的实现

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="10dp">

    <EditText
        android:id="@+id/etPackageNmae"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入应用名"/>

    <Button
        android:id="@+id/btnInstall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="静默安装"/>

</LinearLayout>
 mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));

非ROOT实现静默安装的一些思考与体会,AIDL获取IPackageManager,反射ServiceManager,系统签名-LMLPHP

    //反射获取ServiceManager
        try {
            //指定反射类
            Class<?> forName = Class.forName("android.os.ServiceManager");
            //获取方法,参数是String类型
            Method method = forName.getMethod("getService", String.class);
            //传入参数
            IBinder iBinder = (IBinder) method.invoke(null, "package");
            //初始化AIDL
            mPm = IPackageManager.Stub.asInterface(iBinder);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
     /**
     * 安装apk
     *
     * @param apkPath 路径
     */
    private void runInstall(String apkPath) {
        /**
         *  install方法
         *  1.uri:安装文件路径
         *  2.observer:观察者,安装成功还是失败
         *  3.flags:标记状态
         *  4.installer: 整个路径
         */
        try {
            mPm.installPackage(Uri.fromFile(new File(apkPath)),
                    new PackInstallObserver(), INSTALL_REPLACE_EXISTING,
                    new File(apkPath).getPath());
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>

四.android.uid.system

非ROOT实现静默安装的一些思考与体会,AIDL获取IPackageManager,反射ServiceManager,系统签名-LMLPHP

  • SignApk.java

非ROOT实现静默安装的一些思考与体会,AIDL获取IPackageManager,反射ServiceManager,系统签名-LMLPHP

非ROOT实现静默安装的一些思考与体会,AIDL获取IPackageManager,反射ServiceManager,系统签名-LMLPHP

package com.liuguilin.silentinstall;

import android.content.pm.IPackageInstallObserver;
import android.content.pm.IPackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 静默安装 --by 刘桂林
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    //输入框
    private EditText etPackageNmae;
    //执行按钮
    private Button btnInstall;

    //安装路径
    private String path = Environment.getExternalStorageDirectory().getAbsolutePath();

    //安装类
    private IPackageManager mPm;

    //install flags 状态,详见PackageManager
    private static final int INSTALL_REPLACE_EXISTING = 0X00000002;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
    }

    /**
     * 初始化View
     */
    private void initView() {

        //反射获取ServiceManager
        try {
            Class<?> forName = Class.forName("android.os.ServiceManager");
            Method method = forName.getMethod("getService", String.class);
            IBinder iBinder = (IBinder) method.invoke(null, "package");
            //初始化AIDL
            mPm = IPackageManager.Stub.asInterface(iBinder);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        //初始化
        etPackageNmae = (EditText) findViewById(R.id.etPackageNmae);
        btnInstall = (Button) findViewById(R.id.btnInstall);
        btnInstall.setOnClickListener(this);
    }

    /**
     * 点击事件
     *
     * @param view
     */
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btnInstall:
                String apkPath = path + "/" + etPackageNmae.getText().toString().trim();
                runInstall(apkPath);
                break;
        }
    }

    /**
     * 安装apk
     *
     * @param apkPath 路径
     */
    private void runInstall(String apkPath) {
        /**
         *  install方法
         *  1.uri:安装文件路径
         *  2.observer:观察者,安装成功还是失败
         *  3.flags:标记状态
         *  4.installer: 整个路径
         */
        try {
            mPm.installPackage(Uri.fromFile(new File(apkPath)),
                    new PackInstallObserver(), INSTALL_REPLACE_EXISTING,
                    new File(apkPath).getPath());
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    /**
     * 观察者
     */
    class PackInstallObserver extends IPackageInstallObserver.Stub {

        @Override
        public void packageInstalled(String packageName, int returnCode) throws RemoteException {
            //根据returnCode判断是否成功失败
        }
    }
}

SilentInstall下载:http://download.csdn.net/detail/qq_26787115/9615335

有兴趣的加群:555974449

04-17 02:48
查看更多