美文网首页Android 基础知识
android 实现下载、静默安装以及启动

android 实现下载、静默安装以及启动

作者: 鱼我所欲 | 来源:发表于2018-08-02 14:30 被阅读80次

    记得上一次写简书还是在自己刚进大学的时候,那个时候才开始接触android开发,写出一个登陆界面都好开心。经过一年多的学习,成长为一个稍微入门的菜鸟,所以再一次打开简书记录一下。

    目录

    1.什么是静默安装
    2.如何实现
    3.心得体会

    什么是静默安装

    在百度上浏览了一下,总结到了一下的解释:

    静默安装指的是安装时无需任何用户干预,直接按默认设置安装。即在安装过程中可以静默安装好预先设计集成的一些常用软件,安装结束以后软件就已经可以使用。

    按照我自己的话来解释,就是以前我们最讨厌的那些流氓软件的安装模式,及在我们用户毫不知情的情况下,app自动安装。
    其实,这种模式并无对错,只是看我们怎么运用。假如我们需要实现一个类似于监听的apk时,他需要在安装主apk之后,自动安装,这个时候就可以不需要用户确定而自动安装,这个时候就需要用到静默安装。

    代码实现

    public class Controller {
    
        public static boolean install(String apkPath,Context context){
            // 判断是否有root权限
            if(hasRootPerssion()){
                // 有root权限,利用静默安装实现
                return clientInstall(apkPath);
            }else{
                // 没有root权限,利用意图进行安装
                File file = new File(apkPath);
                if(!file.exists())
                    return false;
                Intent intent = new Intent();
                intent.setAction("android.intent.action.VIEW");
                intent.addCategory("android.intent.category.DEFAULT");
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive");
                context.startActivity(intent);
                return true;
            }
        }
    
        /**
         * 判断手机是否有root权限
         */
        public static boolean hasRootPerssion(){
            PrintWriter PrintWriter = null;
            Process process = null;
            try {
                process = Runtime.getRuntime().exec("su");
                PrintWriter = new PrintWriter(process.getOutputStream());
                PrintWriter.flush();
                PrintWriter.close();
                int value = process.waitFor();
                return returnResult(value);
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                if(process!=null){
                    process.destroy();
                }
            }
            return false;
        }
    
        /**
         * 静默安装
         */
        public static boolean clientInstall(String apkPath){
            PrintWriter PrintWriter = null;
            Process process = null;
            try {
                process = Runtime.getRuntime().exec("su");
                PrintWriter = new PrintWriter(process.getOutputStream());
                PrintWriter.println("chmod 777 "+apkPath);
                PrintWriter.println("export LD_LIBRARY_PATH=/vendor/lib:/system/lib");
                PrintWriter.println("pm install -r "+apkPath);
    //          PrintWriter.println("exit");
                PrintWriter.flush();
                PrintWriter.close();
                int value = process.waitFor();
                return returnResult(value);
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                if(process!=null){
                    process.destroy();
                }
            }
            return false;
        }
        /**
         * 将文件复制到system/app 目录
         * @param apkPath 特别注意格式:该路径不能是:/storage/emulated/0/app/QDemoTest4.apk 需要是:/sdcard/app/QDemoTest4.apk
         * @return
         */
        public static boolean copy2SystemApp(String apkPath){
            PrintWriter PrintWriter = null;
            Process process = null;
            String appName = "chetou.apk",cmd;
    
            try {
                process = Runtime.getRuntime().exec("su");
                PrintWriter = new PrintWriter(process.getOutputStream());
                cmd = "mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system";
                Log.e("copy2SystemApp", cmd);
                PrintWriter.println(cmd);
    
                cmd = "cat "+apkPath+" > /system/app/"+appName;
                Log.e("copy2SystemApp", cmd);
                PrintWriter.println(cmd);
    
                cmd = "chmod 777 /system/app/"+appName +" -R";
                Log.e("copy2SystemApp", cmd);
                PrintWriter.println(cmd);
    
                cmd = "mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system";
                Log.e("copy2SystemApp", cmd);
                PrintWriter.println(cmd);
                PrintWriter.println("reboot");  //重启
                PrintWriter.println("exit");
                PrintWriter.flush();
                PrintWriter.close();
                int value = process.waitFor();
                return returnResult(value);
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                if(process!=null){
                    process.destroy();
                }
            }
            return false;
        }
        private static boolean returnResult(int value){
            // 代表成功
            if (value == 0) {
                return true;
            } else if (value == 1) { // 失败
                return false;
            } else { // 未知情况
                return false;
            }
        }
    }
    

    这是一个封装好的类,直接在需要的地方调用,传入相应的参数。

    下载功能

    这个功能我是在网上找的别人封装好的一个下载工具库,他是基于okhttp来实现的下载功能。逻辑很清楚,自己上代码

    public class DownloadUtil {
        private static DownloadUtil downloadUtil;
        private final OkHttpClient okHttpClient;
    
        public static DownloadUtil get() {
            if (downloadUtil == null) {
                downloadUtil = new DownloadUtil();
            }
            return downloadUtil;
        }
    
        private DownloadUtil() {
            okHttpClient = new OkHttpClient();
        }
    
        /**
         * @param url          下载连接
         * @param destFileDir  下载的文件储存目录
         * @param destFileName 下载文件名称
         * @param listener     下载监听
         */
        public void download(final String url, final String destFileDir, final String destFileName, final OnDownloadListener listener) {
            Request request = new Request.Builder().url(url).build();
            okHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    // 下载失败监听回调
                    listener.onDownloadFailed(e);
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    InputStream is = null;
                    byte[] buf = new byte[2048];
                    int len = 0;
                    FileOutputStream fos = null;
                    // 储存下载文件的目录
                    File dir = new File(destFileDir);
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
                    File file = new File(dir, destFileName);
                    try {
                        is = response.body().byteStream();
                        long total = response.body().contentLength();
                        fos = new FileOutputStream(file);
                        long sum = 0;
                        while ((len = is.read(buf)) != -1) {
                            fos.write(buf, 0, len);
                            sum += len;
                            int progress = (int) (sum * 1.0f / total * 100);
                            // 下载中更新进度条
                            listener.onDownloading(progress);
                        }
                        fos.flush();
                        // 下载完成
                        listener.onDownloadSuccess(file);
                    } catch (Exception e) {
                        listener.onDownloadFailed(e);
                    } finally {
                        try {
                            if (is != null)
                                is.close();
                        } catch (IOException e) {
                        }
                        try {
                            if (fos != null)
                                fos.close();
                        } catch (IOException e) {
                        }
                    }
                }
            });
        }
    
        public interface OnDownloadListener {
            /**
             * @param file 下载成功后的文件
             */
            void onDownloadSuccess(File file);
    
            /**
             * @param progress 下载进度
             */
            void onDownloading(int progress);
    
            /**
             * @param e 下载异常信息
             */
            void onDownloadFailed(Exception e);
        }
    
    }
    

    通过三个监听,来监听下载的状态。

    启动

    Intent intent1=context.getPackageManager().getLaunchIntentForPackage("com.xxx.xx.xxxxxxx");
                context.startActivity(intent1);
    

    心得体会

    实现静默安装的前提是要获得手机的root权限,其次其核心实现逻辑就是调用Android系统的pm install命令。

    相关文章

      网友评论

        本文标题:android 实现下载、静默安装以及启动

        本文链接:https://www.haomeiwen.com/subject/ucujvftx.html