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
 * <p>
 * 封装通知栏实现,对于某些相关属性的处理逻辑,可根据具体的需求调整完善
 */
public class NotifyManager {

    private static final String TAG = NotifyManager.class.getSimpleName();
    private static NotifyManager sInstance = null;
    private static NotificationManager mNotificationManager;
    private static List<NotificationChannelGroup> mChannelGroupList;
    /**
     * 通知栏的消息对象的自增Id
     */
    private AtomicInteger mInitialNotifyId = new AtomicInteger(0);
    /**
     * 全局通知栏的Id,不同消息对象,对应自身唯一的全局Id
     */
    private volatile Map<Object, Integer> 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<Object, Integer> 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都是自增的
     * <p>
     * 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<NotificationChannelGroup> 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 !

感谢所有!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Android通知是一种用于显示应用程序通知的用户界面元素。它可以在屏幕的顶部或底部显示,并且可以包含文本、图像、声音和其他交互元素。通知可以帮助用户及时了解应用程序的状态和事件,例如新消息、更新、提醒和警告等。开发人员可以使用Android SDK提供的通知API来创建和管理通知,以便更好地与用户进行交互。 ### 回答2: Android 通知是一种提供给用户显示有关当前状态和行动的信息的方式,以便用户可以及时地采取必要的行动。通知可以显示来自应用程序和系统的通知消息,例如电子邮件、信息和其他事件,可以让用户在不离开当前应用的情况下对这些消息进行响应。 在通知中,每个通知都包含一个图标、标题、简短的消息文本和通知时间。用户可以从通知中直接打开应用程序或查看通知的详细信息。通知还可以显示多个通知,按照时间顺序进行排序。 开发人员可以使用 Android SDK 提供的 Notification 类来创建自定义通知。可以设置通知的图标、文本、声音、震动和延迟时间等属性。还可以指定通知的优先级,以便系统在有限的屏幕空间中为用户先显示最重要的通知通知还可以与 PendingIntent 实例相关联,以便在用户单击通知时执行特定的操作,例如打开应用程序,启动活动或显示通知详细信息的专用活动。 总之,Android 通知是一种非常有用的功能,可以让用户及时了解应用程序和系统中的重要事件,并采取及时的行动。开发人员可以使用通知来实现更好的用户体验。 ### 回答3: Android 通知是一种非常有用的功能,它可以让你的应用程序以一种全新的方式与用户进行交互。在 Android 应用程序中,通知是一种特殊的 UI 元素,它显示在屏幕的顶部,并显示当前状态、事件或提示。通知通常包含一组小图标,可以展开或折叠以显示更多详细信息。 Android 通知有许多不同的用途,例如提醒用户新的消息、电子邮件、电话、提醒等等。发送通知的应用程序无需与用户保持连接,这使得通知非常适合后台服务或其他形式的低功耗通信。通知还允许用户直接从通知菜单中操作应用程序。例如,当用户收到新的电子邮件时,他们可以在通知中选择该电子邮件并立即查看其内容,而无需打开电子邮件应用程序。 Android 通知的另一个优点是它的可定制性。可以轻松地修改通知的外观、行为和内容,以满足不同应用程序的需求和设计要求。您可以为通知添加各种元素,如纯文本、小图标、大图标、进度指示器、按钮等等。这样,您可以轻松地创造与您的品牌和应用程序设计语言保持一致的通知。 在实现通知之前,您需要确保该应用程序已获得了通知权限。如果您的应用程序需要通知用户任何内容,则必须获得 Android 手机上的通知权限。可以在应用程序设置中找到此选项。 虽然 Android 通知很有用,但在某些情况下,它们可能会变得令人分心。因此,应该仔细考虑应用程序通知的数量和类型,以确保用户不会感到困扰。通知还可以消耗设备电池,因此也应考虑优化应用程序以最小化资源消耗。 Android 通知作为 Android 应用程序非常重要的一部分,可以帮助您在应用程序和用户之间建立更紧密的联系,并提供有关应用程序状态、事件和提示的有用信息。通过努力优化您的应用程序通知,您可以确保用户感到受到了关注,并且同时不会让他们感到困扰。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

windfallsheng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值