Android——横幅通知
橫幅通知,也稱為提醒式通知,效果如下圖:
這個效果在QQ,微信,釘釘?shù)纫恍┲髁鞯腁pp當中,大家一定很熟悉,今天就來說說如何實現(xiàn)。
可能會觸發(fā)提醒式通知的條件有如下3種:
- 用戶的Activiity處于全屏模式(應(yīng)用使用fullScreenIntent)
- 通知的優(yōu)先級很高,且在搭載Android 7.1(API級別25)及更低版本的設(shè)備上使用鈴聲或震動。
- 在搭載Android 8.0(API級別為26)及更高版本的設(shè)備上,通知渠道的重要程度比較高。
但是現(xiàn)實往往是殘酷的,當你按照要求照做之后發(fā)現(xiàn)8.0以上系統(tǒng)還是不能實現(xiàn)你想要的效果。下面來大概說道說道原因。
由于國內(nèi)大多數(shù)App都比較流氓,喜歡這通知也發(fā),那通知也發(fā),導(dǎo)致用戶被一堆垃圾信息困擾,系統(tǒng)為了保護用戶不受此類消息的困擾,就關(guān)閉了權(quán)限,如果想要顯示,就只能由用戶手動打開該權(quán)限才行。而且系統(tǒng)沒辦法獲取該權(quán)限是否打開。所以,當產(chǎn)品再拿QQ等國民應(yīng)用來跟你說人家都能實現(xiàn)怎么怎么滴的時候請勇敢的懟回去。人家那些應(yīng)用廠商一般都默認打開權(quán)限的,這沒什么好說的,級別在那放著呢。
打開權(quán)限管理頁面的方法,不同版本有些差別,需適配下:
//打開系統(tǒng)消息通知設(shè)置頁面 Intent intent = new Intent(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//android 8.0引導(dǎo),引導(dǎo)到CHANNEL_ID對應(yīng)的渠道設(shè)置下intent.setAction(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);intent.putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName());intent.putExtra(Settings.EXTRA_CHANNEL_ID, newChannel); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//android 5.0-7.0,引導(dǎo)到所有渠道設(shè)置下(單個渠道沒有具體的設(shè)置)intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS);intent.putExtra("app_package", getContext().getPackageName());intent.putExtra("app_uid", getContext().getApplicationInfo().uid); } else {//其他intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);intent.setData(Uri.fromParts("package", getContext().getPackageName(), null)); }startActivity(intent);上面是一種解決方式,還有人說了,那我想任何時候用戶都能彈出橫幅通知呢,那就自己寫咯。大概思路就是用懸浮窗的方式展示一個Toast或者Dialog。
大概代碼如下:
private static void showHeadsUpNotification(Context context, UMessage uMessage) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//1、判斷是否開啟了懸浮通知欄權(quán)限 注:部分華為無效if (!Settings.canDrawOverlays(MyApplication.getInstance())) {MessageDialog.show((AppCompatActivity) ActivityUtils.getTopActivity(), "提示","請打開" + AppUtils.getAppName() + "的懸浮窗權(quán)限,否則會有很多重要消息漏掉哦!", "確定", "取消").setOnOkButtonClickListener(new OnDialogButtonClickListener() {@Overridepublic boolean onClick(BaseDialog baseDialog, View v) {//未顯示消息入隊headsupMsgQueue.offer(uMessage);requestOverlayPermission();return false;}}).setOnCancelButtonClickListener(new OnDialogButtonClickListener() {@Overridepublic boolean onClick(BaseDialog baseDialog, View v) {return false;}});} else {//顯示橫幅通知showHeadsUpNotification_(context, uMessage);}} }//請求懸浮窗權(quán)限 @TargetApi(Build.VERSION_CODES.M) private static void requestOverlayPermission() {Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);intent.setData(Uri.parse("package:" + AppUtils.getAppPackageName()));ActivityUtils.getTopActivity().startActivityForResult(intent, ALERT_WINDOW_PERMISSION_REQCODE); }public static void showHeadsUpNotification_(Context context) {if (headsupMsgQueue.isEmpty())return;//由于一開始沒有懸浮窗權(quán)限,所以當收到消息通知時先將他們暫時都存入隊列中,當獲得權(quán)限之后再顯示橫幅通知while (!headsupMsgQueue.isEmpty()) {UMessage uMessage = headsupMsgQueue.poll();if (uMessage != null) {showHeadsUpNotification_(context, uMessage);}} }private static void showHeadsUpNotification_(Context context, UMessage uMessage) {new Handler(Looper.getMainLooper()).post(() -> {//這里要看是否在子線程中再加// 傳入 Application 對象表示設(shè)置成全局的,但需要有懸浮窗權(quán)限new XToast<>(MyApplication.getInstance()).setView(R.layout.layout_headsup_notification)// 設(shè)置成可拖拽的//.setDraggable()// 設(shè)置顯示時長.setDuration(6000)// 設(shè)置動畫樣式//.setAnimStyle(android.R.style.Animation_Translucent)// 設(shè)置外層是否能被觸摸//.setOutsideTouchable(false)// 設(shè)置窗口背景陰影強度 // .setBackgroundDimAmount(0.5f).setGravity(Gravity.TOP).setText(R.id.notification_app_name, AppUtils.getAppName()).setText(R.id.notification_title, uMessage.title).setText(R.id.notification_text, uMessage.text).setOnClickListener(new XToast.OnClickListener<View>() {@Overridepublic void onClick(XToast<?> toast, View view) {// 點擊這個 View 后消失toast.cancel();if (uMessage.extra != null && uMessage.extra.containsKey("type") && uMessage.extra.containsKey("content")) {// 跳轉(zhuǎn)到某個ActivityIntent handleIntent = new Intent(context, NotifyActivity.class);toast.startActivity(handleIntent);}}}).show();});}代碼僅提供實現(xiàn)思路,不能直接運行,有需要還是結(jié)合自己的需求自己寫吧。
彈框可參考這兩個庫:
XPopup
XToast
最近一直搞這個通知,唉,系統(tǒng)升級版本越高權(quán)限控制是越來越嚴格了,有時候發(fā)現(xiàn)我們利用系統(tǒng)提供的能力無能為力的時候還是自己動手實現(xiàn)吧。
總結(jié)
以上是生活随笔為你收集整理的Android——横幅通知的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 王者荣耀手风琴
- 下一篇: 2.垃圾收集器与内存分配策略