Android使用Notification通知栏功能的封装

在Android应用开发中我们经常会使用到通知栏的功能,安卓的通知栏有多种类型样式,包括基本类型、带进度条的类型、大图标类型、大段文本类型等,在Android 8.0 (API level 26) 中使用通知栏的代码示例:

// Create an explicit intent for an Activity in your app
Intent 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 define
notificationManager.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 mGlobalNotifyIdMap; private static Context mContext; private NotifyManager() { } public static NotifyManager getInstance(Context context) { if (sInstance == null) { synchronized (NotifyManager.class) { if (sInstance == null) { sInstance = new NotifyManager(); mContext = context.getApplicationContext(); if (mNotificationManager == null) { mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); initNotifyChannel(); } } } } return sInstance; } private static void initNotifyChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (mChannelGroupList == null) { mChannelGroupList = new ArrayList<>(); } mChannelGroupList.add(new NotificationChannelGroup(mContext.getResources().getString(R.string.groupId_001), "系统消息")); mChannelGroupList.add(new NotificationChannelGroup(mContext.getResources().getString(R.string.groupId_002), "IM消息")); mNotificationManager.createNotificationChannelGroups(mChannelGroupList); NotificationChannel channel1 = new NotificationChannel(mContext.getResources().getString(R.string.channel_001), "系统消息", NotificationManager.IMPORTANCE_HIGH); NotificationChannel channel2 = new NotificationChannel(mContext.getResources().getString(R.string.channel_002), "IM消息", NotificationManager.IMPORTANCE_HIGH); channel1.setGroup(mContext.getResources().getString(R.string.groupId_001)); channel2.setGroup(mContext.getResources().getString(R.string.groupId_002)); mNotificationManager.createNotificationChannel(channel1); mNotificationManager.createNotificationChannel(channel2); } } public int getInitialNotifyId() { if (mInitialNotifyId != null) { return mInitialNotifyId.intValue(); } return 0; } public Map getGlobalNotifyIdMap() { return mGlobalNotifyIdMap; } /** * IM消息的key的形式:key = "ImMessage" * * @param key * @return 返回对应的id */ public int initNotifyId(Object key) { Log.d(TAG, "method:initNotifyId#key=" + key); if (mGlobalNotifyIdMap == null) { mGlobalNotifyIdMap = new HashMap<>(); } Integer notifyId = mGlobalNotifyIdMap.get(key); Log.d(TAG, "method:initNotifyId#mGlobalNotifyIdMap=" + mGlobalNotifyIdMap); Log.d(TAG, "method:initNotifyId#notifyId=" + notifyId); if (notifyId == null) { return putNotifyId(key); } else { return notifyId; } } /** * 保证每次往集合{@link #mGlobalNotifyIdMap}中put新值时,ID都是自增的 *

* IM消息的key的形式:key = "ImMessage" * * @param key * @return */ private int putNotifyId(Object key) { Log.d(TAG, "method:putNotifyId#key=" + key); if (mGlobalNotifyIdMap != null) { int value = mInitialNotifyId.incrementAndGet(); Log.d(TAG, "method:putNotifyId#mInitialNotifyId.incrementAndGet#value=" + value); mGlobalNotifyIdMap.put(key, value); Log.d(TAG, "method:putNotifyId#mGlobalNotifyIdMap=" + mGlobalNotifyIdMap); return value; } return 0; } private void notify(Object key, BaseNotifyBuilder builder) { int notifyId = initNotifyId(key); mNotificationManager.notify(notifyId, builder.build(mContext)); } public NotificationManager getNotificationManager() { return mNotificationManager; } public List getChannelGroupList() { return mChannelGroupList; } public void showDefaultNotification(Object key, DefaultNotifyBuilder defaultBuilder) { BaseNotifyBuilder builder = new BaseNotifyBuilder(defaultBuilder); notify(key, builder); } public void showProgressNotification(Object key, int progress, int max, boolean interminate, DefaultNotifyBuilder defaultBuilder) { ProgressNotifyBuilder builder = new ProgressNotifyBuilder(defaultBuilder); notify(key, builder); } public void showLargeIconNotification(Object key, int largeIconId, DefaultNotifyBuilder defaultBuilder) { LargeIconNotifyBuilder builder = new LargeIconNotifyBuilder(defaultBuilder).setLargeIcon(largeIconId); notify(key, builder); } public void showBigTextNotification(Object key, String bigText, DefaultNotifyBuilder defaultBuilder) { BigTextNotifyBuilder builder = new BigTextNotifyBuilder(defaultBuilder).setBigText(bigText); notify(key, builder); } // ……………… 根据需要完善其它通知栏样式 ……………… }

其它样式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)