關於這個通知使用權,之前寫過一篇文章android 如何去控制第三方音樂播放app之控制QQ音樂。介紹瞭如何去通過監聽通知去拿到QQ音樂的音樂名和歌手名。但是要拿到這個之前,應用必須得首先拿到系統的通知使用權。在上篇文章中的做法是通過主動申請去獲取的系統通知使用權。這裏再回顧一下:
if (!isNotificationServiceEnabled()) { 初次使用時 判斷是否獲取了通知使用權
enableNotificationListenerAlertDialog = buildNotificationServiceAlertDialog();
enableNotificationListenerAlertDialog.show();
}
private boolean isNotificationServiceEnabled() {
String pkgName = mActivityView.getContext().getPackageName();
final String flat = Settings.Secure.getString(mActivityView.getContext().getContentResolver(),
ENABLED_NOTIFICATION_LISTENERS);
if (!TextUtils.isEmpty(flat)) {
final String[] names = flat.split(":");
for (int i = 0; i < names.length; i++) {
final ComponentName cn = ComponentName.unflattenFromString(names[i]);
if (cn != null) {
if (TextUtils.equals(pkgName, cn.getPackageName())) {
return true;
}
}
}
}
return false;
}
但是我轉後一想,我是系統應用啊,我app中可是加了sharedUserId=“android.uid.system” 的。我應該生來就有這個權限啊。不應該再去動態申請啊,這對用戶體驗也不好啊。
首先我發現,我每次動態申請以及檢查是否具有通知使用權,都是在系統中的secure 數據庫中檢查我我的包名服務名是否已經寫入了其中。我們可以在串口中用settings 命令看下:
那接下來我們就只有一個目的,將動態寫入的這個值,在系統初次初始化時就將其加入secure 數據庫中。
因爲是secure 數據庫,原想着可以使用Settings.Secure 直接在代碼中設置的,於是就找了個開機的流程,將這個設置的操作丟進去,雖然完全開機後,發現數據裏有了值。但是依然還是獲取不到通知使用權。最後發現可能還是權限的問題,需要android 系統的權限去設置。
接來下說說正解:
還是操作secure 數據庫,但是是在一開始創建這個數據的時候,就將那行值加進去就行了。
frameworks/base / packages/SettingsProvider/res/values/defaults.xml
<resources>
frameworks\base\packages\SettingsProvider/res/values/defaults.xml
<string name="config_default_notification_app" translatable="false">包名\服務名r</string>
</resources>
frameworks/base / packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
private void loadSecureSettings(SQLiteDatabase db) {
SQLiteStatement stmt = null;
try {
stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
+ " VALUES(?,?);");
loadStringSetting(stmt, Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
R.string.config_default_notification_app);
// 將 此行加入
frameworks/base / core/java/android/provider/Settings.java
private static final HashSet<String> MOVED_TO_SECURE;
static {
MOVED_TO_SECURE = new HashSet<>(30);
MOVED_TO_SECURE.add(Secure.ANDROID_ID);
MOVED_TO_SECURE.add(Secure.ENABLED_NOTIFICATION_LISTENERS); // 加入此屬性
這樣,這個app就完全擁有了通知使用權,就不用再去動態申請了。哇哈哈哈!