关于这个通知使用权,之前写过一篇文章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就完全拥有了通知使用权,就不用再去动态申请了。哇哈哈哈!