Adding a warning button when notification access is not available
Bug: 63418030 Change-Id: I4c2c497d989902ac002314a3b8fb97083757958b
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2017 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.
|
||||||
|
-->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0"
|
||||||
|
android:tint="?android:attr/textColorPrimary" >
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Copyright (C) 2017 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.
|
||||||
|
-->
|
||||||
|
<ImageView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:contentDescription="@string/title_missing_notification_access"
|
||||||
|
android:scaleType="center"
|
||||||
|
android:src="@drawable/ic_warning"
|
||||||
|
android:tint="?android:attr/textColorSecondary" />
|
||||||
@@ -178,6 +178,12 @@
|
|||||||
<string name="icon_badging_desc_on">On</string>
|
<string name="icon_badging_desc_on">On</string>
|
||||||
<!-- Text to indicate that the system icon badging setting is off [CHAR LIMIT=100] -->
|
<!-- Text to indicate that the system icon badging setting is off [CHAR LIMIT=100] -->
|
||||||
<string name="icon_badging_desc_off">Off</string>
|
<string name="icon_badging_desc_off">Off</string>
|
||||||
|
<!-- Title for the dialog shown when the app does not has notification access, explaining the requirement for notification access [CHAR LIMIT=50] -->
|
||||||
|
<string name="title_missing_notification_access">Notification access needed</string>
|
||||||
|
<!-- Message explaining to the user that the notification access is required by the app for showing 'Notification dots' [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="msg_missing_notification_access">To show Notification Dots, turn on app notifications for <xliff:g id="name" example="My App">%1$s</xliff:g></string>
|
||||||
|
<!-- Button text in the confirmation dialog which would take the user to the system settings [CHAR LIMIT=50] -->
|
||||||
|
<string name="title_change_settings">Change settings</string>
|
||||||
|
|
||||||
<!-- Label for the setting that allows the automatic placement of launcher shortcuts for applications and games installed on the device [CHAR LIMIT=40] -->
|
<!-- Label for the setting that allows the automatic placement of launcher shortcuts for applications and games installed on the device [CHAR LIMIT=40] -->
|
||||||
<string name="auto_add_shortcuts_label">Add icon to Home screen</string>
|
<string name="auto_add_shortcuts_label">Add icon to Home screen</string>
|
||||||
|
|||||||
@@ -16,17 +16,18 @@
|
|||||||
|
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<Preference
|
<com.android.launcher3.views.ButtonPreference
|
||||||
android:key="pref_icon_badging"
|
android:key="pref_icon_badging"
|
||||||
android:title="@string/icon_badging_title"
|
android:title="@string/icon_badging_title"
|
||||||
android:persistent="false">
|
android:persistent="false"
|
||||||
|
android:widgetLayout="@layout/notification_pref_warning" >
|
||||||
<intent android:action="android.settings.NOTIFICATION_SETTINGS">
|
<intent android:action="android.settings.NOTIFICATION_SETTINGS">
|
||||||
<!-- This extra highlights the "Allow icon badges" field in Notification settings -->
|
<!-- This extra highlights the "Allow icon badges" field in Notification settings -->
|
||||||
<extra
|
<extra
|
||||||
android:name=":settings:fragment_args_key"
|
android:name=":settings:fragment_args_key"
|
||||||
android:value="notification_badging" />
|
android:value="notification_badging" />
|
||||||
</intent>
|
</intent>
|
||||||
</Preference>
|
</com.android.launcher3.views.ButtonPreference>
|
||||||
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="pref_add_icon_to_home"
|
android:key="pref_add_icon_to_home"
|
||||||
|
|||||||
@@ -17,7 +17,15 @@
|
|||||||
package com.android.launcher3;
|
package com.android.launcher3;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.app.DialogFragment;
|
||||||
|
import android.app.FragmentManager;
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -26,8 +34,11 @@ import android.preference.Preference;
|
|||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.provider.Settings.System;
|
import android.provider.Settings.System;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import com.android.launcher3.graphics.IconShapeOverride;
|
import com.android.launcher3.graphics.IconShapeOverride;
|
||||||
|
import com.android.launcher3.notification.NotificationListener;
|
||||||
|
import com.android.launcher3.views.ButtonPreference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings activity for Launcher. Currently implements the following setting: Allow rotation
|
* Settings activity for Launcher. Currently implements the following setting: Allow rotation
|
||||||
@@ -37,6 +48,8 @@ public class SettingsActivity extends Activity {
|
|||||||
private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging";
|
private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging";
|
||||||
// TODO: use Settings.Secure.NOTIFICATION_BADGING
|
// TODO: use Settings.Secure.NOTIFICATION_BADGING
|
||||||
private static final String NOTIFICATION_BADGING = "notification_badging";
|
private static final String NOTIFICATION_BADGING = "notification_badging";
|
||||||
|
/** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
|
||||||
|
private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -85,17 +98,22 @@ public class SettingsActivity extends Activity {
|
|||||||
rotationPref.setDefaultValue(Utilities.getAllowRotationDefaultValue(getActivity()));
|
rotationPref.setDefaultValue(Utilities.getAllowRotationDefaultValue(getActivity()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Preference iconBadgingPref = findPreference(ICON_BADGING_PREFERENCE_KEY);
|
ButtonPreference iconBadgingPref =
|
||||||
|
(ButtonPreference) findPreference(ICON_BADGING_PREFERENCE_KEY);
|
||||||
if (!Utilities.isAtLeastO()) {
|
if (!Utilities.isAtLeastO()) {
|
||||||
getPreferenceScreen().removePreference(
|
getPreferenceScreen().removePreference(
|
||||||
findPreference(SessionCommitReceiver.ADD_ICON_PREFERENCE_KEY));
|
findPreference(SessionCommitReceiver.ADD_ICON_PREFERENCE_KEY));
|
||||||
getPreferenceScreen().removePreference(iconBadgingPref);
|
getPreferenceScreen().removePreference(iconBadgingPref);
|
||||||
} else {
|
} else {
|
||||||
// Listen to system notification badge settings while this UI is active.
|
// Listen to system notification badge settings while this UI is active.
|
||||||
mIconBadgingObserver = new IconBadgingObserver(iconBadgingPref, resolver);
|
mIconBadgingObserver = new IconBadgingObserver(
|
||||||
|
iconBadgingPref, resolver, getFragmentManager());
|
||||||
resolver.registerContentObserver(
|
resolver.registerContentObserver(
|
||||||
Settings.Secure.getUriFor(NOTIFICATION_BADGING),
|
Settings.Secure.getUriFor(NOTIFICATION_BADGING),
|
||||||
false, mIconBadgingObserver);
|
false, mIconBadgingObserver);
|
||||||
|
resolver.registerContentObserver(
|
||||||
|
Settings.Secure.getUriFor(NOTIFICATION_ENABLED_LISTENERS),
|
||||||
|
false, mIconBadgingObserver);
|
||||||
mIconBadgingObserver.onChange(true);
|
mIconBadgingObserver.onChange(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,24 +171,74 @@ public class SettingsActivity extends Activity {
|
|||||||
* Content observer which listens for system badging setting changes,
|
* Content observer which listens for system badging setting changes,
|
||||||
* and updates the launcher badging setting subtext accordingly.
|
* and updates the launcher badging setting subtext accordingly.
|
||||||
*/
|
*/
|
||||||
private static class IconBadgingObserver extends ContentObserver {
|
private static class IconBadgingObserver extends ContentObserver
|
||||||
|
implements View.OnClickListener {
|
||||||
|
|
||||||
private final Preference mBadgingPref;
|
private final ButtonPreference mBadgingPref;
|
||||||
private final ContentResolver mResolver;
|
private final ContentResolver mResolver;
|
||||||
|
private final FragmentManager mFragmentManager;
|
||||||
|
|
||||||
public IconBadgingObserver(Preference badgingPref, ContentResolver resolver) {
|
public IconBadgingObserver(ButtonPreference badgingPref, ContentResolver resolver,
|
||||||
|
FragmentManager fragmentManager) {
|
||||||
super(new Handler());
|
super(new Handler());
|
||||||
mBadgingPref = badgingPref;
|
mBadgingPref = badgingPref;
|
||||||
mResolver = resolver;
|
mResolver = resolver;
|
||||||
|
mFragmentManager = fragmentManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChange(boolean selfChange) {
|
public void onChange(boolean selfChange) {
|
||||||
boolean enabled = Settings.Secure.getInt(mResolver, NOTIFICATION_BADGING, 1) == 1;
|
boolean enabled = Settings.Secure.getInt(mResolver, NOTIFICATION_BADGING, 1) == 1;
|
||||||
mBadgingPref.setSummary(enabled
|
int summary = enabled ? R.string.icon_badging_desc_on : R.string.icon_badging_desc_off;
|
||||||
? R.string.icon_badging_desc_on
|
|
||||||
: R.string.icon_badging_desc_off);
|
boolean serviceEnabled = true;
|
||||||
|
if (enabled) {
|
||||||
|
// Check if the listener is enabled or not.
|
||||||
|
String enabledListeners =
|
||||||
|
Settings.Secure.getString(mResolver, NOTIFICATION_ENABLED_LISTENERS);
|
||||||
|
ComponentName myListener =
|
||||||
|
new ComponentName(mBadgingPref.getContext(), NotificationListener.class);
|
||||||
|
serviceEnabled = enabledListeners != null &&
|
||||||
|
(enabledListeners.contains(myListener.flattenToString()) ||
|
||||||
|
enabledListeners.contains(myListener.flattenToShortString()));
|
||||||
|
if (!serviceEnabled) {
|
||||||
|
summary = R.string.title_missing_notification_access;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mBadgingPref.setButtonOnClickListener(serviceEnabled ? null : this);
|
||||||
|
mBadgingPref.setSummary(summary);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
new NotificationAccessConfirmation().show(mFragmentManager, "notification_access");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class NotificationAccessConfirmation
|
||||||
|
extends DialogFragment implements DialogInterface.OnClickListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
final Context context = getActivity();
|
||||||
|
String msg = context.getString(R.string.msg_missing_notification_access,
|
||||||
|
context.getString(R.string.derived_app_name));
|
||||||
|
return new AlertDialog.Builder(context)
|
||||||
|
.setTitle(R.string.title_missing_notification_access)
|
||||||
|
.setMessage(msg)
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
.setPositiveButton(R.string.title_change_settings, this)
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
ComponentName cn = new ComponentName(getActivity(), NotificationListener.class);
|
||||||
|
Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)
|
||||||
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
.putExtra(":settings:fragment_args_key", cn.flattenToString());
|
||||||
|
getActivity().startActivity(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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.
|
||||||
|
*/
|
||||||
|
package com.android.launcher3.views;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension of {@link Preference} which makes the widget layout clickable.
|
||||||
|
*
|
||||||
|
* @see #setWidgetLayoutResource(int)
|
||||||
|
*/
|
||||||
|
public class ButtonPreference extends Preference {
|
||||||
|
|
||||||
|
private View.OnClickListener mClickListener;
|
||||||
|
|
||||||
|
public ButtonPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ButtonPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ButtonPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ButtonPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setButtonOnClickListener(View.OnClickListener clickListener) {
|
||||||
|
if (mClickListener != clickListener) {
|
||||||
|
mClickListener = clickListener;
|
||||||
|
notifyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBindView(View view) {
|
||||||
|
super.onBindView(view);
|
||||||
|
|
||||||
|
ViewGroup widgetFrame = view.findViewById(android.R.id.widget_frame);
|
||||||
|
if (widgetFrame != null) {
|
||||||
|
View button = widgetFrame.getChildAt(0);
|
||||||
|
if (button != null) {
|
||||||
|
button.setOnClickListener(mClickListener);
|
||||||
|
}
|
||||||
|
widgetFrame.setVisibility(
|
||||||
|
(mClickListener == null || button == null) ? View.GONE : View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user