1.動態(tài)注冊廣播無法觸發(fā)點擊事件
場景:通知欄的點擊事件通常會采用PendingIntent.getBroadcast方式,這個時候如果采用動態(tài)注冊廣播,將會導致,點擊事件無法響應。
解決方案:不要采取動態(tài)注冊廣播的方式,采用清單文件注冊廣播即可
//AndroidManifest清單文件配置
<receiver android:name=".ClickReceiver"/>
//點擊事件接收的廣播
public class ClickReceiver extends BroadcastReceiver {
public static final String ACTION_SWITCH_CLICK = "notification.toutiao.com.notificationapp.CLICK";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_SWITCH_CLICK.equals(action)) {
Toast.makeText(context, "點擊事件", Toast.LENGTH_SHORT).show();
}
}
}
...省略RemoteViews創(chuàng)建部分代碼
Intent clickIntent = new Intent(this, ClickReceiver.class);
clickIntent.setAction(ClickReceiver.ACTION_SWITCH_CLICK);
//注意:getBroadcast第二個參數(shù) requestCode 值一定不能重復,否則會導后面intent覆蓋掉前面的intent
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
contentView.setOnClickPendingIntent(R.id.tv_notification_name, pendingIntent);

2.通知欄頻繁刷新導致 ANR、Crash、手機卡頓
使用場景:比如下載進度條頻繁更新。
解決方式:最短刷新時間限制(比如刷新時機大于1s) + 進度值更新時再更新通知欄(減少無用刷新)
3.部分手機不支持style api
比如金立S5、魅族MX5(顯示不全、文字遮擋)、小米系統(tǒng)、華為Mate系列。這里因為手里機型限制,style測試并不能覆蓋到大量的測試機,這邊感興趣的話可以參考網(wǎng)易考拉關于style的機型支持統(tǒng)計。

4.部分手機不支持BigPictureStyle
比如魅族、小米系統(tǒng),可以采用CustomBigContentView進行適配


CustomBigContentView適配后:

5.自定義布局的背景色適配
常見方案主要有以下兩種。
a)比如360和西瓜視頻,設置固定背景色方式。這種固定背景色方式在部分風格不搭的手機上面顯示如下這種效果,可以看出明顯比較突兀。

b)根據(jù)手機通知欄背景色進行動態(tài)適配方式
public static boolean isDarkNotificationTheme(Context context) {
return isSimilarColor(Color.BLACK, getNotificationColor(context));
}
/**
* 獲取通知欄顏色
* @param context
* @return
*/
public static int getNotificationColor(Context context) {
Notification notification = null;
try {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
notification = builder.build();
} catch (Exception e) {
e.printStackTrace();
}
if (notification = null || notification.contentView==null){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return Color.BLACK;
} else {
return Color.WHITE;
}
}
int layoutId=notification.contentView.getLayoutId();
ViewGroup viewGroup= (ViewGroup) LayoutInflater.from(context).inflate(layoutId, null, false);
if (viewGroup.findViewById(android.R.id.title)!=null) {
return ((TextView) viewGroup.findViewById(android.R.id.title)).getCurrentTextColor();
}
return findColor(viewGroup);
}
private static boolean isSimilarColor(int baseColor, int color) {
int simpleBaseColor=baseColor|0xff000000;
int simpleColor=color|0xff000000;
int baseRed= Color.red(simpleBaseColor)- Color.red(simpleColor);
int baseGreen= Color.green(simpleBaseColor)- Color.green(simpleColor);
int baseBlue= Color.blue(simpleBaseColor)- Color.blue(simpleColor);
double value= Math.sqrt(baseRed*baseRed+baseGreen*baseGreen+baseBlue*baseBlue);
if (value<180.0) {
return true;
}
return false;
}
private static int findColor(ViewGroup viewGroupSource) {
int color= Color.TRANSPARENT;
LinkedList<ViewGroup> viewGroups=new LinkedList<>();
viewGroups.add(viewGroupSource);
while (viewGroups.size()>0) {
ViewGroup viewGroup1=viewGroups.getFirst();
for (int i = 0; i < viewGroup1.getChildCount(); i++) {
if (viewGroup1.getChildAt(i) instanceof ViewGroup) {
viewGroups.add((ViewGroup) viewGroup1.getChildAt(i));
}
else if (viewGroup1.getChildAt(i) instanceof TextView) {
if (((TextView) viewGroup1.getChildAt(i)).getCurrentTextColor()!=-1) {
color=((TextView) viewGroup1.getChildAt(i)).getCurrentTextColor();
}
}
}
viewGroups.remove(viewGroup1);
}
return color;
}
調(diào)用方式
boolean isDark = isDarkNotificationTheme(this);
if (isDark) {
//其中MIUI系統(tǒng)需要單獨兼容
if (Utils.isMIUI(this)) {
contentView = 透明布局,深色字體
} else {
contentView = 白色背景,深色字體
}
} else {
contentView = 透明布局,淺色字體
}
適配后的三星SM-N9008:

6.小圖標適配
小圖標各個版本可能會有所區(qū)別,不同廠商之間的默認樣式也會存在一些差別。這里統(tǒng)計了小圖標版本歷史上的具體樣式
android <5.0

5.0<= android <7.0

android >= 7.0

關于小圖標適配,官方已有詳細文檔說明,現(xiàn)摘錄一些重點如下:
small icon 必須是帶 Alpha 透明通道的 PNG 圖片。
背景必須是透明的。
圖形必須是白色。不要上傳其他顏色的圖形,而應該通過 setColor 來染色
周圍不宜留過多的 padding

不采用上述方法,可能會導致適配失敗案例:


6.android O新增渠道概念,即設置targetSDK >=26 如果不使用渠道,將無法展示通知欄

7.OPPO為防止第三方應用推送過多無效通知,OPPO手機將默認關閉應用消息推送,用戶可根據(jù)自己需求,通過開關手動開啟。
OPPO會對某些app開啟通知欄白名單,以下統(tǒng)計了部分app
- 默認開啟的app:今日頭條、騰訊新聞、天天快報
- 默認關閉的app:新浪新聞、網(wǎng)易新聞、趣頭條、搜狐新聞、澎湃新聞、鳳凰新聞、惠頭條
接下來,我們對非白名單app如何適配權限進行研究。
新浪新聞 有彈框提示,引導用戶打開通知欄權限。如下圖所示:

網(wǎng)易新聞、搜狐新聞 打開app提示使用移動網(wǎng)絡權限,用戶點擊“始終允許”后,開啟通知欄的權限

這里參考了新浪新聞的做法,主動引導用戶開啟權限
public void openPermission() {
if (!NotificationManagerCompat.from(this).areNotificationsEnabled()) {
Intent localIntent = new Intent();
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
localIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
localIntent.setData(Uri.fromParts("package", BuildConfig.APPLICATION_ID, null));
startActivity(localIntent);
} else {
Toast.makeText(this, "您已打開通知欄權限,無需再次打開", Toast.LENGTH_SHORT).show();
}
}

8.小米MIUI9之后增加了通知過濾功能,通過算法將一些不常用、不重要的通知欄自動降級收縮到通知欄底部“不重要通知”里面。
通知過濾功能的評分模型會通過多個維度判斷通知重要與否,包括但不限于:
- 通知的文本:即標題(title) 和描述(description)
- 該應用的通知在該設備上的歷史點擊率
- 用戶的屬性(如年齡、性別、地域等)
在這些維度中,目前影響最大的維度是歷史點擊率,所以優(yōu)化方向:
app前期的歷史點擊率非常重要,app安裝后,前期盡量減少推送頻率,提高內(nèi)容質(zhì)量等,只要前期這些通知有1條被點擊,后續(xù)通知就有很大概率成為重要通知。比如熱點事件、紅包領取之類。
歷史點擊率針對的是設備。這就要求業(yè)務使用個性化的推送策略,避免全量推送,以減小被列為不重要通知的概率。
關于通知過濾
通知過濾是指將不重要的通知收納進一個統(tǒng)一的頁面。點擊不重要通知可直接查看所有被折疊的通知。范圍包括所有預裝軟件和非預裝軟件。
從小米目前的數(shù)據(jù)統(tǒng)計情況來看,即便是在二級頁,也有很多曝光、點擊行為,如果用戶點擊率回升,系統(tǒng)會再次將該app通知欄設置為重要通知。
同一個app的不同通知欄,也有可能有的在重要通知欄,有的在不重要通知欄里面

點開“不重要通知”,展開列表

9.關于自定義布局的限制:
Android系統(tǒng)可以將自定義布局通過setContent(7.X系統(tǒng)推薦使用setCustomContentView)設置到Notification.Builder中,來實現(xiàn)樣式的更變。
RemoteViews只支持4種基本的布局:
FrameLayout
LinearLayout
RelativeLayout
GridLayout
這些布局下面只支持幾種視圖控件:
AnalogClock
Button
Chronometer
ImageButton
ImageView
ProgressBar
TextView
ViewFlipper
ListView
GridView
StackView
AdapterViewFlipper
10.android O增加了桌面角標的原生支持
注意:國產(chǎn)手機在這方面的適配尚未統(tǒng)一,大多采用自己的設計風格。比如小米采用仿蘋果的 紅點數(shù)字顯示,不支持長按顯示詳情。OPPO 支持桌面圓角小圖標,但不支持長按顯示通知詳情


參考鏈接
1.https://dev.mi.com/console/doc/
2.https://open.oppomobile.com/wiki/doc#id=10171
3.https://developer.android.com/guide/practices/ui_guidelines/icon_design_status_bar
4.https://iluhcm.com/2017/03/12/experience-of-adapting-to-android-notifications/
5.https://mp.weixin.qq.com/s/Ez-G_9hzUCOjU8rRnsW8SA