天天看點

Android 應用層如何操作裝置節點

前言:

有時應用需要通路裝置節點,來進行節點進行操作,來達到控制裝置的目的,一種是裝置是在固定在主機闆上的,一種是需要usb進行插拔的裝置。

兩種方式添加的位置是有差别的。

第一種裝置方式如下:

  • 在init.rc檔案中添加該裝置的權限
on post-fs-data
    setprop debug.delaytime.min 10
    setprop debug.delaytime.mid 100
    setprop debug.delaytime.max 1000
    setprop debug.android_watchdog.disable 1
    
    chmod 666 /sys/devices/virtual/light_state      

第二種裝置方式如下:

src/system/core/rootdir/ueventd.rc      

ueventd.rc檔案還是有一定的修改規則

/dev/tty*                 0777   root       system      

ueventd.rc檔案中的内容大緻為這樣,第一清單示要修改的裝置節點;第二列為修改後的權限;第三列為該節點的使用者,注意,不要嘗試去修改該節點的使用者,很有可能修改導緻修改失敗。

整編譯軟體在out目錄下面搜尋該檔案:find -name init.rc,如果該檔案中存在添加加節點的代碼,那就說明添加成功了.

  • 應用層向該裝置節點寫入值
public static final String LIGHT_POWER_PATH = "/sys/devices/virtual/light_state";
private void setLightOn() {
  
   try {
      Writer light_tunetoch = new FileWriter(LIGHT_POWER_PATH );
      light_tunetoch .write(frequency);
      light_tunetoch .flush();
      light_tunetoch .close();
   } catch (IOException e) {
      Log.i(TAG, "setLightOn()   IOException e "+e.getMessage());
      e.printStackTrace();
   }
}      

這樣寫入值出現問題點如下:

應用層往裝置節點寫值出現了沒有權限問題,日志如下

IOException e = /sys/devices/virtual/light_state: open failed: EACCES (Permission denied)      

出現這種情況,一般是權限問題。

解決方案:

方法1:關閉selinux

adb root; adb shell setenforce 0      

方法2:添權重限.

common/sepolicy/platform_app.te
common/sepolicy/file.te
common/sepolicy/file_contexts      

在file.te檔案添加自己自定義的檔案名,并給予檔案類型

type sysfs_fm, fs_type,sysfs_type;      
allow platform_app sysfs_fm:file {getattr open write read};      
/sys/devices/virtual//power_state     u:object_r:sysfs_fm:s0
/sys/devices/virtual//tunetoch     u:object_r:sysfs_fm:s0