2012年11月17日 星期六

Android下如何寫出一個需要Root應用的程式


在Linux/Unix環境下root是最高權限者,所以擁有root就等於擁有系統全部控制權,也因為這樣只要使用root隨便一個動作將會造成系統的損毀或是產生資安問題。
正因如此Android裝置一般原廠不會開放root權限而只會提供uid及gid為shell的權限,除了擔心使用者勿刪重要檔案外,最主要的原因還是資訊安全的問題,例如保護apk程式、線上影音DRM、...等等。
本篇主要實作如何在Android程式中使用root權限執行動作,注意的是當Android裝置進行root後,原廠幾乎不在保固該設備,故本篇文章內容說明在SDK開發中使用root權限全所以不提供如何root方法,相關root方法有需要的Google搜尋一下吧。


【免責聲明】:本實作有可能會造成Android裝置或是相關周邊的損毀,相對可能危及到相關設備的保固或維修,請評估是否可以自行承擔相關風險,如無把握請勿嘗試將不負任何責任。

在Google Play中我們發現有不少程式會使用到root權限才能執行,通常這些程式絕大多都是為了更改檔案(裝置)系統權限,然後使用它。
例如HelloUsbUart這一篇文章內容所述如果要掛載USB隨身碟的話最快的方法就是將/dev/usb/xxx(裝置名)權限改為 drwxrwxrwx (chmod 777)然後將該裝置掛載到一個目錄下就可以使用了,這種方式有點類似[root] StickMount這個程式做法,使用這樣的方法優點是程式撰寫簡單,使用Linux操作指令就可用了,缺點是裝置需要進行root,有保固問題。
另外值得一提的是在Google Play上有一個不用root就可以讀取USB隨身碟軟體Nexus Media Importer,這支程式作法就類似使用上一篇直接使用USB通訊來做,所以不用root權限就可以讀取USB隨身碟,這部分請看下圖程式開啟時會去讀取的USB裝置是/dev/bus/usb/00x/00x....訊息。使用這樣的方法優點是裝置不需要進行root,缺點是程式撰寫比較進階(專業)而且要對於USB裝置的通訊十分清楚。

除了USB隨身碟應用外,再舉個比較知名的軟體SetCPU for Root Users,這支程式主要就是在調整/sys/devices/system/cpu目錄下的參數達到節能獲超頻的功能,由於該目錄下的檔案權限一般shell的權限無法修改,所以必須透過root權限來讀寫。

綜合上述說明概略的提出了root權限的使用時機,今天實作如何在Android程式中使用root權限執行動作,延續上一篇HelloUsbUart文章還是以NEXUS 7作為測試平台。

下面是本次實驗的環境:
Google nexus 7 (Android 4.2 Jelly Bean)
ASUS Transformer Prime TF201
OTG線
USB to RS-232 (PL-2303)

開發環境:
Win 7 SP1
Java 1.6.0_35
Eclipse 3.7.2
Android SDK r20.0.3

具備知識
Linux系統操作
USB通訊知識


程式內容:
(1)獲取與設備通訊的權限
在這個部分在這支程式可有可無,這部分功能主要是偵測當USB裝置插上後,會詢問是否要執行這個程式,如果不需要這樣的功能可以直接跳過。
參考Android USB 應用之 HelloUsbUart(RS-232)這篇文章中的獲取與設備通訊的權限,主要是改AndroidManifest.xml及增加res/xml/device_filter.xml

AndroidManifest.xml

在<intent-filter>與</intent-filter>加入 <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
在</activity>前面加入 <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"  android:resource="@xml/device_filter" />
在專案目錄 res 中建立一個 xml目錄,在xml目錄下建立一個device_filter.xml檔案,其內容定義USB的PID與UID這必須要視你連上的USB裝置而定,相關內容如下:


res/xml/device_filter.xml

<?xml version="1.0" encoding="utf-8"?>

<resources>
    <usb-device vendor-id="1659" product-id="8963" />
</resources>


(2)主程式MainActivity中程式碼如下:





上述程式主要有三個步驟:
a.執行 "su -c system/bin/sh" 將預設shell使用者改變成root。
b.用root權限執行chmod 0666 /dev/xxx(裝置名)
c.離開root權限返回shell使用者。

(3)執行結果:

可以用指令方式確認:
執行程式前:
android:/ $ ls -l /dev/ttyUSB0                                        
crw------- root     root     188,   0 2012-11-16 09:57 ttyUSB0
執行程式後:
android:/ # ls -l /dev/ttyUSB0                                          
crw-rw-rw- root     root     188,   0 2012-11-16 17:47 ttyUSB0
  

後記:
類似這樣的方法同樣可以使用在NDK開發下,如果是透過NDK來開始用root權限的話,只要找有關於C語言執行外部指令同樣執行上面所說的abc三個步驟即可。

==============延伸閱讀=====================
Android USB 應用之 HelloUsbUart(RS-232)

==============相關閱讀=====================
Java Native Interface (JNI) Android實戰篇(使用NDK) -- HelloUart
Android Bluetooth 應用之 HelloBTUart(RS-232)


沒有留言:

張貼留言