2012-05-07 74 views
1

我已將Code Aurora的FM收音機代碼與我的Android Gingerbread代碼庫合併。Android:無法在JNI實施中打開設備文件

FM應用程序框架試圖使用JNI訪問fm無線電設備(/ dev/radio),該名稱是在名爲android_hardware_fm.cpp的文件中實現的。該文件中有一個函數,它嘗試在讀/寫模式下使用open()獲取設備節點的文件描述符。但是,該調用失敗,錯誤代碼爲-13:權限被拒絕。

我也做了一個小的C可執行文件,它試圖打開/ dev/radio文件(在RDWR模式下),打印它的fd並關閉它。它從目標系統中的/ system/bin運行並顯示有效的fd。

順便說一下,JNI實現是android核心庫的一部分。它位於frameworks/base/core/jni中,並被編譯爲libandroid_runtime.so的一部分。

任何想法/解決方案?提前致謝。

+0

4年後我有一個非常類似的問題:http://stackoverflow.com/questions/37486349 我甚至運行我的可執行文件作爲應用程序相同的UID和它的作品,當然做了一切下面的答案。你有沒有找到解決方案? – jkoreska

+0

@jkoreska我想我使用了一種解決方法。請在下面的答案中看到我的評論。 – trans1st0r

回答

1

顯然你沒有權限從用戶空間打開設備。在第二種情況下,當您從終端運行可執行文件時,您可能擁有權限,可能是因爲您在運行可執行文件之前完成了su

對於您的問題,可以做兩件事。

1)將節點的權限從最終變更。

涉及的步驟:

  • 打開終端(adb shell

  • 不要su(爲了做到這一點您的設備必須植根)

  • 在做chmod 777 /dev/radio終端

完成此操作後,您的無線電節點具有適當的權限供用戶讀取和寫入。所以你現在可以做open()調用,它會工作。

2)以編程方式,您可以通過調用以下函數(changePerm())來實現此目的(假設您的設備已根並且su在設備上運行)。這是我寫的一個小函數,它會改變設備節點的權限,或者更改任何沒有用戶訪問權限的系統文件。一旦你有權限,你可以從用戶空間打開它。在此之後,open()調用將正常工作。

void changePerm() 
{ 
    Process chperm; 
    try { 
     chperm=Runtime.getRuntime().exec("su"); 


    DataOutputStream os = 
      new DataOutputStream(chperm.getOutputStream()); 
     os.writeBytes("chmod 777 /dev/radio\n"); 
     os.flush(); 

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

      chperm.waitFor(); 

} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (InterruptedException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
} 

我已經測試過其他節點。所以它也適用於廣播。如果喲遇到任何困難,請告訴我。謝謝

+0

使用adb shell的用戶有我的默認權限。你在建議之後所做的是在init.rc中放入命令「chmod 777/dev/radio0」...但這只是一個臨時性的修復。 – trans1st0r

+0

爲使init.rc中的更改生效,您需要重新編譯android並使其閃爍 –

+0

哦,在這種情況下,如果您默認具有root權限,則su可能不會出現在您的設備上。那麼只有第一種方法(沒有su適用) –