android 實現下載、靜默安裝以及啟動

記得上一次寫簡書還是在自己剛進大學的時候,那個時候才開始接觸android開發(fā),寫出一個登陸界面都好開心。經過一年多的學習,成長為一個稍微入門的菜鳥,所以再一次打開簡書記錄一下。

目錄

1.什么是靜默安裝
2.如何實現
3.心得體會

什么是靜默安裝

在百度上瀏覽了一下,總結到了一下的解釋:

靜默安裝指的是安裝時無需任何用戶干預,直接按默認設置安裝。即在安裝過程中可以靜默安裝好預先設計集成的一些常用軟件,安裝結束以后軟件就已經可以使用。

按照我自己的話來解釋,就是以前我們最討厭的那些流氓軟件的安裝模式,及在我們用戶毫不知情的情況下,app自動安裝。
其實,這種模式并無對錯,只是看我們怎么運用。假如我們需要實現一個類似于監(jiān)聽的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     下載監(jiān)聽
     */
    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) {
                // 下載失敗監(jiān)聽回調
                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);
    }

}

通過三個監(jiān)聽,來監(jiān)聽下載的狀態(tài)。

啟動

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

心得體會

實現靜默安裝的前提是要獲得手機的root權限,其次其核心實現邏輯就是調用Android系統(tǒng)的pm install命令。

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,030評論 25 709
  • 嚴格模式 ("use strict") 作用: 消除Javascript語法的一些不合理,不嚴謹之處,減少一些怪...
    web阿森閱讀 429評論 1 0
  • smoke to make me numb smoke to make me dumb smoke to soot...
    FollowingSaints閱讀 629評論 0 2
  • 臨暮去,仲商期, 八千里云月同往。 惹塵埃,謝公屐, 鮮衣怒馬踏燕飛。 邊關笛,聽胡琴, 夜宿寒舍常對飲。 結廬下...
    知秋尋隱隱閱讀 401評論 0 0
  • 哈哈,看到這個題目,你肯定會說,瘋了吧? 都說女人善變,是現實讓我有了改觀。 前幾天,到徐水二中參加濕地年會,看到...
    筱華de小天地閱讀 594評論 1 8

友情鏈接更多精彩內容