通知概览
通知是指 Android 在应用的界面之外显示的消息,旨在向用户提供提醒、来自他人的通信信息或应用中的其他实时信息。用户可以点按通知来打开应用,也可以直接在通知中执行某项操作。
目前通知在安卓系统上应用广泛,可以在不同的位置以不同的格式显示,例如,状态栏中的图标、抽屉式通知栏中比较详细的条目、应用图标上的标志,以及在配对的穿戴式设备上自动显示。
在安卓8.0之后,谷歌引入了Channel(渠道)的概念,将不同的信息根据消息的类型推送到相应的渠道,这样做可以可以做到消息的分类,比如我使用支付宝,我希望收到收钱到账的消息推送,而不希望收到支付宝给我推送商品推荐的消息,这个时候由于这两两种消息处于不同的渠道,我关闭商品推送的渠道即可。
在安卓官方开发文档中的最后面有如下的说明:
Android 8.0,API 级别 26
- 现在必须将各个通知放入特定渠道中。
- 现在,用户可以按渠道关闭通知,而非关闭来自某个应用的所有通知。
- 包含有效通知的应用将在主屏幕/启动器屏幕上相应应用图标的上方显示通知“标志”。
- 现在,用户可以从抽屉式通知栏中暂停某个通知。您可以为通知设置自动超时时间。
- 您还可以设置通知的背景颜色。
- 部分与通知行为相关的 API 从
Notification
移至了NotificationChannel
。例如,在搭载 Android 8.0 及更高版本的设备中,使用NotificationChannel.setImportance()
,而非NotificationCompat.Builder.setPriority()
。
我相信在看第一行代码Android第2版的同学都无法实现书中的使用通知案例,并且会发现如下使用出现的横杠:
- Notification notification = new
NotificationCompat.Builder(this);
点上去看,出现"Builder(android.content.Context)' is deprecated
因为从8.0开始需要使用带有channelld的函数,即
- Notification notification = new NotificationCompat.Builder(this, "chat");
改造书中的代码如下:
AndroidMainfest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.notificationtest">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".NotificationActivity"></activity>
<activity android:name=".MainActivity"
tools:ignore="Instantiatable">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml中使用LinearLayout,并添加了三个按钮,其中第二个和第三个按钮和本次实验相关,一个用于发送聊天信息,一个用于发送订阅消息。
<?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"
android:padding="10dp">
<Button
android:id="@+id/send_notice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send notice" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送聊天消息"
android:onClick="sendChatMsg" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送订阅消息"
android:onClick="sendSubscribeMsg" />
</LinearLayout>
MainActivity中的代码,见名知意,不清楚的参见第一行代码相关内容或者本博客的参考资料
package com.example.notificationtest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//版本大于等于 26
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelId = "chat";
String channelName = "聊天消息";
int importance = NotificationManager.IMPORTANCE_HIGH;
createNotificationChannel(channelId, channelName, importance);
channelId = "subscribe";
channelName = "订阅消息";
importance = NotificationManager.IMPORTANCE_DEFAULT;
createNotificationChannel(channelId, channelName, importance);
}
}
@TargetApi(Build.VERSION_CODES.O)
private void createNotificationChannel(String channelId, String channelName, int importance) {
NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
channel.setShowBadge(true);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
}
public void sendChatMsg(View view) {
Intent intent = new Intent(this, NotificationActivity.class);
PendingIntent pdIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this, "chat")
.setContentTitle("收到一条聊天消息")
.setContentText("今天中午吃什么?")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.notification)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.big_image))
.setContentIntent(pdIntent)
.setAutoCancel(true)
.build();
manager.notify(1, notification);
}
public void sendSubscribeMsg(View view) {
Intent intent = new Intent(this, NotificationActivity.class);
PendingIntent pdIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this, "subscribe")
.setContentTitle("收到一条订阅消息")
.setContentText("Macbook pro大降价!")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.notification)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.big_image))
.setContentIntent(pdIntent)
.setAutoCancel(true)
.setNumber(2)
.build();
manager.notify(2, notification);
}
}
notification_layout中的代码,创建一个TextView显示一些信息,用于点击消息时候的跳转到本页面
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".NotificationActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="24sp"
android:text="This is notification layout"
/>
</RelativeLayout>
NotificationActivity中的代码,注释的代码是因为点击通知后需要将通知取消,在MainActivity中的.setAutoCancel(true)可替代这段代码,因此 import android.app.NotificationManager; 可以去掉,考虑到有的同学会打开注释,或者使用它,就不删除了。
package com.example.notificationtest;
import androidx.appcompat.app.AppCompatActivity;
import android.app.NotificationManager;
import android.os.Bundle;
public class NotificationActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.notification_layout);
// NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// manager.cancel(1);
// manager.cancel(2);
}
}
运行结果:
随便点一个通知,进入如下界面,然后通知栏清除该通知
说明:
如果出现图片相关的错误而运行不了,是因为以上程序中使用了两张自己导入的图片,我将图片放在这里,按需获取
big_image.jpg
notification.png
参考资料:
1、https://www.jianshu.com/p/559c30cdeed0
2、https://developer.android.com/guide/topics/ui/notifiers/notifications?hl=zh-cn
3、第一行代码