Notification 用法示例

1.1  普通通知
1.2  带进度条的通知    Android 4.1.2   

1.3  扩展布局      

              适配
              (1) 4.1 api 16 开始支持扩展布局,最顶部的通知自动展开
              (2) 7.0 api 24 每条通知都可以单独展开7.0 
          (3) 8.0 api 26 多条通知可以合并显示在一个里面( notificationChannelID 一样)


          操作按钮
          (1) api19 4.4 开机支持添加操作按钮,每个展开的通知的最多支持3个操作按(通知下方右下角的)
              builder.addAction(icon1,title1,pendingIntent1);
                  builder.addAction(icon2,title2,pendingIntent2);

          样式分类

          (1)多行文本通知   
          .setStyle(new Notification.BigTextStyle().bigText(""))

          (2)大图通知
          .setStyle(new Notification.BigPictureStyle().bigPicture(bitmap))

          (3)收件箱通知(最多显示5行消息)
          .setStyle(new Notification.InboxStyle());

              (4)MediaStyle播放界面通知
          关联音频播放服务的  api21, 点击和清空状态栏不会消失


1.4  浮动通知(headup 类似来电话)
              android 5.0 api 21
          通知具有较高优先级  Priority_MAX 或 HEIGHT

1.5  锁屏通知 
              android 5.0 api 21
          VISIBILITY_PUBLIC  显示通知的完整内容
          VISIBILITY_SECRET  不会在锁定屏幕上显示此通知的任何部分
              VISIBILITY_PRIVATE 显示通知图标和标题,但是隐藏完整内容

1.6  自定义通知 romateViews (很早的版本就支持了,类似音乐播放器的)

         
Notification.FLAG_SHOW_LIGHTS --  builder.setLightes   builder.setDefaults 

Notification.FLAG_ONLY_ALERT_ONCE (提醒铃声震动滚动等只执行一次)  builder.setOnlyAlertOnce(true);

Notification.FLAG_ONGOING_EVENT (正在进行的通知,用户不能取消,类似FLAG_NO_CLEAR)   builder.setOngoing(true);

Notification.FLAG_INSISTENT (持续提醒声音或震动,直到用户取消)   n.flag |= Notification.FLAG_INSISTENT

Notification_FLAG_NO_CLEAR  用户无法取消

Notification_FLAG_FOREGROUND_SERVICE  正在运行的服务


Notifcation.PRIORITY_MAX 重要紧急的通知,

Notification.PRIORITY_HIGH  高优先级

Notification.PRIORITY_DEFAULT  默认

Notificaiton.PRIORITY_LOW   低优先级,通知用户但又不是很紧急

Notification.PRIORITY_NIN   用户后台消息,只有用下拉通知抽屉才能看到内容


Notification.DEFAULT_SOUND  添加默认声音提醒


Notification.DEFAULT_VIBRATE 添加默认震动提醒

Notification.DEFAULT_LIGHTS  添加默认呼吸灯

Notification.DEFAULT_ALL  同时添加以上三种默认提醒


三类intent:
setContentIntent(PendingIntent contentIntent)
setDeleteIntent(PendingIntent deleteIntent)
setFullScreenIntent(PendingIntent fullscreenIntent)

 


builder.setTicker(CharSequence ticker)
builder.setContentTitle()
builder.setContentText()

builder.setContentInfo("ContentInfo");

builder.setNumber(4);


//设置默认notification title name
Bundle a = new Bundle();
a.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, newAppName)
builder.addExtras(a);


//大小图标

左边的大图为 largeIcon
右边的Android小机器人为smallIcon
builder.setSamllIcon(int smallIcon)
builder.setLargeIcon(largeIcon)

//设置按钮事件
setAction(position,string,pendingintent)


//设置时间
builder.setWhen(long date)
//设置是否显示时间
builder.setShowWhen(long data)
//
builder.setSubText()
builer.setProgress(max,progress,indeteminate)

//添加默认声音提醒
builder.setDefaults(Notification.DEFAULT_SOUND);
//添加默认呼吸灯提醒
builder.setDefaults(Notification.DEFAULT_LIGHTS);
//
builder.setSound(Uri.parse(""));

builder.setVibrate(new long[]{200,200,200,200});

builder.setLights(oxffffoooo(color), 300(on) ,100(off))

//设置pendingintent
builder.setContentIntent(pendingintent)
//取消
builder.setDeleteIntent(pendingintent)
//全屏(来电)
builder.setFullScreenIntent(pendingtent,true);

builder.setAutoCancel(true);
//设置为前台服务的notification
builder.setForgroundService() 

//设置style

builder.setStyle(new NotificationCompat.BigTextStyle()
                .setBigContentTitle("BigTextTitle")
                .setSummaryText("SummaryText")
                .bigText("BigTextBigText"));


builder.setStyle(new Notification.BigTextStyle().bigText(""))
builder.setStyle(new Notification.MessagingStyle("self name"))


builder.setVisibility(VISIBILITY_PUBLIC / VISIBILITY_SECRET /  VISIBILITY_PRIVATE );

builder.setLocalOnly();
builder.extend(new Notification.TvExtender());

notificationManager.notifyAsUser
notificationManager.notify

//remoteViews

RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.notif_custom_view);
remoteViews.setImageViewResource(R.id.image_icon, iconResource);
remoteViews.setTextViewText(R.id.text_title, title);
remoteViews.setTextViewText(R.id.text_message, message);
remoteViews.setImageViewResource(R.id.image_end, imageResource);

//--- 7.0
                 
//设置字体颜色
builder.setColor(ContextCompat.getColor());

//设置通知组
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
    // Other properties
    .setGroupSummary(true)
    .setGroup(KEY_NOTIFICATION_GROUP);

//添加直接回复
//-------------------短信会用到的场景------------------------------------
RemoteInput remoteInput = new RemoteInput.Builder("KEY_TEXT_REPLY_ID")
    .setLabel("LABEL_REPLY")
    .build();

Intent replyIntent = new Intent(context,xxxActivity.class);
replyIntent.put(number.value);
replyIntent.put(msg,value);
replyIntent.put(key,value);

PendingIntent replyPendIntent = PendingIntent.getActivity(context,
        requestCode,
        getDirectReplyIntent(context, LABEL_REPLY),
        PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Action replyAction =
        new NotificationCompat.Action.Builder(R.drawable.ic_reply,
                 LABEL_REPLY//发送按钮, 
         replyIntent)
                .addRemoteInput(remoteInput)
                .build();
builder.addAction(replyAction);

oncreate中处理
  oncreate(){
    Intent in = getIntent();
    //处理的地方
    Bundle bundle = RemoteInput.getResultsFromIntent(intent);
    if (remoteInput != null) {
        return bundle.getCharSequence(NotificationUtil.KEY_TEXT_REPLY);
    }
  }
-------------------------------------------------------------------------------

https://blog.csdn.net/hss01248/article/details/55096553
https://github.com/hss01248/NotifyUtil
详细分类: https://gold.xitu.io/post/5863264861ff4b0068b1817d 
7.0新特性:http://www.jianshu.com/p/33e84d5cb43f 
每种类型都有很全的示例代码:http://blog.csdn.net/w804518214/article/details/51231946

/**
 * 8.0以上需要增加channel
 */
@RequiresApi(Build.VERSION_CODES.O)
private fun createChannelIfNeeded() {
    if (Build.VERSION.SDK_INT >= 26) {
        val channel = NotificationChannel(NOTIFICATION_CHANNEL, "视频", NotificationManager.IMPORTANCE_LOW)
        channel.description = "下载"
        channel.enableLights(false)
        channel.enableVibration(false)
        //channel.importance = NotificationManager.IMPORTANCE_LOW //设置为low, 通知栏不会有声音
        mNotificationManager.createNotificationChannel(channel)
    }
}

notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    LogUtil.d(TAG, "onStartCommand");
    final Integer notificationID = 100;
    //Set notification information:
    final NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), NOTIFICATION_CHANNEL);
    notificationBuilder.setOngoing(true)
            .setSmallIcon(R.drawable.ic_launcher_round)
            .setContentTitle("视频")
            .setContentText("下载中")
            .setProgress(100, 0, false);
    //Send the notification:
    final Notification notification = notificationBuilder.build();
    startForeground(notificationID, notification);
    UIThread.uiPost(new Runnable() {
        @Override
        public void run() {
            if (progress == 100) {
                stopForeground(true);
                return;
            }
            notificationBuilder.setProgress(100, progress++, false);
            Notification notification = notificationBuilder.build();
            notificationManager.notify(notificationID, notification);
            UIThread.uiPost(this,100);
        }
    }, 100);
    return START_STICKY;
}


 

Android O 的用户可以使用一致的系统 UI 管理大多数与通知有关的设置。所有发布至通知渠道的通知都具有相同的行为。当用户修改任何下列特性的行为时,修改将作用于通知渠道:

重要性
声音
光
振动
在锁屏上显示
替换免打扰模式

用户可以访问 Settings(右划一段距离通知可以看到Settings),或长按通知来更改这些行为,甚至可以随时屏蔽通知渠道。一旦在创建完某个通知渠道并将其提交到通知管理器后,便无法通过编程方式修改通知渠道的行为,这些设置由用户掌控。

通知优先级和重要性

Android O 弃用了为单个通知设置优先级的功能。创建通知渠道时可以设置建议重要性级别。为通知渠道指定的重要性级别适用于发布至该渠道的所有通知消息。可以配置五个级别中的一个,这些级别代表着通知渠道可以打断用户的程度,范围是 IMPORTANCE_NONE(0)至 IMPORTANCE_HIGH(4)。默认重要性级别为 3:在所有位置显示,发出提示音,但不会对用户产生视觉干扰。创建通知渠道后,只有系统可以修改其重要性。用户可以在设置中找到。


mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 通知渠道的id
String id = "my_channel_01";
// 用户可以看到的通知渠道的名字.
CharSequence name = getString(R.string.channel_name);
// 用户可以看到的通知渠道的描述
String description = getString(R.string.channel_description);
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
// 配置通知渠道的属性
mChannel.setDescription(description);
// 设置通知出现时的闪灯(如果 android 设备支持的话)
mChannel.enableLights(true);
mChannel.setLightColor(Color.RED);
// 设置通知出现时的震动(如果 android 设备支持的话)
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
//最后在notificationmanager中创建该通知渠道
//
mNotificationManager.createNotificationChannel(mChannel);

可以通过调用 createNotificationChannels(List < NotificationChannel > channels)



创建通知渠道组

如果应用支持多个帐户,则可为每个帐户创建一个通知渠道组。通知渠道组用于对一款应用内的多个同名通知渠道进行管理。
例如,一款社交网络应用可能提供面向个人帐户以及企业帐户的支持。在此情境下,每个帐户可能都需要多个功能和名称相同的通知渠道。
一个包括 2 个通知渠道的个人帐户:

帖子新增评论的通知。
联系人推荐帖子的通知。
一个包括 2 个通知渠道的企业帐户:

帖子新增评论的通知。
联系人推荐帖子的通知。
在本例中,将与每个用户帐户相关的通知渠道组织成专用组可确保用户能在 Settings 中轻松地进行区分。
每个通知渠道组都必须在软件包内具有唯一 ID,并具有用户可见的名称。下面这段代码演示了如何创建通知渠道组。

// 通知渠道组的id.
String group = "my_group_01";
// 用户可见的通知渠道组名称.
CharSequence name = getString(R.string.group_name);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannelGroup(new NotificationChannelGroup(group, name));
新建渠道组后,便可调用 setGroup()将某个新渠道关联到该组。注意,只能在将渠道提交给通知管理器之前修改通知渠道与组之间的关联。

小图标,由 setSmallIcon()设置
标题,由 setContentTitle()设置
详细文本,由 setContentText()设置
有效的通知渠道 ID,由 setChannelId()设置
如果 应用是以 Android O 为目标平台并且在不指定有效通知渠道的情况下发布通知,那么通知将无法发布,系统会记录错误。
注:可以在 Android O 中启用一个新设置,当针对 Android O 的应用试图在没有通知渠道的情况下发布时,以 toast 形式显示屏幕警告。
要为运行 Android O 的开发设备启用该设置,请转到 Settings > Developer options,然后打开 Show notification channel warnings。


向渠道发布通知

mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int notifyID = 1;// 为该通知设置一个id
String CHANNEL_ID = "my_channel_01";// 通知渠道的id
// Create a notification and set the notification channel.
Notification notification = new Notification.Builder(MainActivity.this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status) 
.setChannelId(CHANNEL_ID)
.build();
mNotificationManager.notify(id, notification);



1.读取通知渠道设置

用户可以修改通知渠道的设置,包括振动和提示音等行为。开发者可以调用以下两个方法来发现用户对通知渠道应用的设置:
要检索单个通知渠道,可以调用 getNotificationChannel()。
要检索归属的应用的所有通知渠道,可以调用 getNotificationChannels()。
更新通知渠道设置

一旦创建了通知渠道,其设置和行为就由用户掌控。可以再次调用 createNotificationChannel()以重命名现有通知渠道,或更新其说明。
以下示例代码说明如何通过创建启动 Activity的Intent将用户重定向到通知渠道的设置。
在本例中,Intent 要求提供扩展数据,包括通知渠道的 ID 和应用的软件包名称。

Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_CHANNEL_ID,mChannel.getId());
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());startActivity(intent);

2.删除通知渠道
可以通过调用 deleteNotificationChannel()来删除通知渠道。
作为一个垃圾信息预防机制,通知设置中将显示已删除渠道的数量。可以通过以下任一方法清除开发设备上的测试渠道:
重新安装应用;清除与应用副本关联的数据。以下示例代码演示了如何删除通知渠道。

NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// 通知渠道的id
String id = "my_channel_01";
NotificationChannel mChannel = mNotificationManager.getNotificationChannel(id);
mNotificationManager.deleteNotificationChannel(mChannel);

8.0  NotificationChannel
https://blog.csdn.net/misiyuan/article/details/78384819

当设置了  NotificationChannel “通知管道”后, 可以在 设置--通知-- 里面查看每个应用下面的通知详情

一,关键类

1.NotificationManagerService
NotificationManagerService继承SystemService,是系统级别的service.
NotificationManagerService在init初始化的时候会加载/data/system/notification_policy.xml中的通知信息到内存数据结构,

该文件中保存所有package注册的所有NotificationChannel。
如下内容为xml文件部分内容。可以看到不同package下创建的channel以及channel相关属性,文件中定义了系统基本的 packageName 对应的配置

</package>
<package name="com.android.providers.downloads" show_badge="true" uid="1010013">
<channel id="active" name="下载中" importance="2" sound="content://settings/system/notification_sound" usage="5" content_type="4" flags="0" show_badge="true" />
<channel id="complete" name="下载完成" importance="2" sound="content://settings/system/notification_sound" usage="5" content_type="4" flags="0" show_badge="true" />
<channel id="waiting" name="等待中" importance="2" sound="content://settings/system/notification_sound" usage="5" content_type="4" flags="0" show_badge="true" />
<channel id="insufficient_space" name="空间不足" importance="2" sound="content://settings/system/notification_sound" usage="5" content_type="4" flags="0" show_badge="true" />
</package>
<package name="com.android.providers.downloads" show_badge="true" uid="10013">
<channel id="active" name="下载中" importance="2" sound="content://settings/system/notification_sound" usage="5" content_type="4" flags="0" show_badge="true" />
<channel id="complete" name="下载完成" importance="2" sound="content://settings/system/notification_sound" usage="5" content_type="4" flags="0" show_badge="true" />
<channel id="waiting" name="等待中" importance="2" sound="content://settings/system/notification_sound" usage="5" content_type="4" flags="0" show_badge="true" />
<channel id="insufficient_space" name="空间不足" importance="2" sound="content://settings/system/notification_sound" usage="5" content_type="4" flags="0" show_badge="true" />
</package>

NotificationChannel不同用户空间下是通过uid来区分的,所以在多用户下系统在寻找channel时是以pkg + "|" + uid为key查找的


2.NotificationChannel

    创建
    public NotificationChannel(String id, CharSequence name, @Importance int importance) {
        this.mId = getTrimmedString(id);
        this.mName = name != null ? getTrimmedString(name.toString()) : null;
        this.mImportance = importance;
    }


    发送
    public void notifyAsUser(String tag, int id, Notification notification, UserHandle user)
    {
        INotificationManager service = getService();
        String pkg = mContext.getPackageName();
        // Fix the notification as best we can.
        Notification.addFieldsFromContext(mContext, notification);
        if (notification.sound != null) {
            notification.sound = notification.sound.getCanonicalUri();
            if (StrictMode.vmFileUriExposureEnabled()) {
                notification.sound.checkFileUriExposed("Notification.sound");
            }
        }
        fixLegacySmallIcon(notification, pkg);
        if (mContext.getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
            if (notification.getSmallIcon() == null) {
                throw new IllegalArgumentException("Invalid notification (no valid small icon): "
                        + notification);
            }
        }
        if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
        final Notification copy = Builder.maybeCloneStrippedForDelivery(notification);
        try {
            service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
                    copy, user.getIdentifier());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
      }

   
       void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
            final int callingPid, final String tag, final int id, final Notification notification,
            int incomingUserId) {
        if (DBG) {
            Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
                    + " notification=" + notification);
        }
        checkCallerIsSystemOrSameApp(pkg);
 
        final int userId = ActivityManager.handleIncomingUser(callingPid,
                callingUid, incomingUserId, true, false, "enqueueNotification", pkg);
        final UserHandle user = new UserHandle(userId);
 
        if (pkg == null || notification == null) {
            throw new IllegalArgumentException("null not allowed: pkg=" + pkg
                    + " id=" + id + " notification=" + notification);
        }
 
        // The system can post notifications for any package, let us resolve that.
        final int notificationUid = resolveNotificationUid(opPkg, callingUid, userId);
 
        // Fix the notification as best we can.
        try {
            final ApplicationInfo ai = mPackageManagerClient.getApplicationInfoAsUser(
                    pkg, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
                    (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
            Notification.addFieldsFromContext(ai, notification);
        } catch (NameNotFoundException e) {
            Slog.e(TAG, "Cannot create a context for sending app", e);
            return;
        }
 
        mUsageStats.registerEnqueuedByApp(pkg);
 
        // setup local book-keeping
        String channelId = notification.getChannelId();
        if (mIsTelevision && (new Notification.TvExtender(notification)).getChannelId() != null) {
            channelId = (new Notification.TvExtender(notification)).getChannelId();
        }
        final NotificationChannel channel = mRankingHelper.getNotificationChannel(pkg,
                notificationUid, channelId, false /* includeDeleted */);
        if (channel == null) {
            final String noChannelStr = "No Channel found for "
                    + "pkg=" + pkg
                    + ", channelId=" + channelId
                    + ", id=" + id
                    + ", tag=" + tag
                    + ", opPkg=" + opPkg
                    + ", callingUid=" + callingUid
                    + ", userId=" + userId
                    + ", incomingUserId=" + incomingUserId
                    + ", notificationUid=" + notificationUid
                    + ", notification=" + notification;
            Log.e(TAG, noChannelStr);
            doChannelWarningToast("Developer warning for package \"" + pkg + "\"\n" +
                    "Failed to post notification on channel \"" + channelId + "\"\n" +
                    "See log for more details");
            return;
        }
 
        final StatusBarNotification n = new StatusBarNotification(
                pkg, opPkg, id, tag, notificationUid, callingPid, notification,
                user, null, System.currentTimeMillis());
        final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
 
        if (!checkDisqualifyingFeatures(userId, notificationUid, id, tag, r)) {
            return;
        }
 
        // Whitelist pending intents.
        if (notification.allPendingIntents != null) {
            final int intentCount = notification.allPendingIntents.size();
            if (intentCount > 0) {
                final ActivityManagerInternal am = LocalServices
                        .getService(ActivityManagerInternal.class);
                final long duration = LocalServices.getService(
                        DeviceIdleController.LocalService.class).getNotificationWhitelistDuration();
                for (int i = 0; i < intentCount; i++) {
                    PendingIntent pendingIntent = notification.allPendingIntents.valueAt(i);
                    if (pendingIntent != null) {
                        am.setPendingIntentWhitelistDuration(pendingIntent.getTarget(),
                                WHITELIST_TOKEN, duration);
                    }
                }
            }
        }
        mHandler.post(new EnqueueNotificationRunnable(userId, r));
    }


 

 

 


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值