Update notification log
- Change notification presentation to better match notification shade - Stop constantly removing and readding all of the preferences - Update individual preferences in a kind of hacky way (to be improved later) - Link notification entries to notification preferences screen - Hide notification summaries Bug: 137396965 Test: manual Change-Id: Icdd54488b8bf659f6fe42af93e42cd21912fa4fe
This commit is contained in:
@@ -26,8 +26,7 @@
|
|||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@*android:dimen/status_bar_icon_size"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="6dp"
|
|
||||||
>
|
>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
@@ -46,24 +45,38 @@
|
|||||||
android:scaleType="fitCenter" />
|
android:scaleType="fitCenter" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title"
|
android:id="@+id/pkgname"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_toStartOf="@+id/timestamp"
|
|
||||||
android:layout_toEndOf="@id/icon"
|
android:layout_toEndOf="@id/icon"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:textAlignment="viewStart"
|
android:textAlignment="viewStart" />
|
||||||
android:labelFor="@android:id/button2" />
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/alerted_icon"
|
||||||
|
android:layout_width="@*android:dimen/status_bar_icon_size"
|
||||||
|
android:layout_height="@*android:dimen/status_bar_icon_size"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginStart="6dp"
|
||||||
|
android:paddingTop="1dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_toEndOf="@id/pkgname"
|
||||||
|
android:tint="?android:attr/textColorSecondary"
|
||||||
|
android:src="@drawable/ic_notifications_alert"
|
||||||
|
/>
|
||||||
|
|
||||||
<DateTimeView
|
<DateTimeView
|
||||||
android:id="@+id/timestamp"
|
android:id="@+id/timestamp"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="13dp"
|
||||||
|
android:paddingBottom="13dp"
|
||||||
android:layout_alignBottom="@android:id/widget_frame"
|
android:layout_alignBottom="@android:id/widget_frame"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_alignTop="@android:id/widget_frame"
|
android:layout_alignTop="@android:id/widget_frame"
|
||||||
@@ -78,26 +91,25 @@
|
|||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@*android:dimen/status_bar_icon_size"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="vertical"
|
||||||
android:layout_marginStart="30dp"
|
android:layout_marginStart="30dp"
|
||||||
android:layout_marginBottom="6dp"
|
android:layout_marginBottom="6dp"
|
||||||
>
|
>
|
||||||
|
|
||||||
<ImageView
|
<TextView
|
||||||
android:id="@+id/pkgicon"
|
android:id="@+id/title"
|
||||||
android:layout_width="@*android:dimen/status_bar_icon_size"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@*android:dimen/status_bar_icon_size"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="0dp"
|
android:layout_gravity="left|center_vertical"
|
||||||
android:layout_marginEnd="6dp"
|
android:ellipsize="end"
|
||||||
android:contentDescription="@null"
|
android:singleLine="true"
|
||||||
android:adjustViewBounds="true"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:maxHeight="@*android:dimen/status_bar_icon_size"
|
android:textAlignment="viewStart"
|
||||||
android:maxWidth="@*android:dimen/status_bar_icon_size"
|
/>
|
||||||
android:scaleType="fitCenter" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/pkgname"
|
android:id="@+id/text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="left|center_vertical"
|
android:layout_gravity="left|center_vertical"
|
||||||
@@ -106,12 +118,30 @@
|
|||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:textAlignment="viewStart"
|
android:textAlignment="viewStart"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/extra"
|
android:id="@+id/extra"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/notification_extra"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginStart="30dp"
|
||||||
|
android:singleLine="false"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="10sp"
|
||||||
|
android:fontFamily="monospace"
|
||||||
|
android:textAlignment="viewStart"
|
||||||
|
/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/ranking_extra"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
@@ -122,6 +152,7 @@
|
|||||||
android:textSize="10sp"
|
android:textSize="10sp"
|
||||||
android:fontFamily="monospace"
|
android:fontFamily="monospace"
|
||||||
android:textAlignment="viewStart"
|
android:textAlignment="viewStart"
|
||||||
/>
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@@ -9997,14 +9997,7 @@
|
|||||||
<string name="notification_log_details_ashmem">ashmem</string>
|
<string name="notification_log_details_ashmem">ashmem</string>
|
||||||
<!-- Notification log debug tool: header: notification alert info -->
|
<!-- Notification log debug tool: header: notification alert info -->
|
||||||
<string name="notification_log_details_alerted">notification alerted</string>
|
<string name="notification_log_details_alerted">notification alerted</string>
|
||||||
<!-- Notification log debug tool: header: notification sound info -->
|
<string name="notification_log_channel">channel</string>
|
||||||
<string name="notification_log_details_sound">sound</string>
|
|
||||||
<!-- Notification log debug tool: header: notification vibration info -->
|
|
||||||
<string name="notification_log_details_vibrate">vibrate</string>
|
|
||||||
<!-- Notification log debug tool: header: notification vibration info -->
|
|
||||||
<string name="notification_log_details_vibrate_pattern">pattern</string>
|
|
||||||
<!-- Notification log debug tool: the word 'default' -->
|
|
||||||
<string name="notification_log_details_default">default</string>
|
|
||||||
<!-- Notification log debug tool: the word 'none' -->
|
<!-- Notification log debug tool: the word 'none' -->
|
||||||
<string name="notification_log_details_none">none</string>
|
<string name="notification_log_details_none">none</string>
|
||||||
<!-- Notification log debug tool: missing ranking information -->
|
<!-- Notification log debug tool: missing ranking information -->
|
||||||
|
@@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
package com.android.settings.notification;
|
package com.android.settings.notification;
|
||||||
|
|
||||||
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
|
import static android.provider.Settings.EXTRA_APP_PACKAGE;
|
||||||
|
import static android.provider.Settings.EXTRA_CHANNEL_ID;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
@@ -27,18 +28,19 @@ import android.app.PendingIntent;
|
|||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.IntentSender;
|
import android.content.IntentSender;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.Resources;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.service.notification.NotificationListenerService;
|
import android.service.notification.NotificationListenerService;
|
||||||
import android.service.notification.NotificationListenerService.Ranking;
|
import android.service.notification.NotificationListenerService.Ranking;
|
||||||
import android.service.notification.NotificationListenerService.RankingMap;
|
import android.service.notification.NotificationListenerService.RankingMap;
|
||||||
@@ -49,6 +51,7 @@ import android.text.TextUtils;
|
|||||||
import android.text.style.StyleSpan;
|
import android.text.style.StyleSpan;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.widget.DateTimeView;
|
import android.widget.DateTimeView;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -62,8 +65,8 @@ import com.android.settings.SettingsPreferenceFragment;
|
|||||||
import com.android.settings.Utils;
|
import com.android.settings.Utils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class NotificationStation extends SettingsPreferenceFragment {
|
public class NotificationStation extends SettingsPreferenceFragment {
|
||||||
@@ -72,33 +75,44 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
private static final boolean DUMP_EXTRAS = true;
|
private static final boolean DUMP_EXTRAS = true;
|
||||||
private static final boolean DUMP_PARCEL = true;
|
private static final boolean DUMP_PARCEL = true;
|
||||||
private Handler mHandler;
|
|
||||||
|
|
||||||
private static class HistoricalNotificationInfo {
|
private static class HistoricalNotificationInfo {
|
||||||
public String key;
|
public String key;
|
||||||
public String channel;
|
public NotificationChannel channel;
|
||||||
public String pkg;
|
public String pkg;
|
||||||
public Drawable pkgicon;
|
public Drawable pkgicon;
|
||||||
public CharSequence pkgname;
|
public CharSequence pkgname;
|
||||||
public Drawable icon;
|
public Drawable icon;
|
||||||
public CharSequence title;
|
public CharSequence title;
|
||||||
|
public CharSequence text;
|
||||||
public int priority;
|
public int priority;
|
||||||
public int user;
|
public int user;
|
||||||
public long timestamp;
|
public long timestamp;
|
||||||
public boolean active;
|
public boolean active;
|
||||||
public CharSequence extra;
|
public CharSequence notificationExtra;
|
||||||
|
public CharSequence rankingExtra;
|
||||||
|
public boolean alerted;
|
||||||
|
public boolean visuallyInterruptive;
|
||||||
|
|
||||||
|
public void updateFrom(HistoricalNotificationInfo updatedInfo) {
|
||||||
|
this.channel = updatedInfo.channel;
|
||||||
|
this.icon = updatedInfo.icon;
|
||||||
|
this.title = updatedInfo.title;
|
||||||
|
this.text = updatedInfo.text;
|
||||||
|
this.priority = updatedInfo.priority;
|
||||||
|
this.timestamp = updatedInfo.timestamp;
|
||||||
|
this.active = updatedInfo.active;
|
||||||
|
this.alerted = updatedInfo.alerted;
|
||||||
|
this.visuallyInterruptive = updatedInfo.visuallyInterruptive;
|
||||||
|
this.notificationExtra = updatedInfo.notificationExtra;
|
||||||
|
this.rankingExtra = updatedInfo.rankingExtra;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PackageManager mPm;
|
private PackageManager mPm;
|
||||||
private INotificationManager mNoMan;
|
private INotificationManager mNoMan;
|
||||||
private RankingMap mRanking;
|
private RankingMap mRanking;
|
||||||
|
private LinkedList<HistoricalNotificationInfo> mNotificationInfos;
|
||||||
private Runnable mRefreshListRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
refreshList();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private final NotificationListenerService mListener = new NotificationListenerService() {
|
private final NotificationListenerService mListener = new NotificationListenerService() {
|
||||||
@Override
|
@Override
|
||||||
@@ -106,15 +120,21 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
logd("onNotificationPosted: %s, with update for %d", sbn.getNotification(),
|
logd("onNotificationPosted: %s, with update for %d", sbn.getNotification(),
|
||||||
ranking == null ? 0 : ranking.getOrderedKeys().length);
|
ranking == null ? 0 : ranking.getOrderedKeys().length);
|
||||||
mRanking = ranking;
|
mRanking = ranking;
|
||||||
scheduleRefreshList();
|
if (sbn.getNotification().isGroupSummary()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addOrUpdateNotification(sbn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNotificationRemoved(StatusBarNotification notification, RankingMap ranking) {
|
public void onNotificationRemoved(StatusBarNotification sbn, RankingMap ranking) {
|
||||||
logd("onNotificationRankingUpdate with update for %d",
|
logd("onNotificationRankingUpdate with update for %d",
|
||||||
ranking == null ? 0 : ranking.getOrderedKeys().length);
|
ranking == null ? 0 : ranking.getOrderedKeys().length);
|
||||||
mRanking = ranking;
|
mRanking = ranking;
|
||||||
scheduleRefreshList();
|
if (sbn.getNotification().isGroupSummary()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
markNotificationAsDismissed(sbn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -122,7 +142,7 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
logd("onNotificationRankingUpdate with update for %d",
|
logd("onNotificationRankingUpdate with update for %d",
|
||||||
ranking == null ? 0 : ranking.getOrderedKeys().length);
|
ranking == null ? 0 : ranking.getOrderedKeys().length);
|
||||||
mRanking = ranking;
|
mRanking = ranking;
|
||||||
scheduleRefreshList();
|
updateNotificationsFromRanking();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -130,44 +150,29 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
mRanking = getCurrentRanking();
|
mRanking = getCurrentRanking();
|
||||||
logd("onListenerConnected with update for %d",
|
logd("onListenerConnected with update for %d",
|
||||||
mRanking == null ? 0 : mRanking.getOrderedKeys().length);
|
mRanking == null ? 0 : mRanking.getOrderedKeys().length);
|
||||||
scheduleRefreshList();
|
populateNotifications();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private void scheduleRefreshList() {
|
|
||||||
if (mHandler != null) {
|
|
||||||
mHandler.removeCallbacks(mRefreshListRunnable);
|
|
||||||
mHandler.postDelayed(mRefreshListRunnable, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
|
||||||
private final Comparator<HistoricalNotificationInfo> mNotificationSorter
|
private final Comparator<HistoricalNotificationInfo> mNotificationSorter
|
||||||
= new Comparator<HistoricalNotificationInfo>() {
|
= (lhs, rhs) -> Long.compare(rhs.timestamp, lhs.timestamp);
|
||||||
@Override
|
|
||||||
public int compare(HistoricalNotificationInfo lhs,
|
|
||||||
HistoricalNotificationInfo rhs) {
|
|
||||||
return Long.compare(rhs.timestamp, lhs.timestamp);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Activity activity) {
|
public void onAttach(Activity activity) {
|
||||||
logd("onAttach(%s)", activity.getClass().getSimpleName());
|
logd("onAttach(%s)", activity.getClass().getSimpleName());
|
||||||
super.onAttach(activity);
|
super.onAttach(activity);
|
||||||
mHandler = new Handler(activity.getMainLooper());
|
|
||||||
mContext = activity;
|
mContext = activity;
|
||||||
mPm = mContext.getPackageManager();
|
mPm = mContext.getPackageManager();
|
||||||
mNoMan = INotificationManager.Stub.asInterface(
|
mNoMan = INotificationManager.Stub.asInterface(
|
||||||
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
|
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
|
||||||
|
mNotificationInfos = new LinkedList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetach() {
|
public void onDetach() {
|
||||||
logd("onDetach()");
|
logd("onDetach()");
|
||||||
mHandler.removeCallbacks(mRefreshListRunnable);
|
|
||||||
mHandler = null;
|
|
||||||
super.onDetach();
|
super.onDetach();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,24 +210,84 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Cannot register listener", e);
|
Log.e(TAG, "Cannot register listener", e);
|
||||||
}
|
}
|
||||||
refreshList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshList() {
|
/**
|
||||||
List<HistoricalNotificationInfo> infos = loadNotifications();
|
* Adds all current and historical notifications when the NLS connects.
|
||||||
if (infos != null) {
|
*/
|
||||||
final int N = infos.size();
|
private void populateNotifications() {
|
||||||
logd("adding %d infos", N);
|
loadNotifications();
|
||||||
Collections.sort(infos, mNotificationSorter);
|
final int N = mNotificationInfos.size();
|
||||||
if (getPreferenceScreen() == null) {
|
logd("adding %d infos", N);
|
||||||
setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
|
if (getPreferenceScreen() == null) {
|
||||||
|
setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
|
||||||
|
}
|
||||||
|
getPreferenceScreen().removeAll();
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
getPreferenceScreen().addPreference(new HistoricalNotificationPreference(
|
||||||
|
getPrefContext(), mNotificationInfos.get(i), i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds and dims the given notification in the preferences list.
|
||||||
|
*/
|
||||||
|
private void markNotificationAsDismissed(StatusBarNotification sbn) {
|
||||||
|
final int N = mNotificationInfos.size();
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
final HistoricalNotificationInfo info = mNotificationInfos.get(i);
|
||||||
|
if (TextUtils.equals(info.key, sbn.getKey())) {
|
||||||
|
info.active = false;
|
||||||
|
((HistoricalNotificationPreference) getPreferenceScreen().findPreference(
|
||||||
|
sbn.getKey())).updatePreference(info);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
getPreferenceScreen().removeAll();
|
}
|
||||||
for (int i = 0; i < N; i++) {
|
}
|
||||||
getPreferenceScreen().addPreference(
|
|
||||||
new HistoricalNotificationPreference(getPrefContext(), infos.get(i)));
|
/**
|
||||||
|
* Either updates a notification with its latest information or (if it's something the user
|
||||||
|
* would consider a new notification) adds a new entry at the start of the list.
|
||||||
|
*/
|
||||||
|
private void addOrUpdateNotification(StatusBarNotification sbn) {
|
||||||
|
HistoricalNotificationInfo newInfo = createFromSbn(sbn, true);
|
||||||
|
boolean needsAdd = true;
|
||||||
|
final int N = mNotificationInfos.size();
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
final HistoricalNotificationInfo info = mNotificationInfos.get(i);
|
||||||
|
if (TextUtils.equals(info.key, sbn.getKey()) && info.active
|
||||||
|
&& !newInfo.alerted && !newInfo.visuallyInterruptive) {
|
||||||
|
info.updateFrom(newInfo);
|
||||||
|
|
||||||
|
((HistoricalNotificationPreference) getPreferenceScreen().findPreference(
|
||||||
|
sbn.getKey())).updatePreference(info);
|
||||||
|
needsAdd = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (needsAdd) {
|
||||||
|
mNotificationInfos.addFirst(newInfo);
|
||||||
|
getPreferenceScreen().addPreference(new HistoricalNotificationPreference(
|
||||||
|
getPrefContext(),
|
||||||
|
mNotificationInfos.peekFirst(), -1 * mNotificationInfos.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates all notifications in the list based on new information in the ranking.
|
||||||
|
*/
|
||||||
|
private void updateNotificationsFromRanking() {
|
||||||
|
Ranking rank = new Ranking();
|
||||||
|
for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
|
||||||
|
final HistoricalNotificationPreference p =
|
||||||
|
(HistoricalNotificationPreference) getPreferenceScreen().getPreference(i);
|
||||||
|
final HistoricalNotificationInfo info = mNotificationInfos.get(i);
|
||||||
|
mRanking.getRanking(p.getKey(), rank);
|
||||||
|
|
||||||
|
updateFromRanking(info);
|
||||||
|
((HistoricalNotificationPreference) getPreferenceScreen().findPreference(
|
||||||
|
info.key)).updatePreference(info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void logd(String msg, Object... args) {
|
private static void logd(String msg, Object... args) {
|
||||||
@@ -242,14 +307,46 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
CharSequence title = null;
|
CharSequence title = null;
|
||||||
if (n.extras != null) {
|
if (n.extras != null) {
|
||||||
title = n.extras.getCharSequence(Notification.EXTRA_TITLE);
|
title = n.extras.getCharSequence(Notification.EXTRA_TITLE);
|
||||||
if (TextUtils.isEmpty(title)) {
|
}
|
||||||
title = n.extras.getCharSequence(Notification.EXTRA_TEXT);
|
return title == null? null : String.valueOf(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the appropriate substring for this notification based on the style of notification.
|
||||||
|
*/
|
||||||
|
private static String getTextString(Context appContext, Notification n) {
|
||||||
|
CharSequence text = null;
|
||||||
|
if (n.extras != null) {
|
||||||
|
text = n.extras.getCharSequence(Notification.EXTRA_TEXT);
|
||||||
|
|
||||||
|
Notification.Builder nb = Notification.Builder.recoverBuilder(appContext, n);
|
||||||
|
|
||||||
|
if (nb.getStyle() instanceof Notification.BigTextStyle) {
|
||||||
|
text = ((Notification.BigTextStyle) nb.getStyle()).getBigText();
|
||||||
|
} else if (nb.getStyle() instanceof Notification.MessagingStyle) {
|
||||||
|
Notification.MessagingStyle ms = (Notification.MessagingStyle) nb.getStyle();
|
||||||
|
final List<Notification.MessagingStyle.Message> messages = ms.getMessages();
|
||||||
|
if (messages != null && messages.size() > 0) {
|
||||||
|
text = messages.get(messages.size() - 1).getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(text)) {
|
||||||
|
text = n.extras.getCharSequence(Notification.EXTRA_TEXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (TextUtils.isEmpty(title) && !TextUtils.isEmpty(n.tickerText)) {
|
return text == null ? null : String.valueOf(text);
|
||||||
title = n.tickerText;
|
}
|
||||||
|
|
||||||
|
private static Drawable loadIcon(Context context, StatusBarNotification sbn) {
|
||||||
|
Drawable draw = sbn.getNotification().getSmallIcon().loadDrawableAsUser(
|
||||||
|
sbn.getPackageContext(context), sbn.getUserId());
|
||||||
|
if (draw == null) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return String.valueOf(title);
|
draw.mutate();
|
||||||
|
draw.setColorFilter(sbn.getNotification().color, PorterDuff.Mode.SRC_ATOP);
|
||||||
|
return draw;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String formatPendingIntent(PendingIntent pi) {
|
private static String formatPendingIntent(PendingIntent pi) {
|
||||||
@@ -265,7 +362,11 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<HistoricalNotificationInfo> loadNotifications() {
|
/**
|
||||||
|
* Reads all current and past notifications (up to the system limit, since the device was
|
||||||
|
* booted), stores the data we need to present them, and sorts them chronologically for display.
|
||||||
|
*/
|
||||||
|
private void loadNotifications() {
|
||||||
final int currentUserId = ActivityManager.getCurrentUser();
|
final int currentUserId = ActivityManager.getCurrentUser();
|
||||||
try {
|
try {
|
||||||
StatusBarNotification[] active = mNoMan.getActiveNotifications(
|
StatusBarNotification[] active = mNoMan.getActiveNotifications(
|
||||||
@@ -274,51 +375,125 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
mContext.getPackageName(), 50);
|
mContext.getPackageName(), 50);
|
||||||
|
|
||||||
List<HistoricalNotificationInfo> list
|
List<HistoricalNotificationInfo> list
|
||||||
= new ArrayList<HistoricalNotificationInfo>(active.length + dismissed.length);
|
= new ArrayList<>(active.length + dismissed.length);
|
||||||
|
|
||||||
for (StatusBarNotification[] resultset
|
for (StatusBarNotification[] resultSet
|
||||||
: new StatusBarNotification[][] { active, dismissed }) {
|
: new StatusBarNotification[][] { active, dismissed }) {
|
||||||
for (StatusBarNotification sbn : resultset) {
|
for (StatusBarNotification sbn : resultSet) {
|
||||||
if (sbn.getUserId() != UserHandle.USER_ALL & sbn.getUserId() != currentUserId) {
|
if (sbn.getUserId() != UserHandle.USER_ALL & sbn.getUserId() != currentUserId) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (sbn.getNotification().isGroupSummary()) {
|
||||||
final Notification n = sbn.getNotification();
|
continue;
|
||||||
final HistoricalNotificationInfo info = new HistoricalNotificationInfo();
|
|
||||||
info.pkg = sbn.getPackageName();
|
|
||||||
info.user = sbn.getUserId();
|
|
||||||
info.icon = loadIconDrawable(info.pkg, info.user, n.icon);
|
|
||||||
info.pkgicon = loadPackageIconDrawable(info.pkg, info.user);
|
|
||||||
info.pkgname = loadPackageName(info.pkg);
|
|
||||||
info.title = getTitleString(n);
|
|
||||||
if (TextUtils.isEmpty(info.title)) {
|
|
||||||
info.title = getString(R.string.notification_log_no_title);
|
|
||||||
}
|
}
|
||||||
info.timestamp = sbn.getPostTime();
|
final HistoricalNotificationInfo info = createFromSbn(sbn, resultSet == active);
|
||||||
info.priority = n.priority;
|
|
||||||
info.channel = n.getChannelId();
|
|
||||||
info.key = sbn.getKey();
|
|
||||||
|
|
||||||
info.active = (resultset == active);
|
|
||||||
|
|
||||||
info.extra = generateExtraText(sbn, info);
|
|
||||||
|
|
||||||
logd(" [%d] %s: %s", info.timestamp, info.pkg, info.title);
|
logd(" [%d] %s: %s", info.timestamp, info.pkg, info.title);
|
||||||
list.add(info);
|
list.add(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
// notifications are given to us in the same order as the shade; sorted by inferred
|
||||||
|
// priority. Resort chronologically for our display.
|
||||||
|
list.sort(mNotificationSorter);
|
||||||
|
mNotificationInfos = new LinkedList<>(list);
|
||||||
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "Cannot load Notifications: ", e);
|
Log.e(TAG, "Cannot load Notifications: ", e);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HistoricalNotificationInfo createFromSbn(StatusBarNotification sbn, boolean active) {
|
||||||
|
final Notification n = sbn.getNotification();
|
||||||
|
final HistoricalNotificationInfo info = new HistoricalNotificationInfo();
|
||||||
|
info.pkg = sbn.getPackageName();
|
||||||
|
info.user = sbn.getUserId();
|
||||||
|
info.icon = loadIcon(mContext, sbn);
|
||||||
|
if (info.icon == null) {
|
||||||
|
info.icon = loadPackageIconDrawable(info.pkg, info.user);
|
||||||
|
}
|
||||||
|
info.pkgname = loadPackageName(info.pkg);
|
||||||
|
info.title = getTitleString(n);
|
||||||
|
info.text = getTextString(sbn.getPackageContext(mContext), n);
|
||||||
|
info.timestamp = sbn.getPostTime();
|
||||||
|
info.priority = n.priority;
|
||||||
|
info.key = sbn.getKey();
|
||||||
|
|
||||||
|
info.active = active;
|
||||||
|
info.notificationExtra = generateExtraText(sbn, info);
|
||||||
|
|
||||||
|
updateFromRanking(info);
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFromRanking(HistoricalNotificationInfo info) {
|
||||||
|
Ranking rank = new Ranking();
|
||||||
|
if (mRanking == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mRanking.getRanking(info.key, rank);
|
||||||
|
info.alerted = rank.getLastAudiblyAlertedMillis() > 0;
|
||||||
|
info.visuallyInterruptive = rank.visuallyInterruptive();
|
||||||
|
info.channel = rank.getChannel();
|
||||||
|
info.rankingExtra = generateRankingExtraText(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a string of debug information for this notification based on the RankingMap
|
||||||
|
*/
|
||||||
|
private CharSequence generateRankingExtraText(HistoricalNotificationInfo info) {
|
||||||
|
final SpannableStringBuilder sb = new SpannableStringBuilder();
|
||||||
|
final String delim = getString(R.string.notification_log_details_delimiter);
|
||||||
|
|
||||||
|
Ranking rank = new Ranking();
|
||||||
|
if (mRanking != null && mRanking.getRanking(info.key, rank)) {
|
||||||
|
if (info.active && info.alerted) {
|
||||||
|
sb.append("\n")
|
||||||
|
.append(bold(getString(R.string.notification_log_details_alerted)));
|
||||||
|
}
|
||||||
|
sb.append("\n")
|
||||||
|
.append(bold(getString(R.string.notification_log_channel)))
|
||||||
|
.append(delim)
|
||||||
|
.append(info.channel.toString());
|
||||||
|
if (info.active) {
|
||||||
|
sb.append("\n")
|
||||||
|
.append(bold(getString(
|
||||||
|
R.string.notification_log_details_importance)))
|
||||||
|
.append(delim)
|
||||||
|
.append(Ranking.importanceToString(rank.getImportance()));
|
||||||
|
if (rank.getImportanceExplanation() != null) {
|
||||||
|
sb.append("\n")
|
||||||
|
.append(bold(getString(
|
||||||
|
R.string.notification_log_details_explanation)))
|
||||||
|
.append(delim)
|
||||||
|
.append(rank.getImportanceExplanation());
|
||||||
|
}
|
||||||
|
sb.append("\n")
|
||||||
|
.append(bold(getString(
|
||||||
|
R.string.notification_log_details_badge)))
|
||||||
|
.append(delim)
|
||||||
|
.append(Boolean.toString(rank.canShowBadge()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mRanking == null) {
|
||||||
|
sb.append("\n")
|
||||||
|
.append(bold(getString(
|
||||||
|
R.string.notification_log_details_ranking_null)));
|
||||||
|
} else {
|
||||||
|
sb.append("\n")
|
||||||
|
.append(bold(getString(
|
||||||
|
R.string.notification_log_details_ranking_none)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a string of debug information for this notification
|
||||||
|
*/
|
||||||
private CharSequence generateExtraText(StatusBarNotification sbn,
|
private CharSequence generateExtraText(StatusBarNotification sbn,
|
||||||
HistoricalNotificationInfo info) {
|
HistoricalNotificationInfo info) {
|
||||||
final Ranking rank = new Ranking();
|
|
||||||
|
|
||||||
final Notification n = sbn.getNotification();
|
final Notification n = sbn.getNotification();
|
||||||
final SpannableStringBuilder sb = new SpannableStringBuilder();
|
final SpannableStringBuilder sb = new SpannableStringBuilder();
|
||||||
final String delim = getString(R.string.notification_log_details_delimiter);
|
final String delim = getString(R.string.notification_log_details_delimiter);
|
||||||
@@ -333,10 +508,6 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
.append(bold(getString(R.string.notification_log_details_icon)))
|
.append(bold(getString(R.string.notification_log_details_icon)))
|
||||||
.append(delim)
|
.append(delim)
|
||||||
.append(String.valueOf(n.getSmallIcon()));
|
.append(String.valueOf(n.getSmallIcon()));
|
||||||
sb.append("\n")
|
|
||||||
.append(bold("channelId"))
|
|
||||||
.append(delim)
|
|
||||||
.append(String.valueOf(n.getChannelId()));
|
|
||||||
sb.append("\n")
|
sb.append("\n")
|
||||||
.append(bold("postTime"))
|
.append(bold("postTime"))
|
||||||
.append(delim)
|
.append(delim)
|
||||||
@@ -357,58 +528,6 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
getString(R.string.notification_log_details_group_summary)));
|
getString(R.string.notification_log_details_group_summary)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (info.active) {
|
|
||||||
// mRanking only applies to active notifications
|
|
||||||
if (mRanking != null && mRanking.getRanking(sbn.getKey(), rank)) {
|
|
||||||
if (rank.getLastAudiblyAlertedMillis() > 0) {
|
|
||||||
sb.append("\n")
|
|
||||||
.append(bold(getString(R.string.notification_log_details_alerted)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
NotificationChannel channel = mNoMan.getNotificationChannelForPackage(
|
|
||||||
sbn.getPackageName(), sbn.getUid(), n.getChannelId(), false);
|
|
||||||
sb.append("\n")
|
|
||||||
.append(bold(getString(R.string.notification_log_details_sound)))
|
|
||||||
.append(delim);
|
|
||||||
if (channel == null || channel.getImportance() == IMPORTANCE_UNSPECIFIED) {
|
|
||||||
|
|
||||||
if (0 != (n.defaults & Notification.DEFAULT_SOUND)) {
|
|
||||||
sb.append(getString(R.string.notification_log_details_default));
|
|
||||||
} else if (n.sound != null) {
|
|
||||||
sb.append(n.sound.toString());
|
|
||||||
} else {
|
|
||||||
sb.append(getString(R.string.notification_log_details_none));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sb.append(String.valueOf(channel.getSound()));
|
|
||||||
}
|
|
||||||
sb.append("\n")
|
|
||||||
.append(bold(getString(R.string.notification_log_details_vibrate)))
|
|
||||||
.append(delim);
|
|
||||||
if (channel == null || channel.getImportance() == IMPORTANCE_UNSPECIFIED) {
|
|
||||||
if (0 != (n.defaults & Notification.DEFAULT_VIBRATE)) {
|
|
||||||
sb.append(getString(R.string.notification_log_details_default));
|
|
||||||
} else if (n.vibrate != null) {
|
|
||||||
sb.append(getString(R.string.notification_log_details_vibrate_pattern));
|
|
||||||
} else {
|
|
||||||
sb.append(getString(R.string.notification_log_details_none));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (channel.getVibrationPattern() != null) {
|
|
||||||
sb.append(getString(R.string.notification_log_details_vibrate_pattern));
|
|
||||||
} else {
|
|
||||||
sb.append(getString(R.string.notification_log_details_none));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.d(TAG, "cannot read channel info", e);
|
|
||||||
}
|
|
||||||
sb.append("\n")
|
|
||||||
.append(bold(getString(R.string.notification_log_details_visibility)))
|
|
||||||
.append(delim)
|
|
||||||
.append(Notification.visibilityToString(n.visibility));
|
|
||||||
if (n.publicVersion != null) {
|
if (n.publicVersion != null) {
|
||||||
sb.append("\n")
|
sb.append("\n")
|
||||||
.append(bold(getString(
|
.append(bold(getString(
|
||||||
@@ -416,42 +535,7 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
.append(delim)
|
.append(delim)
|
||||||
.append(getTitleString(n.publicVersion));
|
.append(getTitleString(n.publicVersion));
|
||||||
}
|
}
|
||||||
sb.append("\n")
|
|
||||||
.append(bold(getString(R.string.notification_log_details_priority)))
|
|
||||||
.append(delim)
|
|
||||||
.append(Notification.priorityToString(n.priority));
|
|
||||||
if (info.active) {
|
|
||||||
// mRanking only applies to active notifications
|
|
||||||
if (mRanking != null && mRanking.getRanking(sbn.getKey(), rank)) {
|
|
||||||
sb.append("\n")
|
|
||||||
.append(bold(getString(
|
|
||||||
R.string.notification_log_details_importance)))
|
|
||||||
.append(delim)
|
|
||||||
.append(Ranking.importanceToString(rank.getImportance()));
|
|
||||||
if (rank.getImportanceExplanation() != null) {
|
|
||||||
sb.append("\n")
|
|
||||||
.append(bold(getString(
|
|
||||||
R.string.notification_log_details_explanation)))
|
|
||||||
.append(delim)
|
|
||||||
.append(rank.getImportanceExplanation());
|
|
||||||
}
|
|
||||||
sb.append("\n")
|
|
||||||
.append(bold(getString(
|
|
||||||
R.string.notification_log_details_badge)))
|
|
||||||
.append(delim)
|
|
||||||
.append(Boolean.toString(rank.canShowBadge()));
|
|
||||||
} else {
|
|
||||||
if (mRanking == null) {
|
|
||||||
sb.append("\n")
|
|
||||||
.append(bold(getString(
|
|
||||||
R.string.notification_log_details_ranking_null)));
|
|
||||||
} else {
|
|
||||||
sb.append("\n")
|
|
||||||
.append(bold(getString(
|
|
||||||
R.string.notification_log_details_ranking_none)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (n.contentIntent != null) {
|
if (n.contentIntent != null) {
|
||||||
sb.append("\n")
|
sb.append("\n")
|
||||||
.append(bold(getString(
|
.append(bold(getString(
|
||||||
@@ -535,25 +619,6 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
return sb;
|
return sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Resources getResourcesForUserPackage(String pkg, int userId) {
|
|
||||||
Resources r = null;
|
|
||||||
|
|
||||||
if (pkg != null) {
|
|
||||||
try {
|
|
||||||
if (userId == UserHandle.USER_ALL) {
|
|
||||||
userId = UserHandle.USER_SYSTEM;
|
|
||||||
}
|
|
||||||
r = mPm.getResourcesForApplicationAsUser(pkg, userId);
|
|
||||||
} catch (PackageManager.NameNotFoundException ex) {
|
|
||||||
Log.e(TAG, "Icon package not found: " + pkg, ex);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r = mContext.getResources();
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Drawable loadPackageIconDrawable(String pkg, int userId) {
|
private Drawable loadPackageIconDrawable(String pkg, int userId) {
|
||||||
Drawable icon = null;
|
Drawable icon = null;
|
||||||
try {
|
try {
|
||||||
@@ -576,31 +641,17 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
return pkg;
|
return pkg;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Drawable loadIconDrawable(String pkg, int userId, int resId) {
|
|
||||||
Resources r = getResourcesForUserPackage(pkg, userId);
|
|
||||||
|
|
||||||
if (resId == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return r.getDrawable(resId, null);
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
Log.w(TAG, "Icon not found in "
|
|
||||||
+ (pkg != null ? resId : "<system>")
|
|
||||||
+ ": " + Integer.toHexString(resId), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class HistoricalNotificationPreference extends Preference {
|
private static class HistoricalNotificationPreference extends Preference {
|
||||||
private final HistoricalNotificationInfo mInfo;
|
private final HistoricalNotificationInfo mInfo;
|
||||||
private static long sLastExpandedTimestamp; // quick hack to keep things from collapsing
|
private static long sLastExpandedTimestamp; // quick hack to keep things from collapsing
|
||||||
|
public ViewGroup mItemView; // hack to update prefs fast;
|
||||||
|
|
||||||
public HistoricalNotificationPreference(Context context, HistoricalNotificationInfo info) {
|
public HistoricalNotificationPreference(Context context, HistoricalNotificationInfo info,
|
||||||
|
int order) {
|
||||||
super(context);
|
super(context);
|
||||||
setLayoutResource(R.layout.notification_log_row);
|
setLayoutResource(R.layout.notification_log_row);
|
||||||
|
setOrder(order);
|
||||||
|
setKey(info.key);
|
||||||
mInfo = info;
|
mInfo = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,41 +659,67 @@ public class NotificationStation extends SettingsPreferenceFragment {
|
|||||||
public void onBindViewHolder(PreferenceViewHolder row) {
|
public void onBindViewHolder(PreferenceViewHolder row) {
|
||||||
super.onBindViewHolder(row);
|
super.onBindViewHolder(row);
|
||||||
|
|
||||||
if (mInfo.icon != null) {
|
mItemView = (ViewGroup) row.itemView;
|
||||||
((ImageView) row.findViewById(R.id.icon)).setImageDrawable(mInfo.icon);
|
|
||||||
|
updatePreference(mInfo);
|
||||||
|
|
||||||
|
row.findViewById(R.id.timestamp).setOnLongClickListener(v -> {
|
||||||
|
final View extras = row.findViewById(R.id.extra);
|
||||||
|
extras.setVisibility(extras.getVisibility() == View.VISIBLE
|
||||||
|
? View.GONE : View.VISIBLE);
|
||||||
|
sLastExpandedTimestamp = mInfo.timestamp;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePreference(HistoricalNotificationInfo info) {
|
||||||
|
if (mItemView == null) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (mInfo.pkgicon != null) {
|
if (info.icon != null) {
|
||||||
((ImageView) row.findViewById(R.id.pkgicon)).setImageDrawable(mInfo.pkgicon);
|
((ImageView) mItemView.findViewById(R.id.icon)).setImageDrawable(mInfo.icon);
|
||||||
|
}
|
||||||
|
((TextView) mItemView.findViewById(R.id.pkgname)).setText(mInfo.pkgname);
|
||||||
|
((DateTimeView) mItemView.findViewById(R.id.timestamp)).setTime(info.timestamp);
|
||||||
|
if (!TextUtils.isEmpty(info.title)) {
|
||||||
|
((TextView) mItemView.findViewById(R.id.title)).setText(info.title);
|
||||||
|
mItemView.findViewById(R.id.title).setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
mItemView.findViewById(R.id.title).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(info.text)) {
|
||||||
|
((TextView) mItemView.findViewById(R.id.text)).setText(info.text);
|
||||||
|
mItemView.findViewById(R.id.text).setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
mItemView.findViewById(R.id.text).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if (info.icon != null) {
|
||||||
|
((ImageView) mItemView.findViewById(R.id.icon)).setImageDrawable(info.icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
((DateTimeView) row.findViewById(R.id.timestamp)).setTime(mInfo.timestamp);
|
((DateTimeView) mItemView.findViewById(R.id.timestamp)).setTime(mInfo.timestamp);
|
||||||
((TextView) row.findViewById(R.id.title)).setText(mInfo.title);
|
|
||||||
((TextView) row.findViewById(R.id.pkgname)).setText(mInfo.pkgname);
|
|
||||||
|
|
||||||
final TextView extra = (TextView) row.findViewById(R.id.extra);
|
((TextView) mItemView.findViewById(R.id.notification_extra))
|
||||||
extra.setText(mInfo.extra);
|
.setText(mInfo.notificationExtra);
|
||||||
extra.setVisibility(mInfo.timestamp == sLastExpandedTimestamp
|
((TextView) mItemView.findViewById(R.id.ranking_extra))
|
||||||
? View.VISIBLE : View.GONE);
|
.setText(mInfo.rankingExtra);
|
||||||
|
|
||||||
row.itemView.setOnClickListener(
|
mItemView.findViewById(R.id.extra).setVisibility(
|
||||||
new View.OnClickListener() {
|
mInfo.timestamp == sLastExpandedTimestamp ? View.VISIBLE : View.GONE);
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
extra.setVisibility(extra.getVisibility() == View.VISIBLE
|
|
||||||
? View.GONE : View.VISIBLE);
|
|
||||||
sLastExpandedTimestamp = mInfo.timestamp;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
row.itemView.setAlpha(mInfo.active ? 1.0f : 0.5f);
|
mItemView.setAlpha(mInfo.active ? 1.0f : 0.5f);
|
||||||
|
|
||||||
|
mItemView.findViewById(R.id.alerted_icon).setVisibility(
|
||||||
|
mInfo.alerted ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void performClick() {
|
public void performClick() {
|
||||||
// Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
|
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
|
||||||
// Uri.fromParts("package", mInfo.pkg, null));
|
.putExtra(EXTRA_APP_PACKAGE, mInfo.pkg)
|
||||||
// intent.setComponent(intent.resolveActivity(getContext().getPackageManager()));
|
.putExtra(EXTRA_CHANNEL_ID, mInfo.channel.getId());
|
||||||
// getContext().startActivity(intent);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
getContext().startActivity(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user