斷定手機系統的構建模式、用戶模式android
編譯 Rom 時,須要指定目標構建模式,構建模式有三種:用戶模式 user、用戶調試模式 userdebug 和工程模式 eng安全
- 用戶模式 user
- 僅安裝標籤爲 user 的模塊
- 設定屬性 ro.secure=1,打開安全檢查功能
- 設定屬性 ro.debuggable=0,關閉應用調試功能
- 默認關閉 adb 功能
- 打開 Proguard 混淆器
- 打開 DEXPREOPT 預先編譯優化
- 用戶調試模式 userdebug
- 安裝標籤爲 user、debug 的模塊
- 設定屬性 ro.secure=1,打開安全檢查功能
- 設定屬性 ro.debuggable=1,啓用應用調試功能
- 默認打開 adb 功能
- 打開 Proguard 混淆器
- 打開 DEXPREOPT 預先編譯優化
- 工程模式 eng
- 安裝標籤爲 user、debug、eng 的模塊
- 設定屬性 ro.secure=0,關閉安全檢查功能
- 設定屬性 ro.debuggable=1,啓用應用調試功能
- 設定屬性 ro.kernel.android.checkjni=1,啓用 JNI 調用檢查
- 默認打開 adb 功能
- 關閉 Proguard 混淆器
- 關閉 DEXPREOPT 預先編譯優化
指定目標構建模式:在
make
命令中加入參數ide$ sudo make -j8 PRODUCT-rk312x-user $ sudo make -j8 PRODUCT-rk312x-userdebug $ sudo make -j8 PRODUCT-rk312x-eng來源:https://www.kancloud.cn/amoy0226/fireprime_android_compile/105885函數
思路:經過觀察以上三個模式的屬性,這裏使用安全檢查功能(ro.securero)和應用調試功能(ro.debuggable)兩個屬性來區分這三個模式:優化
其中,若是隻需判斷是否爲 user 模式,使用 ro.debuggable 一個屬性便可。ui
在 android.os.Build
的源碼中我發現一個靜態變量:spa
/** * Returns true if we are running a debug build such as "user-debug" or "eng". * @hide */ public static final boolean IS_DEBUGGABLE = SystemProperties.getInt("ro.debuggable", 0) == 1;
可是沒有 ro.securero
這個屬性,進一步發現其調用的是 android.os.SystemProperties
的 getInt()
函數,那能夠直接使用它來獲取ro.securero
的值。debug
因爲是 android.os.SystemProperties
是隱藏類,咱們能夠使用兩種方式來調用其方法:調試
方法一:使用修改過增長了這些隱藏類的 android.jar 來編譯 APK,此方式問題較多,配置繁瑣,不推薦;code
方法二:使用反射調用,普通 App 便可使用,無限制,推薦使用此方法。
源碼產品免費下載地址:http://www.jinhusns.com/Products/Download
先說下方法一下的實現:
/** * 獲取系統構建模式 * * @return int(0:未知, 1 user, 2 userdebug, 3 eng) */ public static int getOSMode() { int debug = SystemProperties.getInt("ro.debuggable", -1); int secure = SystemProperties.getInt("ro.secure", -1); if (debug == 0 && secure == 1) return 1; else if (debug == 1 && secure == 1) return 2; else if (debug == 1 && secure == 0) return 3; else return 0; }
那麼方法二隻是和方法一的屬性獲取方式不同:
/** * 獲取系統構建模式 * * @return int(0:未知, 1 user, 2 userdebug, 3 eng) */ public static int getOSMode() { try { Class clazz = Class.forName("android.os.SystemProperties"); int debug = (int) clazz.getMethod("getInt", String.class, int.class).invoke(clazz, "ro.debuggable", -1); int secure = (int) clazz.getMethod("getInt", String.class, int.class).invoke(clazz, "ro.secure", -1); if (debug == 0 && secure == 1) return 1; else if (debug == 1 && secure == 1) return 2; else if (debug == 1 && secure == 0) return 3; else return 0; } catch (ClassNotFoundException ignore) { } catch (NoSuchMethodException ignore) { } catch (IllegalAccessException ignore) { } catch (InvocationTargetException ignore) { } return 0; }
這裏未對反射時可能產生的異常作處理,只是簡單的返回 0,有須要請自行處理。
android.os.Build
和 android.os.SystemProperties
的源碼在 Android SDK 中,很方便尋找,比較困難的一步就是了解到所需的屬性和這兩個類有關,這就須要對 Android Rom 的編譯有一點了解。