3.0 新建一个项目,Notificationtest,目录如下:
2019-02-21_165013.png
备注:为什么不把源代码上传到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()
设置通知大ICONsetPriority
设置通知优先级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)模拟器
运行:
2019-02-21_195725.png
点击“发送通知”按钮,最上方标题栏出现一个小白点:
2019-02-21_195731.png
下拉状态栏,查看:
2019-02-21_195737.png
接下来在Android 7.0.0(API 24)模拟器
运行:
2019-02-21_195831.png
点击“发送通知”按钮,最上方标题栏出现一个小白点:
2019-02-21_195837.png
下拉状态栏,查看:
2019-02-21_195844.png
作者:我睡醒刚刚
链接:https://www.jianshu.com/p/556acaf2195c