Android中软件的静默安装,安装完成后再自动打开新安装软件(需Root)

来源:互联网 发布:python 定时任务 编辑:程序博客网 时间:2024/06/05 20:34

编写不易,如有转载,请声明出处: 梦回河口:http://blog.csdn.net/zxc514257857/article/details/77488832

前言

  需要获取Root权限,安装过程完全静默实现,注册安装、卸载、升级的广播,安装完成后自动打开新安装的软件

全部代码

// AndroidManifest中权限配置<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/><uses-permission android:name="android.permission.RESTART_PACKAGES" /><uses-permission android:name="android.permission.INSTALL_PACKAGES"                 tools:ignore="ProtectedPermissions" />----------------------------------------------------------------------------------------// AndroidManifest中静态注册广播<receiver android:name=".SilenceInstallReceiver">   <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>----------------------------------------------------------------------------------------// MainActivityimport android.content.Context;import android.content.Intent;import android.content.pm.PackageInfo;import android.net.Uri;import android.os.Environment;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import java.io.DataOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;public class MainActivity extends AppCompatActivity {    private static final String TAG = "MainActivity";    private String tempPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/temp.apk";    private PackageInfo mPackageInfo;    private Context mContext = MainActivity.this;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        if(RootUtils.isRooted()) {            // 从assets目录中获取apk并安装            installFromAssets();        }    }    /**     * 从assets目录中获取并安装     */    public void installFromAssets(){        try {            // 根据包名判断是否安装 如果未找到包名说明包名输入错误或未安装            // 想要安装的apk的名字是testapk,其包名为com.testapk.apk            mPackageInfo = getPackageManager().getPackageInfo("com.test.testapk", 0);        } catch (Exception e) {            mPackageInfo = null;            e.printStackTrace();        }        if (mPackageInfo == null) {            // 启用安装新线程            new Thread(new Runnable() {                @Override                public void run() {                    Log.i(TAG , "未安装进行安装");                    // 静默安装(安装其他软件或自己的升级版 无界面显示) 并启动                    slientInstall();                }            }).start();        } else {            Log.i(TAG , "已经安装");        }    }    /**     * 静默安装 并启动     *     * @return     */    public boolean slientInstall() {        // 进行资源的转移 将assets下的文件转移到可读写文件目录下        createFile();        File file = new File(tempPath);        boolean result = false;        Process process = null;        OutputStream out = null;        Log.i(TAG , "file.getPath():" + file.getPath());        if (file.exists()) {            System.out.println(file.getPath() + "==");            try {                process = Runtime.getRuntime().exec("su");                out = process.getOutputStream();                DataOutputStream dataOutputStream = new DataOutputStream(out);                // 获取文件所有权限                dataOutputStream.writeBytes("chmod 777 " + file.getPath()                        + "\n");                // 进行静默安装命令                dataOutputStream                        .writeBytes("LD_LIBRARY_PATH=/vendor/lib:/system/lib pm install -r "                                + file.getPath());                dataOutputStream.flush();                // 关闭流操作                dataOutputStream.close();                out.close();                int value = process.waitFor();                // 代表成功                if (value == 0) {                    Log.i(TAG , "安装成功!");                    result = true;                    // 失败                } else if (value == 1) {                    Log.i(TAG , "安装失败!");                    result = false;                    // 未知情况                } else {                    Log.i(TAG , "未知情况!");                    result = false;                }            } catch (IOException e) {                e.printStackTrace();            } catch (InterruptedException e) {                e.printStackTrace();            }            if (!result) {                Log.i(TAG , "root权限获取失败,将进行普通安装");                normalInstall(mContext);                result = true;            }        }        return result;    }    /**     * 进行资源的转移 将assets下的文件转移到可读写文件目录下     */    public void createFile() {        InputStream is = null;        FileOutputStream fos = null;        try {            // 从assets文件夹中获取testapk.apk文件            is = getAssets().open("testapk.apk");            File file = new File(tempPath);            file.createNewFile();            fos = new FileOutputStream(file);            byte[] temp = new byte[1024];            int i = 0;            while ((i = is.read(temp)) > 0) {                fos.write(temp, 0, i);            }        } catch (IOException e) {            e.printStackTrace();        } finally {            if (is != null) {                try {                    is.close();                } catch (IOException e) {                    e.printStackTrace();                }            }            if (fos != null) {                try {                    fos.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }    /**     * 传统安装     *     * @param context     */    public void normalInstall(Context context) {        // 进行资源的转移 将assets下的文件转移到可读写文件目录下        createFile();        File file = new File(tempPath);        Intent intent = new Intent();        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        intent.setAction(android.content.Intent.ACTION_VIEW);        intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");        context.startActivity(intent);        startApp(mContext);    }    /**     * 安装后自启动apk     *     * @param context     */    private static void startApp(Context context) {        execRootShellCmd("am start -S  " + context.getPackageName() + "/"                + MainActivity.class.getCanonicalName() + " \n");    }    /**     * 执行shell命令     *     * @param cmds     * @return     */    private static boolean execRootShellCmd(String... cmds) {        if (cmds == null || cmds.length == 0) {            return false;        }        DataOutputStream dos = null;        InputStream dis = null;        Process p = null;        try {            p = Runtime.getRuntime().exec("su");// 经过Root处理的android系统即有su命令            dos = new DataOutputStream(p.getOutputStream());            for (int i = 0; i < cmds.length; i++) {                dos.writeBytes(cmds[i] + " \n");            }            dos.writeBytes("exit \n");            int code = p.waitFor();            return code == 0;        } catch (Exception e) {            e.printStackTrace();        } finally {            try {                if (dos != null) {                    dos.close();                }            } catch (IOException e) {                e.printStackTrace();            }            try {                if (dis != null) {                    dis.close();                }            } catch (Exception e2) {                e2.printStackTrace();            }            try {                if (p != null) {                    p.destroy();                    p = null;                }            } catch (Exception e3) {                e3.printStackTrace();            }        }        return false;    }}----------------------------------------------------------------------------------------// SilenceInstallReceiver import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;public class SilenceInstallReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        if (intent.getAction().equals("android.intent.action.PACKAGE_REPLACED")){            String packageName = intent.getDataString();            System.out.println("升级了:" + packageName + "包名的程序");//            startApp(context);        }        // 接收安装广播        if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {            String packageName = intent.getDataString();            System.out.println("安装了:" +packageName + "包名的程序");            // 监测到升级后执行app的启动 只能启动自身 一般用于软件更新            startApp(context);        }        //接收卸载广播        if (intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) {            String packageName = intent.getDataString();            System.out.println("卸载了:"  + packageName + "包名的程序");        }    }    /**     * 监测到升级后执行app的启动      */    public void startApp(Context context){        // 根据包名打开安装的apk        Intent resolveIntent = context.getPackageManager().getLaunchIntentForPackage("com.test.testapk");        context.startActivity(resolveIntent);        // 打开自身 一般用于软件升级//        Intent intent = new Intent(context, MainActivity.class);//        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//        context.startActivity(intent);    }}----------------------------------------------------------------------------------------// RootUtilimport android.util.Log;import java.io.BufferedReader;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;public class RootUtils {    public static final String TAG = "RootUtils";    @Deprecated    public static boolean isRooted() {        Process process = null;        try {            process = Runtime.getRuntime().exec("su");            OutputStream outputStream = process.getOutputStream();            InputStream inputStream = process.getInputStream();            outputStream.write("id\n".getBytes());            outputStream.flush();            outputStream.write("exit\n".getBytes());            outputStream.flush();            process.waitFor();            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));            String s = bufferedReader.readLine();            if (s.contains("uid=0")) return true;        } catch (IOException e) {            Log.e(TAG, "没有root权限");        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            if (process != null)                process.destroy();        }        return false;    }    public static boolean checkRooted() {        boolean result = false;        try {            result = new File("/system/bin/su").exists() || new File("/system/xbin/su").exists();        } catch (Exception e) {            e.printStackTrace();        }        return result;    }}

Demo下载请移步:http://download.csdn.net/download/zxc514257857/9945636


因本人才疏学浅,如博客或Demo中有错误的地方请大家随意指出,与大家一起讨论,共同进步,谢谢!

阅读全文
0 0