Android 生成通知栏以及点击通知栏跳转

一般结合一些透传消息(比如:个推推送),有时客户端需要自己生成相关需求的通知栏,生成的通知栏并且点击后,可以跳转到指定页面并携带上所需的参数。

    private static void showNotification(Context context, String contentTitle, String contentText, PendingIntent intent) {
        int channelId = new Random().nextInt(543254);
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, String.valueOf(channelId));
        builder.setContentTitle(contentTitle)
                .setContentText(contentText)
                .setContentIntent(intent)
                .setTicker("")//通知首次出现在通知栏,带上升动画效果的
                .setPriority(Notification.PRIORITY_DEFAULT)//设置该通知优先级
                .setAutoCancel(true)//设置这个标志当用户单击面板就可以让通知将自动取消
                .setOngoing(false)//ture,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
                .setDefaults(Notification.DEFAULT_VIBRATE);//向通知添加声音、闪灯和振动效果的最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,可以组合:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String name = "yourname";
            NotificationChannel mChannel = new NotificationChannel(String.valueOf(channelId), name, NotificationManager.IMPORTANCE_HIGH);
            if (notificationManager != null) {
                notificationManager.createNotificationChannel(mChannel);
                builder.setChannelId(String.valueOf(channelId));
            }
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            builder.setSmallIcon(R.drawable.ic_notification); //需要使用背景透明,图标为纯白色的图标。不然在很多机型上,如果直接使用应用icon,会直接显示纯白色图标,体验会不好。
        } else {
            builder.setSmallIcon(R.mipmap.ic_launcher);
        }
        if (notificationManager != null) {
            notificationManager.notify(channelId * 10, builder.build());
        }
    }
    //https://stackoverflow.com/questions/3168484/pendingintent-works-correctly-for-the-first-notification-but-incorrectly-for-the
    private static PendingIntent getMainActivityIntent(Context context, String jumpPageType, int requestCode, String sourceId) {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.setAction(Long.toString(System.currentTimeMillis()));
        intent.putExtra("jump_page_type", jumpPageType);
        intent.putExtra("source_id", sourceId);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setComponent(new ComponentName(context, MainActivity.class));
        // FLAG_ONE_SHOT:该PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。
        return PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
    }

以上代码有用到 PendingIntent, 想对PendingIntent的内部机制有更多了解的,可以看下这篇文章:https://my.oschina.net/youranhongcha/blog/196933

PendingIntent.getActivity(Context context, int requestCode, Intent intent, int flags)
第一个参数连接上下文的context
第二个参数是对PendingIntent的描述,请求值不同Intent就不同
第三个参数是一个Intent对象,包含跳转目标
第四个参数有4种状态

FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的PendingIntent对象,那么就将先将已有的PendingIntent取消,然后重新生成一个PendingIntent对象。

FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统将不会创建该PendingIntent对象而是直接返回null。

FLAG_ONE_SHOT:该PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。

FLAG_UPDATE_CURRENT:如果系统中有一个和你描述的PendingIntent对等的PendingInent,那么系统将使用该PendingIntent对象,但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,例如更新Intent中的Extras。

如果使用PendingIntent.FLAG_UPDATE_CURRENT,那么每次notifiId都是相同的数字,说明PendingIntent是一个,旧的参数被更新了。

如果使用PendingIntent.FLAG_ONE_SHOT,那么PendingIntent只是第一次有效,后来再点击别的Notification就无效了。

你可能感兴趣的:(Android 生成通知栏以及点击通知栏跳转)