×

Notification

96
不需要任何
2017.06.12 21:02* 字数 413
社会树状图

基本使用

1.获取 NotificationManager 实例
2.实例化 NotificationCompat.Builder 并设置相关属性
3.通过 builder.build() 方法生成 Notification 对象,并发送通知

  //获取NotificationManager实例
   NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
   //实例化NotificationCompat.Builde并设置相关属性
   NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           //设置小图标
           .setSmallIcon(R.mipmap.icon_fab_repair)
           //设置通知标题
           .setContentTitle("最简单的Notification")
           //设置通知内容
           .setContentText("只有小图标、标题、内容")
           //设置通知时间,默认为系统发出通知的时间,通常不用设置
           //.setWhen(System.currentTimeMillis());
   //通过builder.build()方法生成Notification对象,并发送通知,id=1
   notifyManager.notify(1, builder.build());

ps

setSmallIcon()和 setLargeIcon()同时存在的时候
小logo在通知栏的右下方

实行交互功能

即点击转跳

/**
* 发送一个点击跳转到MainActivity的消息
*/
private void sendSimplestNotificationWithAction() {
   //获取PendingIntent
   Intent mainIntent = new Intent(this, MainActivity.class);
   PendingIntent mainPendingIntent = PendingIntent.getActivity(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
   //创建 Notification.Builder 对象
   NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.mipmap.ic_launcher)
           //点击通知后自动清除
           .setAutoCancel(true)
           .setContentTitle("我是带Action的Notification")
           .setContentText("点我会打开MainActivity")
           .setContentIntent(mainPendingIntent);
   //发送通知
   mNotifyManager.notify(3, builder.build());
}

这里注意三个Intent (Intent PendingIntent 以及方法setContentIntent() ) 接下来重点介绍PendingIntent

pendingIntent

pendingIntent即一个延迟的Intent ,就是用户点击通知的时候才会执行,

PendingIntent 是 Android 系统管理并持有的用于描述和获取原始数据的对象的标志(引用)。也就是说,即便创建该PendingIntent对象的进程被杀死了,这个PendingItent对象在其他进程中还是可用的。
日常使用中的短信、闹钟等都用到了 PendingIntent。(引用

pendingIntent的获取方式

//获取一个用于启动 Activity 的 PendingIntent 对象
public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags);

//获取一个用于启动 Service 的 PendingIntent 对象
public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags);

//获取一个用于向 BroadcastReceiver 广播的 PendingIntent 对象
public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)

PengdingIntent有几种flag

FLAG_CANCEL_CURRENT:如果系统存在一个相同的PendingIntent的,取消之前的对象再新创建一个PendingIntent对象

FLAG_NO_CREATE:如果系统中不存在这个PengdingIntent对象时,返回null

FLAG_ONE_SHOT:给PendingIntent只作用一次

FLAG_UPDATE_CURRENT:如果系统中已存在该 PendingIntent 对象,那么系统将保留该 PendingIntent 对象,但是会使用新的 Intent 来更新之前 PendingIntent 中的 Intent 对象数据,例如更新 Intent 中的 Extras 。(!!!!!)

PengdingIntent的更新

更新通知即发送新的通知即可,只要ID相同即可,
如果更新存在的画只是改变,
如果被取消即创建新的通知;

取消 PendingIntent(五种)

  • 通知被清除 按钮 右滑
  • 设置了 setAutoCancel() 或 FLAG_AUTO_CANCEL 的通知,点击该通知时会清除它
  • 调用NotificationManagerCancel(int id) 指定Id消除
  • 通过 NotificationManager 调用 cancel(String tag, int id) 方法清除指定 TAG 和 ID 的通知
  • 通过 NotificationManager 调用 cancelAll() 方法清除所有该应用之前发送的通知

    小Demo

/**
 * 为了方便,大部分通知都没设置对应的Action,即PendingIntent
 * 除了sendFlagAutoCancelNotification()方法
 */
public class SimpleNotificationActivity extends Activity implements View.OnClickListener {

    //Notification.FLAG_FOREGROUND_SERVICE    //表示正在运行的服务
    public static final String NOTIFICATION_TAG = "littlejie";
    public static final int DEFAULT_NOTIFICATION_ID = 1;

    private NotificationManager mNotificationManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple_notification);

        findViewById(R.id.btn_remove_all_notification).setOnClickListener(this);
        findViewById(R.id.btn_send_notification).setOnClickListener(this);
        findViewById(R.id.btn_remove_notification).setOnClickListener(this);
        findViewById(R.id.btn_send_notification_with_tag).setOnClickListener(this);
        findViewById(R.id.btn_remove_notification_with_tag).setOnClickListener(this);
        findViewById(R.id.btn_send_ten_notification).setOnClickListener(this);
        findViewById(R.id.btn_send_flag_no_clear_notification).setOnClickListener(this);
        findViewById(R.id.btn_send_flag_ongoing_event_notification).setOnClickListener(this);
        findViewById(R.id.btn_send_flag_auto_cancecl_notification).setOnClickListener(this);

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

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_remove_all_notification:
                //移除当前 Context 下所有 Notification,包括 FLAG_NO_CLEAR 和 FLAG_ONGOING_EVENT
                mNotificationManager.cancelAll();
                break;
            case R.id.btn_send_notification:
                //发送一个 Notification,此处 ID = 1
                sendNotification();
                break;
            case R.id.btn_remove_notification:
                //移除 ID = 1 的 Notification,注意:该方法只针对当前 Context。
                mNotificationManager.cancel(DEFAULT_NOTIFICATION_ID);
                break;
            case R.id.btn_send_notification_with_tag:
                //发送一个 ID = 1 并且 TAG = littlejie 的 Notification
                //注意:此处发送的通知与 sendNotification() 发送的通知并不冲突
                //因为此处的 Notification 带有 TAG
                sendNotificationWithTag();
                break;
            case R.id.btn_remove_notification_with_tag:
                //移除一个 ID = 1 并且 TAG = littlejie 的 Notification
                //注意:此处移除的通知与 NotificationManager.cancel(int id) 移除通知并不冲突
                //因为此处的 Notification 带有 TAG
                mNotificationManager.cancel(NOTIFICATION_TAG, DEFAULT_NOTIFICATION_ID);
                break;
            case R.id.btn_send_ten_notification:
                //连续发十条 Notification
                sendTenNotifications();
                break;
            case R.id.btn_send_flag_no_clear_notification:
                //发送 ID = 1, flag = FLAG_NO_CLEAR 的 Notification
                //下面两个 Notification 的 ID 都为 1,会发现 ID 相等的 Notification 会被最新的替换掉
                sendFlagNoClearNotification();
                break;
            case R.id.btn_send_flag_auto_cancecl_notification:
                sendFlagOngoingEventNotification();
                break;
            case R.id.btn_send_flag_ongoing_event_notification:
                sendFlagAutoCancelNotification();
                break;
        }
    }

    /**
     * 发送最简单的通知,该通知的ID = 1
     */
    private void sendNotification() {
        //这里使用 NotificationCompat 而不是 Notification ,因为 Notification 需要 API 16 才能使用
        //NotificationCompat 存在于 V4 Support Library
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Send Notification")
                .setContentText("Hi,My id is 1");
        mNotificationManager.notify(DEFAULT_NOTIFICATION_ID, builder.build());
    }

    /**
     * 使用notify(String tag, int id, Notification notification)方法发送通知
     * 移除对应通知需使用 cancel(String tag, int id)
     */
    private void sendNotificationWithTag() {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Send Notification With Tag")
                .setContentText("Hi,My id is 1,tag is " + NOTIFICATION_TAG);
        mNotificationManager.notify(NOTIFICATION_TAG, DEFAULT_NOTIFICATION_ID, builder.build());
    }

    /**
     * 循环发送十个通知
     */
    private void sendTenNotifications() {
        for (int i = 0; i < 10; i++) {
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("Send Notification Batch")
                    .setContentText("Hi,My id is " + i);
            mNotificationManager.notify(i, builder.build());
        }
    }

    /**
     * 设置FLAG_NO_CLEAR
     * 该 flag 表示该通知不能被状态栏的清除按钮给清除掉,也不能被手动清除,但能通过 cancel() 方法清除
     * Notification.flags属性可以通过 |= 运算叠加效果
     */
    private void sendFlagNoClearNotification() {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Send Notification Use FLAG_NO_CLEAR")
                .setContentText("Hi,My id is 1,i can't be clear.");
        Notification notification = builder.build();
        //设置 Notification 的 flags = FLAG_NO_CLEAR
        //FLAG_NO_CLEAR 表示该通知不能被状态栏的清除按钮给清除掉,也不能被手动清除,但能通过 cancel() 方法清除
        //flags 可以通过 |= 运算叠加效果
        notification.flags |= Notification.FLAG_NO_CLEAR;
        mNotificationManager.notify(DEFAULT_NOTIFICATION_ID, notification);
    }

    /**
     * 设置FLAG_AUTO_CANCEL
     * 该 flag 表示用户单击通知后自动消失
     */
    private void sendFlagAutoCancelNotification() {
        //设置一个Intent,不然点击通知不会自动消失
        Intent resultIntent = new Intent(this, MainActivity.class);
        PendingIntent resultPendingIntent = PendingIntent.getActivity(
                this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Send Notification Use FLAG_AUTO_CLEAR")
                .setContentText("Hi,My id is 1,i can be clear.")
                .setContentIntent(resultPendingIntent);
        Notification notification = builder.build();
        //设置 Notification 的 flags = FLAG_NO_CLEAR
        //FLAG_AUTO_CANCEL 表示该通知能被状态栏的清除按钮给清除掉
        //等价于 builder.setAutoCancel(true);
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        mNotificationManager.notify(DEFAULT_NOTIFICATION_ID, notification);
    }

    /**
     * 设置FLAG_ONGOING_EVENT
     * 该 flag 表示发起正在运行事件(活动中)
     */
    private void sendFlagOngoingEventNotification() {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Send Notification Use FLAG_ONGOING_EVENT")
                .setContentText("Hi,My id is 1,i can't be clear.");
        Notification notification = builder.build();
        //设置 Notification 的 flags = FLAG_NO_CLEAR
        //FLAG_ONGOING_EVENT 表示该通知通知放置在正在运行,不能被手动清除,但能通过 cancel() 方法清除
        //等价于 builder.setOngoing(true);
        notification.flags |= Notification.FLAG_ONGOING_EVENT;
        mNotificationManager.notify(DEFAULT_NOTIFICATION_ID, notification);
    }    
}

Notification实现通知功能

用setDefaults()方法来实现相关通知功能
ps:一旦设置了Defaluts效果则 ,自定义效果就会消失

这几个事默认设置

//设置系统默认提醒效果,一旦设置默认提醒效果,则自定义的提醒效果会全部失效。具体可看源码
//添加默认震动效果,需要申请震动权限
//<uses-permission android:name="android.permission.VIBRATE" />
Notification.DEFAULT_VIBRATE

//添加系统默认声音效果,设置此值后,调用setSound()设置自定义声音无效
Notification.DEFAULT_SOUND

//添加默认呼吸灯效果,使用时须与 Notification.FLAG_SHOW_LIGHTS 结合使用,否则无效
Notification.DEFAULT_LIGHTS

//添加上述三种默认提醒效果
Notification.DEFAULT_ALL```
此为未有默认设置的

```java
//提醒效果常用 Flag
//三色灯提醒,在使用三色灯提醒时候必须加该标志符
Notification.FLAG_SHOW_LIGHTS

//发起正在运行事件(活动中)
Notification.FLAG_ONGOING_EVENT
//FLAG_ONGOING_EVENT 表示该通知通知放置在正在运行,不能被手动清除,但能通过 cancel() 方法清除

//让声音、振动无限循环,直到用户响应 (取消或者打开)
Notification.FLAG_INSISTENT

//发起Notification后,铃声和震动均只执行一次
Notification.FLAG_ONLY_ALERT_ONCE

//用户单击通知后自动消失
Notification.FLAG_AUTO_CANCEL

//只有调用NotificationManager.cancel()时才会清除
Notification.FLAG_NO_CLEAR

//表示正在运行的服务
Notification.FLAG_FOREGROUND_SERVICE```
接下来讲讲核心代码
```java
/**
* 最普通的通知效果
*/
private void showNotifyOnlyText() {
   NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.mipmap.ic_launcher)
           .setLargeIcon(mLargeIcon)
           .setContentTitle("我是只有文字效果的通知")
           .setContentText("我没有铃声、震动、呼吸灯,但我就是一个通知");
   mManager.notify(1, builder.build());
}

/**
* 展示有自定义铃声效果的通知
* 补充:使用系统自带的铃声效果:Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");
*/
private void showNotifyWithRing() {
   NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.mipmap.ic_launcher)
           .setContentTitle("我是伴有铃声效果的通知")
           .setContentText("美妙么?安静听~")
           //调用系统默认响铃,设置此属性后setSound()会无效
           //.setDefaults(Notification.DEFAULT_SOUND)
           //调用系统多媒体裤内的铃声
           //.setSound(Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2"));
           //调用自己提供的铃声,位于 /res/values/raw 目录下
           .setSound(Uri.parse("android.resource://com.littlejie.notification/" + R.raw.sound));
   //另一种设置铃声的方法
   //Notification notify = builder.build();
   //调用系统默认铃声
   //notify.defaults = Notification.DEFAULT_SOUND;
   //调用自己提供的铃声
   //notify.sound = Uri.parse("android.resource://com.littlejie.notification/"+R.raw.sound);
   //调用系统自带的铃声
   //notify.sound = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2");
   //mManager.notify(2,notify);
   mManager.notify(2, builder.build());
}

/**
* 展示有震动效果的通知,需要在AndroidManifest.xml中申请震动权限
* <uses-permission android:name="android.permission.VIBRATE" />
* 补充:测试震动的时候,手机的模式一定要调成铃声+震动模式,否则你是感受不到震动的
*/
private void showNotifyWithVibrate() {
   //震动也有两种设置方法,与设置铃声一样,在此不再赘述
   long[] vibrate = new long[]{0, 500, 1000, 1500};
   NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.mipmap.ic_launcher)
           .setContentTitle("我是伴有震动效果的通知")
           .setContentText("颤抖吧,凡人~")
           //使用系统默认的震动参数,会与自定义的冲突
           //.setDefaults(Notification.DEFAULT_VIBRATE)
           //自定义震动效果
           .setVibrate(vibrate);
   //另一种设置震动的方法
   //Notification notify = builder.build();
   //调用系统默认震动
   //notify.defaults = Notification.DEFAULT_VIBRATE;
   //调用自己设置的震动
   //notify.vibrate = vibrate;
   //mManager.notify(3,notify);
   mManager.notify(3, builder.build());
}

/**
* 显示带有呼吸灯效果的通知,但是不知道为什么,自己这里测试没成功
*/
private void showNotifyWithLights() {
   final NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.mipmap.ic_launcher)
           .setContentTitle("我是带有呼吸灯效果的通知")
           .setContentText("一闪一闪亮晶晶~")
           //ledARGB 表示灯光颜色、 ledOnMS 亮持续时间、ledOffMS 暗的时间
           .setLights(0xFF0000, 3000, 3000);
   Notification notify = builder.build();
   //只有在设置了标志符Flags为Notification.FLAG_SHOW_LIGHTS的时候,才支持呼吸灯提醒。
   notify.flags = Notification.FLAG_SHOW_LIGHTS;
   //设置lights参数的另一种方式
   //notify.ledARGB = 0xFF0000;
   //notify.ledOnMS = 500;
   //notify.ledOffMS = 5000;
   //使用handler延迟发送通知,因为连接usb时,呼吸灯一直会亮着
   Handler handler = new Handler();
   handler.postDelayed(new Runnable() {
       @Override
       public void run() {
           mManager.notify(4, builder.build());
       }
   }, 10000);
}

/**
* 显示带有默认铃声、震动、呼吸灯效果的通知
* 如需实现自定义效果,请参考前面三个例子
*/
private void showNotifyWithMixed() {
   NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.mipmap.ic_launcher)
           .setContentTitle("我是有铃声+震动+呼吸灯效果的通知")
           .setContentText("我是最棒的~")
           //等价于setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE);
           .setDefaults(Notification.DEFAULT_ALL);
   mManager.notify(5, builder.build());
}

/**
* 通知无限循环,直到用户取消或者打开通知栏(其实触摸就可以了),效果与FLAG_ONLY_ALERT_ONCE相反
* 注:这里没有给Notification设置PendingIntent,也就是说该通知无法响应,所以只能手动取消
*/
private void showInsistentNotify() {
   NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.mipmap.ic_launcher)
           .setContentTitle("我是一个死循环,除非你取消或者响应")
           .setContentText("啦啦啦~")
           .setDefaults(Notification.DEFAULT_ALL);
   Notification notify = builder.build();
   notify.flags |= Notification.FLAG_INSISTENT;
   mManager.notify(6, notify);
}

/**
* 通知只执行一次,与默认的效果一样
*/
private void showAlertOnceNotify() {
   NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.mipmap.ic_launcher)
           .setContentTitle("仔细看,我就执行一遍")
           .setContentText("好了,已经一遍了~")
           .setDefaults(Notification.DEFAULT_ALL);
   Notification notify = builder.build();
   notify.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
   mManager.notify(7, notify);
}

/**
* 清除所有通知
*/
private void clearNotify() {
   mManager.cancelAll();
}```
日记本
Web note ad 1