【Android 應用】執行腳本文件---以及多行命令執行,su權限執行

需求是在應用中執行版本腳本,且只執行一次。需要用到su權限、資源文件獲取等等知識點。

基本思路

  1. 對比版本信息
  2. 將資源文件中的版本腳本寫入到應用目錄中
  3. 給腳本執行權限
  4. 執行腳本

對比版本信息

主要思路是:執行成功完成後將版本寫入到數據庫中去。下次執行時再對比版本信息是否一致。

資源文件寫入到應用目錄

獲取資源文件我採用的是:mContext.getAssets().open("versionShell.sh");

需要注意的是:assets需要放到main目錄下,否則會報找不到文件的錯誤。

    /**
     * 將資源文件中的sh腳本寫到應用目錄
     */
    private void writeFileToData() {
        OutputStream output = null;
        InputStream input = null;
        try {
            File shellPath = new File(mContext.getFilesDir(), SHELL_FILE_NAME);
            output = new FileOutputStream(shellPath);
            input = mContext.getAssets().open(SHELL_FILE_NAME);
            int count;
            int off = 0;
            byte data[] = new byte[1024];
            while ((count = input.read(data)) != -1) {
                output.write(data, off, count);
                off += count;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (output != null) {
                    output.close();
                    output = null;
                }
                if (input != null) {
                    input.close();
                    input = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

執行腳本

1、普通權限執行命令

    /**
     * 普通權限執行
     * @param cmd
     */
    private void exec(String cmd) {
        Runtime mRuntime = Runtime.getRuntime();
        BufferedReader mReader = null;
        try {
            //Process中封裝了返回的結果和執行錯誤的結果
            Process mProcess = mRuntime.exec(cmd);
            Logger.d(TAG, "exec cmd : " + cmd);
            mReader = new BufferedReader(new InputStreamReader(mProcess.getInputStream()));
            StringBuffer mRespBuff = new StringBuffer();
            char[] buff = new char[1024];
            int ch = 0;
            while ((ch = mReader.read(buff)) != -1) {
                mRespBuff.append(buff, 0, ch);
            }
            Logger.d(TAG, mRespBuff.toString());
        } catch (IOException e) {
            Logger.e(TAG, "exec error: "+ e.toString());
        }finally {
            try{
                if(mReader != null){
                    mReader.close();
                    mReader = null;
                }
            }catch (IOException e){
                Logger.e(TAG, "exec error: "+ e.toString());
            }
        }
    }

2、su權限執行命令

包含了多條命令執行。

    /**
     * su權限執行命令
     * @param fileName
     * @return
     */
    public boolean runShellFile(String fileName) {
        boolean result = false;
        DataOutputStream dataOutputStream = null;
        BufferedReader mReader = null;
        try {
            Process process = Runtime.getRuntime().exec("su");
            dataOutputStream = new DataOutputStream(process.getOutputStream());

            String cmd = "cd " + mContext.getFilesDir()+"\n";
            dataOutputStream.write(cmd.getBytes(Charset.forName("utf-8")));
            dataOutputStream.flush();

            cmd = "chmod +x " + fileName+"\n";
            dataOutputStream.writeBytes(cmd);
            dataOutputStream.flush();

            //清理文本編碼不對導致有後綴的問題
            cmd = "dos2unix " + fileName+"\n";
            dataOutputStream.writeBytes(cmd);
            dataOutputStream.flush();

            cmd = "./" + fileName +"\n";
            dataOutputStream.writeBytes(cmd);
            dataOutputStream.flush();

            dataOutputStream.writeBytes("exit\n");
            dataOutputStream.flush();

            //獲取結果
            process.waitFor();
            mReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String msg = "";
            String line;

            while ((line = mReader.readLine()) != null) {
                msg += line;
            }
            Logger.d(TAG, " read msg: " + msg);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (dataOutputStream != null) {
                    dataOutputStream.close();
                }

                if (mReader != null) {
                    mReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }

注意點1:沒有返回值的時候會卡頓在readLine讀取返回值的地方。

注意點2:su權限執行後,需要執行exit退出後才能獲取到返回值。

源碼

飛機票:【源碼】android應用執行腳本文件

結束語

以上就是本次分享的android應用開發中,如何執行腳本文件的解決方案。最後慣例給大家推介一下我們的技術工作號,歡迎大家來交流技術問題,謝謝!

在這裏插入圖片描述

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章