首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 讀寫 /sys/ 系統文件需要 Root 權限的正確方法

     編輯:程式設計綜合問答

在 Android 中讀寫 /sys/ 目錄下的系統文件(如振動器振幅控制)需要 Root 權限,不能使用普通文件流操作,需通過 su Shell 命令執行。

問題代碼分析

// 錯誤嘗試:普通文件流無權限訪問 /sys/
FileOutputStream fos = new FileOutputStream("/sys/devices/virtual/timed_output/vibrator/amp");
fos.write(value.getBytes()); // 權限被拒絕

// 錯誤的 su 寫法
os.writeBytes(value + " > " + filename + "\n"); // 缺少 echo 命令

正確的 su 寫入方法

public static void writeSysFile(String filename, String value) {
    Process process = null;
    DataOutputStream os = null;
    try {
        // 1. 獲取 Root Shell
        process = Runtime.getRuntime().exec("su");
        os = new DataOutputStream(process.getOutputStream());
        
        // 2. 正確命令:echo '值' > 文件路徑
        // 注意:單引號包裹值,防止特殊字符;重定向符 > 需在 Shell 中執行
        String command = "echo '" + value + "' > " + filename + "\n";
        os.writeBytes(command);
        
        // 3. 退出 Shell
        os.writeBytes("exit\n");
        os.flush();
        
        // 4. 等待執行完成並檢查結果
        int exitCode = process.waitFor();
        if (exitCode != 0) {
            // 讀取錯誤流排查
            BufferedReader errorReader = new BufferedReader(
                new InputStreamReader(process.getErrorStream()));
            String line;
            StringBuilder error = new StringBuilder();
            while ((line = errorReader.readLine()) != null) {
                error.append(line).append("\n");
            }
            Log.e("SysWrite", "寫入失敗 exitCode=" + exitCode + ", error=" + error);
        }
    } catch (IOException | InterruptedException e) {
        Log.e("SysWrite", "異常", e);
    } finally {
        try { if (os != null) os.close(); } catch (IOException ignored) {}
        if (process != null) process.destroy();
    }
}

關鍵點解析

  1. echo '值' > 文件:Shell 重定向寫入標準語法,單引號保護值不被 Shell 解析
  2. su 進程:Runtime.exec("su") 啟動 Root Shell,後續命令在 Root 權限下執行
  3. exit\n:必須發送退出命令結束 Shell,否則進程掛起
  4. waitFor():等待命令執行完成,獲取退出碼判斷成敗

讀取系統文件

public static String readSysFile(String filename) {
    Process process = null;
    BufferedReader reader = null;
    try {
        process = Runtime.getRuntime().exec("su");
        DataOutputStream os = new DataOutputStream(process.getOutputStream());
        os.writeBytes("cat " + filename + "\n");
        os.writeBytes("exit\n");
        os.flush();
        
        reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        return reader.readLine(); // 讀取輸出
    } catch (IOException e) {
        Log.e("SysRead", "讀取失敗", e);
        return null;
    } finally {
        try { if (reader != null) reader.close(); } catch (IOException ignored) {}
        if (process != null) process.destroy();
    }
}

必要條件與限制

  • 設備必須已 Root (Magisk、SuperSU 等)
  • App 需獲得 Root 授權彈窗確認
  • Android 7.0+ 增加了 SELinux 限制,部分 /sys/ 節點即使 Root 也不可寫
  • 系統文件修改可能影響穩定性,需極其謹慎

現代替代:系統 API

振動控制等功能優先使用官方 API:

Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
} else {
    vibrator.vibrate(500); // 舊版 API
}

避免直接操作 /sys/ 文件,兼容性差、風險高、易失效。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved