1.0 通知(Notification),这个内容网上可以找到很多介绍,但是:
- 要么都没有更新到
Android O(API 26,Android 8)
系统以上. - 要么篇幅太短,打油诗级别的介绍
- 要么一篇博文全部怼完,乱七八糟不说,理解起来不知道从哪捋思路。
- 也因为
Android
版本更新的原因,一些方法被弃用,导致现如今网上的很多关于 通知(Notification
)的代码无法顺利编译,或者用Android studio编写时,方法上已经划横线了。 - 事实上面对国内各种深度定制的
Android系统
,通知(Notification
)可能存在其他乱七八糟的缺陷
备注:所以,本篇更新至今天,最新版本(2019-02-21)
2.0 本篇主要是通过一个简单的项目实现顺利地发出一条状态栏通知,会尽量在项目中精简代码,将系统性的理论知识放最后分类补充。
可参考文章:
链接:Android Notification 详解
链接:# Android 通知栏Notification的整合全面学习
链接:Android通知栏(Notification)介绍及使用
3.0 新建一个项目,Notificationtest,目录如下:
备注:为什么不把源代码上传到Gittub
?因为Android编程
的尿性,更新换代很快,今天能运行的代码,明天不一定能跑得起来(而且配置文件超多)。所以习惯性展示目录和代码,可以避免某些参考时可能存在的版本兼容问题。
4.0 布局文件中就一个控件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/send_notice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送通知"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.05" />
</android.support.constraint.ConstraintLayout>
5.0 划线的重点来了,需要解决新版本的兼容问题
由于升级到Android O
(安卓欧,不是安卓零)版本后,一些方法被弃用,而且Android O
引入了通知渠道(Notification Channels
),以提供统一的系统来帮助用户管理通知,如果是针对 android O 为目标平台时,必须实现一个或者多个通知渠道(就是要new NotificationChannel()
),以向用户显示通知。比如聊天软件,为每个聊天组设置一个通知渠道,指定特定声音、灯光等配置。
6.0 先解决状态栏通知显示
需要干什么,再解决考虑到Android O
版本还需要做什么。
6.1 通知显示需要3步走:
- 1.第1步:获取状态通知栏管理:
- 2.第2步:实例化通知栏构造器
NotificationCompat.Builder
- 3第3步:对
Builder
进行配置:
(第3步和第2步之间本来还有1步的,但是不是必要,放下一章讲解——通知栏点击事件处理)
6.1.1 状态栏通知的管理类 NotificationManager
,负责发通知、清除通知等操作。
注意:NotificationManager
是一个系统Service,
所以必须通过 getSystemService (NOTIFICATION_SERVICE)
方法来获取。
6.1.2 实例化通知栏构造器通过声明Notification
类
一个 Notification
的必要属性有三项,如果不设置则在运行时会抛出异常:
- 小图标,通过
setSmallIcon()
方法设置 - 标题,通过
setContentTitle()
方法设置 - 内容,通过
setContentText()
方法设置
除了这3种还有:
-
setWhen()
通知产生的时间。会在通知信息里显示,通常是系统获取到的时间:setWhen( System.currentTimeMillis() )
-
setLargeIcon()
设置通知大ICON -
setPriority
设置通知优先级 -
setOngoing(false)
设置它为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接) -
setNumber( )
设置通知集合的数量 -
setStyle( )
设置 -
setAutoCancel(true)
设置这个标志当用户单击面板就可以让通知将自动取消(手机QQ
就是设置成false
,所以你在通知栏总是取消不掉它) -
setTicker( )
设置通知首次出现在通知栏,带上升动画效果的 -
setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL))
设置设置通知栏点击意图 -
setDefaults(int defualts)
为了精简学习难度,Notification
的通知效果知识点本章不写。(通过setDefaults(int defualts)
方法来设置。一旦设置了Default
效果,自定义的效果就会失效。Default
效果可以相互组合)
6.1.3 第3步,只需要调用
NotificationManager
的notify()
方法就可以让通知显示出来。
notify()
方法接收2个参数:
- 第一个参数是
id
,保证每个通知的id都是不一样的。 - 第二个参数是指
Notification对象
,将第二步建好的Notification对象
传入即可。这样显示一个通知就可以写成:
NotificationManager manager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = null;
...
manager.notify(1, notification);
OK,理论讲完,继续往下走
7.0 综合上面理论知识,下面MainActivity.java
中的代码,看懂就没什么大问题了。
package com.example.notificationtest;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private String id = "channel_001";
private String name = "name";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendNotice = (Button) findViewById(R.id.send_notice);
sendNotice.setOnClickListener(this);
}
@RequiresApi(api =26)
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.send_notice:
//第一步:获取状态通知栏管理:
NotificationManager manager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = null;
//第二步:实例化通知栏构造器NotificationCompat.Builder:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//判断API
NotificationChannel mChannel = new NotificationChannel(id, name,
NotificationManager.IMPORTANCE_LOW);
manager.createNotificationChannel(mChannel);
notification = new NotificationCompat.Builder(this, id)
.setContentTitle("这是一个内容标题")//设置通知栏标题
.setContentText("这是一个内容文本") //设置通知栏显示内容
.setWhen(System.currentTimeMillis())//通知产生的时间。
// 会在通知信息里显示,通常是系统获取到的时间
.setSmallIcon(R.mipmap.ic_launcher)//设置通知小ICON
.setLargeIcon(BitmapFactory.decodeResource(getResources()
, R.mipmap.ic_launcher))//设置通知大ICON
.build();
} else {
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, id)
.setContentTitle("这是一个内容标题")
.setContentText("这是一个内容文本")
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources()
, R.mipmap.ic_launcher));
// .setOngoing(true);
notification = notificationBuilder.build();
}
//第三步:对Builder进行配置:
manager.notify(1, notification);
break;
default:
break;
}
}
}
需要注意的两个方面:
- 用的实现
implements
关键字实现监控的接口,这是因为在经常用的内部类中,用NotificationCompat.Builder(Context context, String channelId)
报错…… - 网上代码基本都是用
NotificationCompat.Builder(Context context)
方法,但这个方法已经弃用,最新版本NotificationCompat.Builder(Context context, String channelId)
,channelId
在一开始就随便申明一个就好…… - 关于解决
Android O
兼容性问题,看9.0
8.0 解决Android O版本
兼容性问题(好吧,本来想放在6.2
的):在Android 8版本及以上
按网上大部分的代码来写,是不会显示状态栏通知的。
需要用到如上代码中if语句
来处理,记得声明@RequiresApi(api =26)
。
下面开始解释下这个逻辑,把上面MainActivity.java
中if语句
代码抄下来如下所示:
//如果当前Android的版本相比Android O,一样或者版本更高,就建通知渠道(Notification Channels )
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//判断API
//1.0 建渠道
NotificationChannel mChannel = new NotificationChannel(id, name,
NotificationManager.IMPORTANCE_LOW);
//2.0 把通知渠道通过createNotificationChannel( )方法给-
// -状态栏通知的管理类 NotificationManager
manager.createNotificationChannel(mChannel);
//3.0 Notification这时候可以正常工作了
notification = new NotificationCompat.Builder(this, id)
.setContentTitle("这是一个内容标题")//设置通知栏标题
.setContentText("这是一个内容文本") //设置通知栏显示内容
.setWhen(System.currentTimeMillis())//通知产生的时间。
// 会在通知信息里显示,通常是系统获取到的时间
.setSmallIcon(R.mipmap.ic_launcher)//设置通知小ICON
.setLargeIcon(BitmapFactory.decodeResource(getResources()
, R.mipmap.ic_launcher))//设置通知大ICON
.build();
} else {
//如果当前Android的版本比Android O(API 26)版本要低
//直接开始上面的3.0步骤——Notification这时候就可以正常工作了
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, id)
.setContentTitle("这是一个内容标题")
.setContentText("这是一个内容文本")
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources()
, R.mipmap.ic_launcher));
// .setOngoing(true);
notification = notificationBuilder.build();
//为什么if语句里面两个3.0不一样
// notification =
// new NotificationCompat.Builder(this, id)
// .setContentTitle("这是一个内容标题")
// .setContentText("这是一个内容文本")
// .setSmallIcon(R.mipmap.ic_launcher)
// .setLargeIcon(BitmapFactory.decodeResource(getResources()
// , R.mipmap.ic_launcher)).build();
//这几行代码就一样了。
}
如上。
9.0 执行项目(如果你的手机系统版本是Android 8.0.0版本
及以上,建议用真机测试,真机测试更自信):
现在Android 9.0.0(API 28)模拟器
运行:
点击“发送通知”按钮,最上方标题栏出现一个小白点:
下拉状态栏,查看:
接下来在Android 7.0.0(API 24)模拟器
运行:
点击“发送通知”按钮,最上方标题栏出现一个小白点:
下拉状态栏,查看:
10.0 如果你使用的是Android手机,此时应该会下意识地认为这条通知是可以点击的。
但你去点击的时候,你会发现没有任何效果。它是不会因为你可能是中国人就给你面子的……
可以参考我的下一篇:
链接:【Android】24.0 手机多媒体(二)——通知(Notification)(2):状态栏通知点击事件处理
END