Android使用Notification通知栏功能的封装
在Android应用开发中我们经常会使用到通知栏的功能,安卓的通知栏有多种类型样式,包括基本类型、带进度条的类型、大图标类型、大段文本类型等,在Android 8.0 (API level 26) 中使用通知栏的代码示例:
// Create an explicit intent for an Activity in your appIntent intent = new Intent(this, AlertDetails.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) // Set the intent that will fire when the user taps the notification .setContentIntent(pendingIntent) .setAutoCancel(true);NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);// notificationId is a unique int for each notification that you must definenotificationManager.notify(notificationId, builder.build());
以下会对notification的使用做一个简单的封装,具体的功能逻辑还可以再扩展
先看一下具体的使用:
package com.windfallsheng.mynotificationmanager;import android.app.PendingIntent;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.TextView;import com.windfallsheng.mynotificationmanager.notification.DefaultNotifyBuilder;import com.windfallsheng.mynotificationmanager.notification.NotifyManager;public class MainActivity extends AppCompatActivity implements View.OnClickListener { private final String TAG = MainActivity.class.getSimpleName(); TextView tvImMsg, tvSysMsg; private String userArray[] = {"Cyra", "Morgen", "Iris", "Mia"}; private String messageArray[] = {"我发表了新的美食文章", "我更新了我的相册", "我在FaceBook申请了账号", "我做了一个好看的小视频"}; private String sysMessageArray[] = {"有新的系统版本可以升级", "收到新的资讯内容", "为你推荐周边美食、娱乐活动", "最新最火爆的游戏"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvImMsg = findViewById(R.id.textview_im_msg); tvSysMsg = findViewById(R.id.textview_sys_msg); tvImMsg.setOnClickListener(this); tvSysMsg.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.textview_im_msg: notifyImMessage(); break; case R.id.textview_sys_msg: notifySysMessage(); break; default: break; } } private void notifyImMessage() { int uIndex = (int) (Math.random() * userArray.length); int mIndex = (int) (Math.random() * messageArray.length); String userName = userArray[uIndex]; String content = messageArray[mIndex]; String key = "ImMessage#" + userName; int requestCode = NotifyManager.getInstance(MainActivity.this).initNotifyId(key); Log.d(TAG, "method:notifyReceivedMessage#key=" + key + ", requestCode=" + requestCode); Intent intent = new Intent(MainActivity.this, NotificationMsgActivity.class); intent.putExtra("msgContent", userName + ":\n\n" + content); PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); DefaultNotifyBuilder defaultNotifyBuilder = new DefaultNotifyBuilder(userName, content) .setChannelId(getResources().getString(R.string.channel_001)) .setContentIntent(pendingIntent); NotifyManager.getInstance(MainActivity.this).showDefaultNotification(key, defaultNotifyBuilder); } private void notifySysMessage() { String key = "SysMessage#系统消息"; int mIndex = (int) (Math.random() * sysMessageArray.length); String content = sysMessageArray[mIndex]; int requestCode = NotifyManager.getInstance(MainActivity.this).initNotifyId(key); Log.d(TAG, "method:notifyReceivedMessage#key=" + key + ", requestCode=" + requestCode); Intent intent = new Intent(MainActivity.this, NotificationMsgActivity.class); intent.putExtra("msgContent", "系统消息" + ":\n\n" + content); PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); DefaultNotifyBuilder defaultNotifyBuilder = new DefaultNotifyBuilder("系统消息", content) .setChannelId(getResources().getString(R.string.channel_002)) .setContentIntent(pendingIntent); NotifyManager.getInstance(MainActivity.this).showDefaultNotification(key, defaultNotifyBuilder); }}
DefaultNotifyBuilder中有一些参数会有默认值:
package com.windfallsheng.mynotificationmanager.notification;import android.app.PendingIntent;import android.support.v4.app.NotificationCompat;import com.windfallsheng.mynotificationmanager.R;/** * @author lzsheng */public class DefaultNotifyBuilder { public String channelId; public int smallIcon = R.drawable.ic_launcher_foreground; public CharSequence contentTitle = "小蜗牛Tech"; public CharSequence contentText; public CharSequence ticker; public int flag = NotificationCompat.FLAG_AUTO_CANCEL; public int priority = NotificationCompat.PRIORITY_HIGH; public long when = System.currentTimeMillis(); public PendingIntent contentIntent; public boolean autoCancel = true; public boolean sound; public boolean vibrate; public boolean lights; public DefaultNotifyBuilder(CharSequence contentText) { this.contentText = contentText; } public DefaultNotifyBuilder(CharSequence contentTitle, CharSequence contentText) { this.contentTitle = contentTitle; this.contentText = contentText; } public DefaultNotifyBuilder(int smallIcon, CharSequence contentTitle, CharSequence contentText) { this.smallIcon = smallIcon; this.contentTitle = contentTitle; this.contentText = contentText; } public DefaultNotifyBuilder setChannelId(String channelId) { this.channelId = channelId; return this; } public DefaultNotifyBuilder setTicker(CharSequence ticker) { this.ticker = ticker; return this; } public DefaultNotifyBuilder setFlag(int flag) { this.flag = flag; return this; } public DefaultNotifyBuilder setPriority(int priority) { this.priority = priority; return this; } public DefaultNotifyBuilder setWhen(long when) { this.when = when; return this; } public DefaultNotifyBuilder setContentIntent(PendingIntent contentIntent) { this.contentIntent = contentIntent; return this; } public DefaultNotifyBuilder setAutoCancel(boolean autoCancel) { this.autoCancel = autoCancel; return this; } public DefaultNotifyBuilder setSound(boolean sound) { this.sound = sound; return this; } public DefaultNotifyBuilder setVibrate(boolean vibrate) { this.vibrate = vibrate; return this; } public DefaultNotifyBuilder setLights(boolean lights) { this.lights = lights; return this; }}
BaseNotifyBuilder会对基本的参数进行组装:
package com.windfallsheng.mynotificationmanager.notification;import android.app.Notification;import android.app.PendingIntent;import android.content.Context;import android.os.Build;import android.support.annotation.NonNull;import android.support.v4.app.NotificationCompat;import android.text.TextUtils;import android.util.Log;/** * @author lzsheng */public class BaseNotifyBuilder { private static final String TAG = BaseNotifyBuilder.class.getSimpleName(); protected DefaultNotifyBuilder defaultBuilder; protected NotificationCompat.Builder notifyBuilder; public BaseNotifyBuilder(@NonNull DefaultNotifyBuilder defaultBuilder) { if (defaultBuilder == null) { throw new IllegalArgumentException("defaultNotifyBuilder = null."); } this.defaultBuilder = defaultBuilder; } public Notification build(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { notifyBuilder = new NotificationCompat.Builder(context, defaultBuilder.channelId); } else { notifyBuilder = new NotificationCompat.Builder(context); } Log.d(TAG, "method:build#defaultBuilder=" + defaultBuilder); // 设置顶部状态栏的小图标 notifyBuilder.setSmallIcon(defaultBuilder.smallIcon); // 设置通知中心的标题 notifyBuilder.setContentTitle(defaultBuilder.contentTitle); // 设置通知中心中的内容 CharSequence contentText = defaultBuilder.contentText; if (!TextUtils.isEmpty(contentText)) { notifyBuilder.setContentText(defaultBuilder.contentText); } PendingIntent contentIntent = defaultBuilder.contentIntent; if (contentIntent != null) { notifyBuilder.setContentIntent(contentIntent); } int defaults = 0; boolean sound = defaultBuilder.sound; boolean vibrate = defaultBuilder.vibrate; boolean lights = defaultBuilder.lights; if (sound) { defaults |= Notification.DEFAULT_SOUND; } if (vibrate) { defaults |= Notification.DEFAULT_VIBRATE; } if (lights) { defaults |= Notification.DEFAULT_LIGHTS; } if (defaults != 0) { notifyBuilder.setDefaults(defaults); } CharSequence ticker = defaultBuilder.ticker; if (!TextUtils.isEmpty(ticker)) { notifyBuilder.setTicker(defaultBuilder.ticker); } notifyBuilder.setAutoCancel(defaultBuilder.autoCancel); notifyBuilder.setWhen(defaultBuilder.when); notifyBuilder.setPriority(defaultBuilder.priority); return notifyBuilder.build(); }}
MyNotificationManager采用单例模式
从 Android 8.0(API 级别 26)开始,必须为所有通知分配渠道,否则通知将不会显示。通过将通知归类为不同的渠道,用户可以停用您应用的特定通知渠道(而非停用您的所有通知),还可以控制每个渠道的视觉和听觉选项,所有这些操作都在 Android 系统设置中完成。用户还可以长按通知以更改所关联渠道的行为。
package com.windfallsheng.mynotificationmanager.notification;import android.app.NotificationChannel;import android.app.NotificationChannelGroup;import android.app.NotificationManager;import android.content.Context;import android.os.Build;import android.util.Log;import com.windfallsheng.mynotificationmanager.R;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.concurrent.atomic.AtomicInteger;/** * @author lzsheng * * 封装通知栏实现,对于某些相关属性的处理逻辑,可根据具体的需求调整完善 */public class NotifyManager { private static final String TAG = NotifyManager.class.getSimpleName(); private static NotifyManager sInstance = null; private static NotificationManager mNotificationManager; private static List mChannelGroupList; /** * 通知栏的消息对象的自增Id */ private AtomicInteger mInitialNotifyId = new AtomicInteger(0); /** * 全局通知栏的Id,不同消息对象,对应自身唯一的全局Id */ private volatile Map
其它样式builder的处理逻辑,如 BigTextNotifyBuilder:
package com.windfallsheng.mynotificationmanager.notification;import android.app.Notification;import android.content.Context;import android.support.v4.app.NotificationCompat;/** * @author lzsheng */public class BigTextNotifyBuilder extends BaseNotifyBuilder{ public String mBigText; public NotificationCompat.BigTextStyle mBigTextStyle; public BigTextNotifyBuilder(DefaultNotifyBuilder defaultBuilder) { super(defaultBuilder); } public BigTextNotifyBuilder setBigText(String bigText) { this.mBigText = bigText; mBigTextStyle = new NotificationCompat.BigTextStyle() .bigText(bigText); return this; } @Override public Notification build(Context context) { super.build(context); notifyBuilder.setStyle(mBigTextStyle); return notifyBuilder.build(); }}
示例代码GitHub地址
由于作者水平有限,语言描述及代码实现中难免有纰漏,望各位看官多提宝贵意见!
Hello , World !
感谢所有!
更多相关文章
- Android(安卓)8.0系统Bug Only fullscreen opaque activities ca
- Android调用系统的库
- Android(安卓)P系统设置之默认打开定位开关(默认使用位置服务)
- 深入浅出 - Android系统移植与平台开发(二)
- Error generating final archive: java.io.EOFException
- 关于android:targetSdkVersion
- Android(安卓)异步任务 设置 超时使用handler更新通知功能
- 如何在Android系统中添加系统服务(以PowerManager为例)
- 如何获得系统权限--解决no conscrypt_openjdk_jni in java.libra