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

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

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

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

普通通知

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

完整的代码如下:

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创建视图

指定展开状态的视图:

notification.bigContentView = remoteViews;

普通状态视图:

notification.contentView = remoteViews;

完整代码如下:

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以后的新特性,前两种需要手动拉通知栏,而这种方式不需要,直接就可以显示在屏幕上方

完整代码如下:

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以上

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;
    }
}

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/25/android-implement-three-types-of-status-bar-notifications/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Android实现3种Notification(状态栏通知)
Notification,是一种具有全局效果的通知,可以在系统的通知栏中显示。当 APP 向系统发出通知时,它将先以图标的形式显示在通知栏中。用户可以下拉通知栏查看……
<<上一篇
下一篇>>
文章目录
关闭
目 录