Android 8.0系统的通知栏适配

news/2025/3/28 9:13:02/文章来源:https://www.cnblogs.com/cxeye/p/18791122

为什么要进行通知栏适配?
现在经常是早上一觉醒来拿起手机一看,通知栏上全是各种APP的推送,烦。随着智能手机发展的成熟,通知栏搞得越来越不讨人喜欢了。各个App都希望抢占通知栏的空间,来尽可能地销售自己的产品。

通知栏是Android系统原创的,虽说乔布斯一直认为Android系统是彻底抄袭iOS的一个产品,苹果在iOS 5之后也抄袭了Android的通知栏。

通知栏的设计巧妙,它不占用屏幕空间,只有当用户需要的时候用手指在状态栏上向下滑动,通知栏的内容才会显示出来,在智能手机发展的初期解决了手机屏幕小,内容展示不足的问题。

从Android 8.0系统开始,Google引入了通知渠道这个概念。
什么是通知渠道呢?顾名思义,就是每条通知都要属于一个对应的渠道。每个App自由创建通知渠道,但这些通知渠道的控制权都是掌握在用户手上。用户随便设置通知渠道的重要程度,是否响铃、是否振动、或者是否要关闭这个渠道的通知。

举个例子,我希望立马收到支付宝的收款信息,因为不想错过每笔钱,但是又不想收到支付宝给我推荐的周围美食,因为我没钱去大饭店。这种情况,支付宝就可以创建两种通知渠道,一个收支,一个推荐,而我作为用户对推荐类的通知讨厌,那么我直接把推荐通知渠道关闭,这样不影响我关心的通知,又不会让那些我不关心的通知来打扰我了。

我一定要搞适配吗?
Google这次对于8.0系统通知渠道的态度硬硬的。如果你升级了AppCompat库,所有使用AppCompat库来构建通知的地方全部会进行废弃方法提示

Google也并没做绝,即使方法标为废弃,还是可以凑合用。可是如果你将项目中的targetSdkVersion指定到了26或者更高,Android系统认为APP已经做好了8.0系统的适配工作,当然包括了通知栏的适配。这个时候不使用通知渠道,你App的通知将不弹出。

那么现在开始我们就正式来学习一下如何进行8.0系统中通知栏的适配。

创建通知渠道
首先我们使用Android Studio来新建一个项目,就叫它NoticationChannel

创建好项目,打开app/build.gradle文件检查一下,targetSdkVersion已经指定到了26或者更高,如下:

android {compileSdkVersion 28buildToolsVersion "28.0.0"defaultConfig {applicationId "com.example.noticationchannel"minSdkVersion 21targetSdkVersion 28versionCode 100versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}
}public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void sendChatMsg(View view) {NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {String channelId = "chat";String channelName = "聊天消息";int importance = NotificationManager.IMPORTANCE_HIGH;NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);notificationManager.createNotificationChannel(channel);}Notification notification = new NotificationCompat.Builder(this, "chat").setContentTitle("来了吧,小伙子 聊天消息").setContentText("中午吃点啥呢?").setWhen(System.currentTimeMillis()).setSmallIcon(R.mipmap.ic_launcher).setAutoCancel(true).build();manager.notify(1, notification);}public void sendSubscribeMsg(View view) {if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {String channelId = "subscribe";String channelName = "订阅消息";int importance = NotificationManager.IMPORTANCE_DEFAULT;NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);notificationManager.createNotificationChannel(channel);}NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);Notification notification = new NotificationCompat.Builder(this, "subscribe").setContentTitle("来了吧,小伙子 订阅消息").setContentText("房子便宜卖啦,有要买的吗!").setWhen(System.currentTimeMillis()).setSmallIcon(R.mipmap.ic_launcher_round).setAutoCancel(true).build();manager.notify(2, notification);}public void cancelChatMsg(View view) {NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);manager.cancel(1);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {manager.deleteNotificationChannel("chat");}}public void cancelSubscribeMsg(View view) {NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);manager.cancel(2);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {manager.deleteNotificationChannel("chat");}}}
下面我们就来让通知显示出来首先修改activity_main.xml中的代码,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="60dp"android:gravity="center_horizontal"android:orientation="horizontal"><androidx.appcompat.widget.AppCompatButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="sendChatMsg"android:text="发送聊天消息" /><androidx.appcompat.widget.AppCompatButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="cancelChatMsg"android:text="取消聊天消息" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="60dp"android:gravity="center_horizontal"android:orientation="horizontal"><androidx.appcompat.widget.AppCompatButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="sendSubscribeMsg"android:text="发送订阅消息" /><androidx.appcompat.widget.AppCompatButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="cancelSubscribeMsg"android:text="取消订阅消息" /></LinearLayout></LinearLayout>

想象一下我们正在开发类似于微信的APP,其中APP通知主要分为两类,一类是聊天消息,这类消息非常重要,因此重要等级设为了IMPORTANCE_HIGH。另一类公众号订阅消息,这类消息不那么重要,重要等级+我设为了IMPORTANCE_DEFAULT。当然,重要等级还可以设置为IMPORTANCE_LOW、+IMPORTANCE_MIN,分别对应更低的通知重要程度。

代码不长,要确保的是当前手机的系统版本必须是Android 8.0系统或者更高,低版本的手机系统没有通知渠道功能,不做系统版本检查会在低版本手机上造成崩溃。

创建通知渠道很简单,需要注意的是,创建一个通知渠道需要渠道ID、渠道名称以及重要等级这三个参数,其中渠道ID随便写,只要保证全局独一份就可以。渠道名称是给用户看的,要能够表达清楚这个渠道的用途。等级不同决定通知行为不同,这里只是初始状态下的等级,用户随时更改渠道的等级,APP 无法干预。

现在运行一下代码了,运行成功之后,点击发送聊天消息,点击发送订阅消息,状态栏上会有通知小图标,用手指在状态栏上向下滑动,如下图所示:

 刚才我们创建两个通知渠道已经显示出来了。由于这两个通知渠道的重要等级不同,通知的行为也是不同的,聊天消息可以发出在屏幕上弹出通知,而订阅消息不会弹出通知。

当然,用户还可以点击进去对该通知渠道进行任意的修改,比如降低聊天消息的重要等级,甚至是可以完全关闭该渠道的通知。

管理通知渠道
通知渠道一旦创建就不能再通过代码修改了。为此,Android赋予了开发者读取通知渠道配置的权限,如果某个功能必须配置通知渠道才能使用,可以提示用户手动更改通知渠道配置。

概念总是抽象,我们还是通过具体例子来实象。想象我们开发的是一个类似于微信的APP,聊天消息是重要地,如果用户将聊天消息的通知渠道关闭了,所有重要聊天通知全部都丢了,为此我们一定要保证用户打开了聊天消息通知渠道才行。

修改MainActivity中的代码

public void sendChatMsg(View view) {NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {NotificationChannel channel = manager.getNotificationChannel("chat");if (channel != null && channel.getImportance() == NotificationManager.IMPORTANCE_NONE) {Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());intent.putExtra(Settings.EXTRA_CHANNEL_ID, channel.getId());startActivity(intent);Toast.makeText(this, "请手动将通知打开", Toast.LENGTH_SHORT).show();}}......
}

这里我们对sendChatMsg()方法进行了修改,通过getNotificationChannel()方法获取到了NotificationChannel对象,如果为null,没有设置通知渠道,否则就可以读取该通知渠道下的所有配置了。这里我们判断如果通知渠道的importance等于IMPORTANCE_NONE,就说明用户将该渠道的通知给关闭了,这时会跳转到通知的设置界面提醒用户手动打开。

1 当聊天消息的通知渠道关闭后,下次再次发送聊天消息直接跳转到通知设置界面,提醒用户手动将通知打开。
2 除了以上管理通知渠道的方式之外,Android 8.0还赋予了我们删除通知渠道的功能,只需使用如下代码即可删除:
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.deleteNotificationChannel(channelId);

文章中的示例源码点击 https://github.com/githubwwj/NoticationChannel下载



作者:as_pixar
链接:https://www.jianshu.com/p/ca15907474b3
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
 
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/905395.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

日事清25年战略目标如何高效执行?企业组织架构优化与项目管理全流程解析

如何使用日事清搭建一份可实现的25年战略目标-执行体系?在这个快节奏的商业世界里,每个企业都需要弄清楚几个超重要的问题: 首先,你的企业使命和抱负够不够清晰 ——能不能让每一个员工充满归属感和使命感? 然后,你们团队有没有一个明确的目标体系?还是只是在“摸着石头…

Obsidian 笔记一键转换发布为 Jekyll 博客

Obsidian 是一款功能强大且灵活的知识管理和笔记软件,与 Jekyll 这一轻量级静态博客框架的结合,既能保留 Obsidian 的网状知识关联优势,又能借助 Jekyll 的高效编译能力快速生成标准化博文。 Obsidian 笔记自动转换为 Jekyll 博客一文介绍了如何把挑选出的 Obsidian 笔记转换…

变更《营业执照》操作流程

第一步:打开甘肃政务服务网 https://zwfw.gansu.gov.cn/ 第二步:登录 (1)右上角(2)点“法人登录”(3)点“电子营业执照登录”第三步:使用【电子营业执照】的【扫一扫】进行登录 (1)打开法人的手机微信,在微信中搜索“电子营业执照小程序”(2)点击“扫一扫”(3)…

DVWA靶场安装教程

1 靶场下载github 下载 https://github.com/digininja/DVWAgithub网站在国外,有时不能访问,可以下载我分享的这个:百度网盘分享 https://pan.baidu.com/s/1vIsf_VFiY9Ah3DG3Ichsyg?pwd=zyvf 2 靶场部署 2.1 解压缩靶场 解压缩后,只保留DVWA-master文件夹,里面是靶场代码…

leaflet框选范围下载地图离线瓦片:以高德地图为例(附源码下载)

demo源码运行环境以及配置运行环境:依赖Node安装环境,demo本地Node版本:14.19.1。 运行工具:vscode或者其他工具。 配置方式:下载demo源码,vscode打开,然后顺序执行以下命令: (1)下载demo环境依赖包命令:npm i (2)启动Node后端接口命令:node nodeServer.js (3)打…

Python 也能做前端?用 Streamlit + LangChain 搭建 AI Chat 应用!

项目成果 使用 LangChain 处理对话逻辑,包括消息存储、上下文管理。 使用 Streamli项目成果使用 LangChain 处理对话逻辑,包括消息存储、上下文管理。 使用 Streamlit 构建前端 UI,实现流式输出对话体验。 调用 OpenAI API 进行智能问答,使 AI 能够自然交互。 支持对话历史…

春雨

在某一瞬间抛下了自己的灵魂,任由祂对着死去的肉体宣泄、嘶吼、哀悼。 折断笔不去书写过往,可回想的每一刻都值得记录。 工作、学习、人际关系、比赛、生活, 或者说焦虑、压力、责任、情感、不甘, 为什么不想想,把生活放到第一位。 在这苦难中,对知识的渴望和情感的向往刺…

leetcode每日一题:对角线上不同值的数量差

题目 2711. 对角线上不同值的数量差 给你一个下标从 0 开始、大小为 m x n 的二维矩阵 grid ,请你求解大小同样为 m x n 的答案矩阵 answer 。 矩阵 answer 中每个单元格 (r, c) 的值可以按下述方式进行计算:令 topLeft[r][c] 为矩阵 grid 中单元格 (r, c) 左上角对角线上 不…

Linux基本功

知识来源:B站-尚硅谷-武晟然 https://www.bilibili.com/video/BV1WY4y1H7d3/?spm_id_from=333.337.search-card.all.click&vd_source=d9e91669cbb2a200e91188c38bf38a7a 第01章_常用基本命令 ​ Shell 可以看作是一个命令解释器,为我们提供了交互式的文本控制台界面。我…

宝塔部署的Java项目通过域名无法访问问题

背景 1.域名已经绑定IP 2.端口已经开放,宝塔和云服务器的端口设置都开放 3.测试通过公网IP:port可以访问 4.通过域名:port不可以访问 猜测1: Java 项目未绑定到0.0.0.0 Java 项目默认监听 127.0.0.1(仅允许本地访问),无法通过公网 IP 或域名访问。 解决方案:启动 Java 项目…

知识库管理:全流程智能化中枢,驱动企业信息资产高效流转

思通数科智能系统的知识库管理模块,以多模态数据管理为基础,深度融合AI技术与精细化流程控制,构建从内容创建、智能分类到版本追溯的全生命周期管理体系,助力企业实现知识资产的安全存储、高效利用与持续优化。以下是核心功能详解: 一、多模态数据统一存储:打破信息孤岛,…

IPD流程中的风险管理与应对方法

IPD(Integrated Product Development)流程即集成产品开发流程,是一套产品开发的模式、理念与方法。它强调将产品开发视为一个完整的流程,涵盖从市场需求分析、产品规划、设计开发到产品上市及后续维护等各个环节。在当今复杂多变的商业环境中,IPD流程对于企业提升产品竞争…