Andriod Settings

前言

公司開發(fā) Android Launcher 項(xiàng)目,需要設(shè)置一些系統(tǒng)的屬性,比如說修改系統(tǒng)語言設(shè)置,修改輸入法,修改時(shí)間格式,修改時(shí)區(qū)等等,因?yàn)槭且恍┫到y(tǒng)屬性,配置的時(shí)候都一些注意的要點(diǎn)。

修改系統(tǒng)語言設(shè)置

修改系統(tǒng)語言比較特殊,需要用到一個(gè)叫作 ActivityManagerNative 類,這個(gè)類在 layoutlib.jar 中,它與 android.jar 是同一級(jí)別的,不參與編譯進(jìn) apk 中,所以需要自己導(dǎo)入。

  • android studo 的導(dǎo)入方法如下:
android {
  ...需寫在 android 之后
}

dependencies {
  ...
    provided files(getLayoutLibPath())
  ...
}

tasks.withType(JavaCompile) {
  options.encoding = "UTF-8"
}

/**
 * get layoutlib.jar path
 * android.os.SystemProperties need it
 * must called after "android" definition
 */
def getLayoutLibPath() {
    return "${android.getSdkDirectory().getAbsolutePath()}" + "/platforms/" + android.compileSdkVersion + "/data/layoutlib.jar"
}

接下來就是修改語言的代碼

IActivityManager iManager;
try {
      iManager = ActivityManagerNative.getDefault();
      Configuration localConfiguration = iManager.getConfiguration();
      localConfiguration.locale = mInfos.get(position).getLocale();
      iManager.updateConfiguration(localConfiguration);
      BackupManager.dataChanged("com.android.providers.settings");
      finish();
      } catch (RemoteException e) {
      e.printStackTrace();
}
  • 這里的locale對(duì)象,代表了一個(gè)特定的地理、政治和文化地區(qū)。在操作 Date、Calendar等表示日期/時(shí)間的對(duì)象時(shí),經(jīng)常會(huì)用到。

  • 這里用到了 Configuration,對(duì)其進(jìn)行了修改,就需要聲明權(quán)限

    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>
    
  • 同時(shí)因?yàn)檫@是系統(tǒng)級(jí)別的權(quán)限,普通的第三方應(yīng)用沒有權(quán)限使用,即使聲明了該權(quán)限也無法獲取該權(quán)限,需要聲明該應(yīng)用為系統(tǒng)應(yīng)用:需要在 AndroidManifest.xml 添加:

    android:sharedUserId="android.uid.system"
    

Android Settings

其它許多系統(tǒng)屬性的修改都在 Settings 應(yīng)用當(dāng)中進(jìn)行設(shè)置,比如 wifi,藍(lán)牙狀態(tài),等一些相關(guān)的系統(tǒng)屬性。這些屬性的數(shù)據(jù)主要保存在數(shù)據(jù)庫 settings 中,而 settings 保存的位置在:/data/data/com.android.providers.settings/databases/settings.db。

我從自己機(jī)器中拉了一個(gè)出來,上傳了堅(jiān)果云,可以下載了看看。

settings數(shù)據(jù)庫堅(jiān)果云地址

主要的操作就是針對(duì)以下三張表:

表名 URI 備注
secure Settings.Secure content://settings/secure 安全性的用戶偏好系統(tǒng)設(shè)置,第三方APP有讀沒有寫的權(quán)限
global Settings.Global content://settings/global 所有的編號(hào)設(shè)置,對(duì)系統(tǒng)的所有用戶公開,第三方APP有讀沒有寫的權(quán)限
system Settings.system content://settings/system 包含各種各樣的用戶偏好系統(tǒng)設(shè)置

因?yàn)檫@是一個(gè)本應(yīng)用外的數(shù)據(jù)庫,不能跨進(jìn)程和包直接訪問,就需要用到了內(nèi)容提供者ContentProvider和內(nèi)容解析者ContentResolver。
跨進(jìn)程通信的ContentProvider

簡(jiǎn)短的概括一下就是,如果跨進(jìn)程訪問數(shù)據(jù),需要將這個(gè)數(shù)據(jù)通過ContentProvider共享出來,然后通過ContentResolver 訪問到,執(zhí)行增刪改查的操作。ContentProvider是一個(gè)抽象類,也就是繼承實(shí)現(xiàn)它,而 Android 中對(duì) settings.db 實(shí)現(xiàn)的就是 SettingsProvider,當(dāng)中封裝了對(duì) settings.db 的操作,而framework有一個(gè)類對(duì)使用SettingsProvider進(jìn)行了封裝。

以Secure表為例

三個(gè)表的使用都差不多,就以secure為例。

獲取當(dāng)前輸入法
String defaultMethodId = Settings.Secure.getString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
修改當(dāng)前輸入法

先在系統(tǒng)的配置信息中添加該輸入法,通過 Settings.Secure.ENABLE_INPUT_METHODS 添加,如果有多個(gè)輸入法,這些字符串間以分號(hào)分隔,再將輸入法設(shè)置成默認(rèn)輸入法

Settings.Secure.putString(getContentResolver(), Settings.Secure.ENABLED_INPUT_METHODS, newInputMethodId);
Settings.Secure.putString(getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD, newInputMethodId);
獲取日期格式
Settings.System.getString(getContentResolver(), Settings.System.DATE_FORMAT)
添加權(quán)限
<uses-permission android:name="android.permission.SET_TIME"/> <!--允許程序設(shè)置系統(tǒng)時(shí)間-->
<uses-permission android:name="android.permission.SET_TIME_ZONE" /> <!--允許程序設(shè)置系統(tǒng)時(shí)區(qū)-->
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/> <!--允許應(yīng)用程序讀取或?qū)懭氚踩到y(tǒng)設(shè)置-->
<uses-permission android:name="android.permission.WRITE_SETTINGS" /> <!--允許應(yīng)用程序讀取或?qū)懭氚踩到y(tǒng)設(shè)置-->
Condition
  • 在獲取時(shí)區(qū)的時(shí)候,Calendar對(duì)象需要重新獲取,不然獲得時(shí)區(qū)值不會(huì)變
  • 在 Android6.0 之后,申請(qǐng) WRITE_SETTINGS 的權(quán)限,會(huì)出現(xiàn)閃退的情況,異常為:java.lang.IllegalArgumentException : You can not keep your settings in the secure settings.
    • 原因:在 Android6.0 以后,WRITE_SETTINGS 權(quán)限的保護(hù)等級(jí)已經(jīng)由原來的 dangerous 升級(jí)為signatrue, 意味著APP需要用系統(tǒng)簽名或者成為系統(tǒng)預(yù)裝軟件才能夠申請(qǐng)?jiān)摍?quán)限,并且還需要提示用戶跳轉(zhuǎn)到修改系統(tǒng)的設(shè)置界面去授予此權(quán)限。
    • 解決方案:要想申請(qǐng)?jiān)摍?quán)限,apk必須要打包,簽名打包,debug模式是不能申請(qǐng)?jiān)摍?quán)限的
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容