List apps that advertise notification settings.
Apps that have a CATEGORY_NOTIFICATION_PREFERENCES + CATEGORY_DEFAULT activity will be listed in notification settings, with a convenient link to that activity so the user can tweak those settings. Change-Id: Idc97b2aee3f070225822ebee1ecbeab79e7b9c2d
This commit is contained in:
84
res/layout/notification_app.xml
Normal file
84
res/layout/notification_app.xml
Normal file
@@ -0,0 +1,84 @@
|
||||
<!--
|
||||
Copyright (C) 2014 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toStartOf="@+id/divider"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/icon"
|
||||
android:layout_width="@android:dimen/app_icon_size"
|
||||
android:layout_height="@android:dimen/app_icon_size"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_marginStart="0dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:contentDescription="@null"
|
||||
android:maxHeight="@android:dimen/app_icon_size"
|
||||
android:maxWidth="@android:dimen/app_icon_size"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toStartOf="@android:id/button1"
|
||||
android:layout_toEndOf="@android:id/icon"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textAlignment="viewStart"
|
||||
android:labelFor="@android:id/button2" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- Divider -->
|
||||
|
||||
<ImageView
|
||||
android:id="@id/divider"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toStartOf="@android:id/button2"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/nav_divider" />
|
||||
|
||||
<!-- Settings icon -->
|
||||
|
||||
<ImageView
|
||||
android:id="@android:id/button2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignBottom="@android:id/widget_frame"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignTop="@android:id/widget_frame"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_margin="0dip"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/notification_app_settings_button"
|
||||
android:padding="8dip"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:src="@drawable/ic_bt_config" />
|
||||
|
||||
</RelativeLayout>
|
@@ -5041,4 +5041,8 @@
|
||||
|
||||
<!-- [CHAR LIMIT=20] Notifications settings: Apps section header -->
|
||||
<string name="notification_settings_apps">Apps</string>
|
||||
|
||||
<!-- [CHAR LIMIT=NONE] Content description for per-app notification
|
||||
settings button -->
|
||||
<string name="notification_app_settings_button">Notification settings</string>
|
||||
</resources>
|
||||
|
@@ -75,14 +75,11 @@
|
||||
<Preference
|
||||
android:title="Coming soon"
|
||||
/>
|
||||
-->
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="category_apps"
|
||||
android:title="@string/notification_settings_apps"/>
|
||||
|
||||
<Preference
|
||||
android:title="Coming soon"
|
||||
/>
|
||||
-->
|
||||
android:title="@string/notification_settings_apps">
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
@@ -17,9 +17,16 @@
|
||||
package com.android.settings;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.RingtoneManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@@ -30,12 +37,26 @@ import android.preference.Preference.OnPreferenceClickListener;
|
||||
import android.preference.PreferenceGroup;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.provider.Settings;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class NotificationSettings extends SettingsPreferenceFragment implements
|
||||
Preference.OnPreferenceChangeListener, OnPreferenceClickListener {
|
||||
private static final String TAG = "NotificationSettings";
|
||||
|
||||
private static final Intent APP_NOTIFICATION_PREFS_CATEGORY_INTENT
|
||||
= new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_NOTIFICATION_PREFERENCES);
|
||||
|
||||
private static final String KEY_NOTIFICATION_SOUND = "notification_sound";
|
||||
private static final String KEY_ZEN_MODE = "zen_mode";
|
||||
private static final String KEY_NOTIFICATION_ACCESS = "manage_notification_access";
|
||||
@@ -44,6 +65,7 @@ public class NotificationSettings extends SettingsPreferenceFragment implements
|
||||
private static final String KEY_NOTIFICATION_PULSE = "notification_pulse";
|
||||
|
||||
private static final String KEY_SECURITY_CATEGORY = "category_security";
|
||||
private static final String KEY_APPS_CATEGORY = "category_apps";
|
||||
private static final String KEY_TWEAKS_CATEGORY = "category_tweaks"; // power toys, eng only
|
||||
|
||||
private static final int MSG_UPDATE_SOUND_SUMMARY = 2;
|
||||
@@ -81,6 +103,84 @@ public class NotificationSettings extends SettingsPreferenceFragment implements
|
||||
}
|
||||
};
|
||||
|
||||
private final ArrayList<AppNotificationInfo> mAppNotificationInfo
|
||||
= new ArrayList<AppNotificationInfo>();
|
||||
private final HashSet<String> mAppNotificationInfoPackages = new HashSet<String>();
|
||||
private final Comparator<AppNotificationInfo> mAppComparator = new Comparator<AppNotificationInfo>() {
|
||||
private final Collator sCollator = Collator.getInstance();
|
||||
@Override
|
||||
public int compare(AppNotificationInfo lhs, AppNotificationInfo rhs) {
|
||||
return sCollator.compare(lhs.label, rhs.label);
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable mCollectAppsRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (mAppNotificationInfo) {
|
||||
mAppNotificationInfo.clear();
|
||||
mAppNotificationInfoPackages.clear();
|
||||
|
||||
final PackageManager pm = getPackageManager();
|
||||
|
||||
final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(APP_NOTIFICATION_PREFS_CATEGORY_INTENT,
|
||||
PackageManager.MATCH_DEFAULT_ONLY);
|
||||
|
||||
for (ResolveInfo ri : resolveInfos) {
|
||||
final ActivityInfo activityInfo = ri.activityInfo;
|
||||
final ApplicationInfo appInfo = activityInfo.applicationInfo;
|
||||
if (mAppNotificationInfoPackages.contains(activityInfo.packageName)) {
|
||||
Log.v(TAG, "Ignoring duplicate notification preference activity ("
|
||||
+ activityInfo.name + ") for package "
|
||||
+ activityInfo.packageName);
|
||||
continue;
|
||||
}
|
||||
final AppNotificationInfo info = new AppNotificationInfo();
|
||||
mAppNotificationInfoPackages.add(activityInfo.packageName);
|
||||
|
||||
info.label = appInfo.loadLabel(pm);
|
||||
info.icon = appInfo.loadIcon(pm);
|
||||
info.name = activityInfo.name;
|
||||
info.pkg = activityInfo.packageName;
|
||||
mAppNotificationInfo.add(info);
|
||||
}
|
||||
|
||||
Collections.sort(mAppNotificationInfo, mAppComparator);
|
||||
mHandler.post(mRefreshAppsListRunnable);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable mRefreshAppsListRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final PreferenceScreen root = getPreferenceScreen();
|
||||
final PreferenceGroup appsCategory = (PreferenceGroup)
|
||||
root.findPreference(KEY_APPS_CATEGORY);
|
||||
|
||||
appsCategory.removeAll();
|
||||
|
||||
synchronized (mAppNotificationInfo) {
|
||||
if (mAppNotificationInfo.size() == 0) {
|
||||
root.removePreference(appsCategory);
|
||||
return;
|
||||
}
|
||||
|
||||
final int N = mAppNotificationInfo.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final AppNotificationInfo info = mAppNotificationInfo.get(i);
|
||||
Preference pref = new AppNotificationPreference(root.getContext());
|
||||
pref.setTitle(info.label);
|
||||
pref.setIcon(info.icon);
|
||||
pref.setIntent(new Intent(Intent.ACTION_MAIN)
|
||||
.setClassName(info.pkg, info.name));
|
||||
appsCategory.addPreference(pref);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -156,6 +256,11 @@ public class NotificationSettings extends SettingsPreferenceFragment implements
|
||||
|
||||
refreshNotificationListeners();
|
||||
lookupRingtoneNames();
|
||||
loadAppsList();
|
||||
}
|
||||
|
||||
private void loadAppsList() {
|
||||
AsyncTask.execute(mCollectAppsRunnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -252,4 +357,56 @@ public class NotificationSettings extends SettingsPreferenceFragment implements
|
||||
private void lookupRingtoneNames() {
|
||||
new Thread(mRingtoneLookupRunnable).start();
|
||||
}
|
||||
|
||||
// === Per-app notification settings row ==
|
||||
|
||||
private static class AppNotificationPreference extends Preference {
|
||||
private Intent mIntent;
|
||||
|
||||
public AppNotificationPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
|
||||
setLayoutResource(R.layout.notification_app);
|
||||
}
|
||||
|
||||
public AppNotificationPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public AppNotificationPreference(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public AppNotificationPreference(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public void setIntent(Intent intent) {
|
||||
mIntent = intent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindView(View view) {
|
||||
super.onBindView(view);
|
||||
|
||||
ImageView icon = (ImageView) view.findViewById(android.R.id.icon);
|
||||
icon.setImageDrawable(getIcon());
|
||||
TextView title = (TextView) view.findViewById(android.R.id.title);
|
||||
title.setText(getTitle());
|
||||
ImageView settingsButton = (ImageView) view.findViewById(android.R.id.button2);
|
||||
settingsButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getContext().startActivity(mIntent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static class AppNotificationInfo {
|
||||
public Drawable icon;
|
||||
public CharSequence label;
|
||||
public String name;
|
||||
public String pkg;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user