Android实现3种Notification(状态栏通知)

Notification,是一种具有全局效果的通知,可以在系统的通知栏中显示。当 APP 向系统发出通知时,它将先以图标的形式显示在通知栏中。用户可以下拉通知栏查看通知的详细信息。下面会分别实现普通的通知,带自定义视图的通知,还有悬挂似的通知

3种方式开始前都要先执行下面这行代码:

1
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

普通通知

创建Builder对象,利用PendingIntent来跳转,然后给Builder添加各种属性。

完整的代码如下:

1
2
3
4
5
6
7
8
9
10
Notification.Builder builder = new Notification.Builder(this);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.appblog.cn"));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

builder.setContentIntent(pendingIntent);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
builder.setAutoCancel(true);
builder.setContentTitle("普通通知");
mNotificationManager.notify(1, builder.build());

带视图的通知

自定义视图有两种状态,一种是上面的效果图,即展开状态的视图;另一种是普通状态下的视图,需要我们手动的拉一下,折叠部分才会出来。带视图的通知需要用到RemoteViews创建视图

指定展开状态的视图:

1
notification.bigContentView = remoteViews;

普通状态视图:

1
notification.contentView = remoteViews;

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
Notification.Builder builder2 = new Notification.Builder(this);
Intent intent2 = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.appblog.cn"));
PendingIntent pendingIntent2 = PendingIntent.getActivity(this,0,intent2,0);
builder2.setContentIntent(pendingIntent2);
builder2.setSmallIcon(R.mipmap.ic_launcher);
builder2.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
builder2.setAutoCancel(true);
builder2.setContentTitle("折叠通知");

RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_view);
Notification notification = builder2.build();
notification.bigContentView = remoteViews;
mNotificationManager.notify(1, notification);

悬挂式的通知

悬挂式是Android 5.0以后的新特性,前两种需要手动拉通知栏,而这种方式不需要,直接就可以显示在屏幕上方

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Notification.Builder builder3 = new Notification.Builder(this);
Intent intent3 = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.appblog.cn"));
PendingIntent pendingIntent3 = PendingIntent.getActivity(this, 0, intent3, 0);
builder3.setContentIntent(pendingIntent3);
builder3.setSmallIcon(R.mipmap.ic_launcher);
builder3.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
builder3.setAutoCancel(true);
builder3.setContentTitle("悬挂通知");

Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(this, MainActivity.class);

PendingIntent pendingIntent3 = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
builder3.setFullScreenIntent(pendingIntent3, true);
mNotificationManager.notify(2, builder3.build());

附加:Android 5.0以后可以设置通知的等级

  • VISIBILITY_PUBLIC: 任何情况的显示
  • VISIBILITY_PRIVATE: 只有在没有锁屏时显示
  • VISIBILITY_SECRET: 在安全锁下或者没锁屏下显示

Android 5.0以后可以通过builder.setVisibility(Notification.VISIBILITY_PUBLIC);设置

Android状态栏通知

Android状态栏通知,兼容到Android 8.0以上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import android.annotation.SuppressLint;
import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.support.v4.app.NotificationCompat;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class NotificationUtil {

/**
* 默认的notification id
*/
private static final int DEFAULT_NOTIFICATION_ID = 5000;
/**
* notification id
*/
private static int notificationId = DEFAULT_NOTIFICATION_ID;

/**
* 获取新的notificationId
*
* @return
*/
public static int getNewNotificationId() {
notificationId++;
return notificationId;
}

public static void pushNotify(Context context, NotifyMessage notifyMessage) {
if (context == null || notifyMessage == null) {
return;
}

Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.putExtra("pushReciveMessage", notifyMessage);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 9001, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

notify(context, getNewNotificationId(), notifyMessage, pendingIntent);
}

public static void notify(Context context, int notificationId, NotifyMessage notifyMessage, PendingIntent pendingIntent) {
if (context == null || notifyMessage == null) {
return;
}

int appLogoResId = R.drawable.app_logo;
String appName = Util.getAppName(context);
if (Util.isEmpty(notifyMessage.getTitle())) {
notifyMessage.setTitle(appName);
}

NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //Android 8.0
String channelId = context.getPackageName();
NotificationChannel mChannel = new NotificationChannel(channelId, appName, NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(mChannel);
Notification.Builder builder = new Notification.Builder(context, channelId)
.setSmallIcon(appLogoResId)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), appLogoResId))
.setTicker(notifyMessage.getContent())
.setContentTitle(notifyMessage.getTitle())
.setContentText(notifyMessage.getContent())
.setAutoCancel(true);
if (pendingIntent != null) {
builder.setContentIntent(pendingIntent);
}
notification = builder.build();
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(appLogoResId)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), appLogoResId))
.setTicker(notifyMessage.getContent())
.setContentTitle(notifyMessage.getTitle())
.setContentText(notifyMessage.getContent())
.setAutoCancel(true);
if (pendingIntent != null) {
builder.setContentIntent(pendingIntent);
}
notification = builder.build();
}
notificationManager.notify(notificationId, notification);
}

/**
* 取消所有的notification
*
* @param context
*/
public static void cancelAll(Context context) {
if (notificationId != DEFAULT_NOTIFICATION_ID) {
notificationId = DEFAULT_NOTIFICATION_ID;
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancelAll();
}
}

/**
* 通知的权限校验
*
* @param context
*/
public static void checkNotification(Context context) {
if (!isNotificationEnabled(context)) {
if (GlobalSimpleSP.getIsNeedCheckNotification(context)) {
PermissionUtils.openSystemSetting(context, "当前应用需要消息通知");
GlobalSimpleSP.storeNeedCheckNotification(context, false);
}
}
}

@SuppressLint("NewApi")
public static boolean isNotificationEnabled(Context context) {
try {
Class appOpsClass = Class.forName(AppOpsManager.class.getName());
Method checkOpNoThrowMethod = appOpsClass.getMethod("checkOpNoThrow", Integer.TYPE, Integer.TYPE, String.class);
Field opPostNotificationValue = appOpsClass.getDeclaredField("OP_POST_NOTIFICATION");

AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
int value = (Integer) opPostNotificationValue.get(Integer.class);
int uid = context.getApplicationInfo().uid;
String pkg = context.getApplicationContext().getPackageName();

return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) == AppOpsManager.MODE_ALLOWED);
} catch (NoClassDefFoundError e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
}

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2020 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :