使用Java程式碼在應用層獲取Android系統屬性
之前使用Native程式碼的property_get()/property_set()來獲取Android系統屬性,現在需要改寫到Java上面,
但是System.getProperty() / System.setProperty()所操作的屬性與上面的是不同的東西,而在android.os.Build只提供了訪問ro屬性的方法。
好在Google提供了一個隱藏類android.os.SystemProperties用來管理屬性,其內部實際上也是通過JNI呼叫Native的property_get和property_set方法來獲得和設定屬性。我們不能直接import這個類來使用,但是可以通過Java中的反射機制來實現。
get程式碼如下:
- private static Method getStringPropMethod = null;
- private static Method getBooleanPropMethod = null;
- public static String getSystemPropString(final String key, final String defaultValue) {
- try {
- if (getStringPropMethod == null) {
- getStringPropMethod = Class.forName("android.os.SystemProperties"
- .getMethod("get", String.class, String.class);
- }
- return (String) getStringPropMethod.invoke(null, key, defaultValue);
- } catch (Exception e) {
- Log.e(TAG, "Reflect error: " + e.toString());
- return defaultValue;
- }
- }
- public
- try {
- if (getBooleanPropMethod == null) {
- getBooleanPropMethod = Class.forName("android.os.SystemProperties")
- .getMethod("getBoolean", String.class, boolean.class);
- }
- return (boolean) getBooleanPropMethod.invoke(null, key, defaultValue);
- } catch (Exception e) {
- Log.e(TAG, "Reflect error: " + e.toString());
- return defaultValue;
- }
- }
屬性名字的意義:
(1)persist.* : 以persist開始的屬性會在/data/property存一個副本。也就是說,如果程式調property_set設了一個以persist為字首的屬性,系統會在/data/property/*里加一個檔案記錄這個屬性,重啟以後這個屬性還有。
如果property_set其它屬性,因為屬性是在記憶體裡存,所以重啟後這個屬性就沒有了。
(2)ro.* :以ro為字首的屬性不能修改。
(3)如果屬性名稱以“net.”開頭,當設定這個屬性時,“net.change”屬性將會自動設定,以加入到最後修改的屬性名。(這是很巧妙的。 netresolve模組的使用這個屬性來追蹤在net.*屬性上的任何變化。)
(4)屬性“ ctrl.start ”和“ ctrl.stop ”是用來啟動和停止服務。每一項服務必須在/init.rc中定義.系統啟動時,與init守護程序將解析init.rc和啟動屬性服務。一旦收到設定“ ctrl.start ”屬性的請求,屬性服務將使用該屬性值作為服務名找到該服務,啟動該服務。這項服務的啟動結果將會放入“ init.svc.<服務名>“屬性中。客戶端應用程式可以輪詢那個屬性值,以確定結果。