当前位置:   article > 正文

Android 8.0或其以上的系统上的通知的创建和取消通知震动_app 9.0创建前端通知时取消震动

app 9.0创建前端通知时取消震动

今天在做通知的模块。才知道8.0及其以上的系统通知的创建已经不是简单的用 NoticeficationCompat.Builder就可以创建出来的。8.0系统引入了一个消息通道概念----- NotificationChannel。

所以我们需要创建通知的时候,判断下是否是8的系统。以下是完整代码

  1. //1:获取系统提供的通知管理服务
  2. notificationManager = (NotificationManager)
  3. getSystemService(Context.NOTIFICATION_SERVICE);
  1. //2:如果是8以上的系统,则新建一个消息通道
  2. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  3. setChannerl();
  4. }
  1. private void setChannerl() {
  2. channelId = "chat";//消息通道的id,以后可以通过该id找到该消息通道
  3. String channelName = "聊天消息";//消息通道的name
  4. int importance = NotificationManager.IMPORTANCE_MAX;//通知的优先级
  5. // .具体的请自行百度。作用就是优先级的不同。可以导致消息出现的形式不一样。
  6. // MAX是会震动并且出现在屏幕的上方。设置优先级为low或者min时。来通知时都不会震动,
  7. // 且不会直接出现在屏幕上方
  8. createNotificationChannel(channelId, channelName, importance);
  9. }
  1. @TargetApi(Build.VERSION_CODES.O)
  2. private void createNotificationChannel( String channelId, String channelName,
  3. int
  4. importance) {
  5. NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
  6. notificationManager.createNotificationChannel(channel);
  7. }

然后我是点击按钮来模拟收到通知:

  1. findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() {
  2. @Override
  3. public void onClick(View view) {
  4. //3:创建通知
  5. createNotification("测试通知");
  6. }
  7. });
  1. private void createNotification( String content) {
  2. Intent intent = new Intent(this, SecondActivity.class);
  3. /*
  4. * 调用PendingIntent的静态放法创建一个 PendingIntent对象用于点击通知之后执行的操作,
  5. * PendingIntent可以理解为延时的Intent,在这里即为点击通知之后执行的Intent
  6. * 这里调用getActivity(Context context, int requestCode, Intent intent, int flag)方法
  7. * 表示这个PendingIntent对象启动的是Activity,类似的还有getService方法、getBroadcast方法
  8. */
  9. PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
  10. NotificationCompat.Builder builder;
  11. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  12. //如果是8以上的系统。需要传一个channelId.
  13.  builder = new NotificationCompat.Builder(this, "chat");
  14. } else {
  15. builder = new NotificationCompat.Builder(this);
  16. }
  17. builder
  18. .setContentTitle("通知1") // 创建通知的标题
  19. .setContentText(content) // 创建通知的内容
  20. .setSmallIcon(R.drawable.ic_launcher_background) // 创建通知的小图标
  21. .setLargeIcon(BitmapFactory.decodeResource(getResources(),
  22. R.mipmap.ic_launcher)) // 创建通知的大图标
  23. /*
  24. * 首先,无论你是使用自定义视图还是系统提供的视图,上面4的属性一定要设置,不然这个通知显示不出来
  25. */
  26. .setWhen(System.currentTimeMillis()) // 设定通知显示的时间
  27. .setContentIntent(pi) // 设定点击通知之后启动的内容,这个内容由方法中的参数:PendingIntent对象决定
  28. //.setPriority(NotificationCompat.PRIORITY_MAX) // 设置通知的优先级
  29. .setAutoCancel(true); // 设置点击通知之后通知是否消失
  30. //.setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg"))) // 设置声音
  31. /*
  32. * 设置震动,用一个 long 的数组来表示震动状态,这里表示的是先震动1秒、静止1秒、再震动1秒,这里以毫秒为单位
  33. * 如果要设置先震动1秒,然后停止0.5秒,再震动2秒则可设置数组为:long[]{1000, 500, 2000}。
  34. * 别忘了在AndroidManifest配置文件中申请震动的权限
  35. */
   builder.setVibrate(new long[]{1000, 500, 2000});
  1. /*
  2. * 设置手机的LED灯为蓝色并且灯亮2秒,熄灭1秒,达到灯闪烁的效果,不过这些效果在模拟器上是看不到的,
  3. * 需要将程序安装在真机上才能看到对应效果,如果不想设置这些通知提示效果,
  4. * 可以直接设置:setDefaults(Notification.DEFAULT_ALL);
  5. * 意味将通知的提示效果设置为系统的默认提示效果
  6. */
  7. //.setLights(Color.BLUE, 2000, 1000)
  8. Notification notification = builder.build(); // 创建通知(每个通知必须要调用这个方法来创建)
  9. /*
  10. * 使用从系统服务获得的通知管理器发送通知,第一个参数是通知的id,不同的通知应该有不同的id,
  11. * 这样当我们要取消哪条通知的时候我们调用notificationManager(通知管理器).cancel(int id)
  12. * 方法并传入发送通知时的对应id就可以了。在这里如果我们要取消这条通知,
  13. * 我们调用notificationManager.cancel(1);就可以了
  14. * 第二个参数是要发送的通知对象
  15. */
  16. notificationManager.notify(1, notification);

到此。就创建出来一个通知了。我们可以在8.0以上的手机找到设置--》应用和通知---》应用信息---》找到你的那个应用---》应用通知就可以看到会有个类别。这里面的列表就是我们在应用里面创建的应用通道。你可以点击通道查看详情。

点击运行,我们可以看到通知可以正常的弹出来。可是对比一下就可以看到。在8以下的系统上。消息的震动我们是可以控制的。以前我们只要把:

 builder.setVibrate(new long[]{1000, 500, 2000});
修改成
 builder.setVibrate(new long[]{0});

就可以不震动了。可是这个方法在8.0的设备上并没有起作用。写了以后还是会震动。最后通过查看资料发现。8.0以后。消息的震动就不再是修改builder就可以的。我们需要修改消息通道的属性,代码如下:

  1. @TargetApi(Build.VERSION_CODES.O)
  2. private void createNotificationChannel(boolean isVibrate, String channelId, String channelName,
  3. int
  4. importance) {
  5. NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
  6. //NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
  7. if (isVibrate) {
  8. // 设置通知出现时的震动(如果 android 设备支持的话)
  9. channel.enableVibration(true);
  10. channel.setVibrationPattern(pattern);
  11. } else {
  12. // 设置通知出现时不震动
  13. channel.enableVibration(false);
  14. channel.setVibrationPattern(new long[]{0});
  15. }
  16. notificationManager.createNotificationChannel(channel);
  17. }

8.0以下的还是

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

即可。

然后我又发现一个问题。就是channel一旦createNotificationChannel出来以后。你通过代码再去修改他的属性就不再起作用。

因为我界面上有个checkBox。我想实现。勾选以后接受通知的时候就是震动的。不勾选就是不震动的。

刚开始的思路是在cb的setOnCheckedChangeListener方法里面。去修改channel的enableVibration和setVibrationPattern两个属性的值。发现没有任何作用。后来我思考是不是。因为。channel一旦生产出来就是在系统里面了。不能修改了。于是我又在修改之前。根据channelId先去查看查找有没有。如果有。

  notificationManager.deleteNotificationChannel(channelId);

我就先删除掉。然后我再重新new.并且create.即代码修改成了:

  1. cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
  2. @Override
  3. public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
  4. setChannerl(b);
  5. Log.e("zmm", "onCheckedChanged------------>" + b);
  6. }
  7. });
  1. private void setChannerl(boolean checked) {
  2. channelId = "chat";//消息通道的id,以后可以通过该id找到该消息通道
  3. String channelName = "聊天消息";//消息通道的name
  4. int importance = NotificationManager.IMPORTANCE_MAX;//通知的优先级
  5. // .具体的请自行百度。作用就是优先级的不同。可以导致消息出现的形式不一样。
  6. // MAX是会震动并且出现在屏幕的上方。设置优先级为low或者min时。来通知时都不会震动,
  7. // 且不会直接出现在屏幕上方
  8. createNotificationChannel(checked, channelId, channelName, importance);
  9. }
  1.  @TargetApi(Build.VERSION_CODES.O)
  2. private void createNotificationChannel(boolean isVibrate, String channelId, String channelName,
  3. int
  4. importance) {
  5. //先删除之前的channelId对应的消息通道.
  6. notificationManager.deleteNotificationChannel(channelId);
  7. //重新new一个消息通道。
  8. NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
  9. //是否震动
  10. if (isVibrate) {
  11. // 设置通知出现时的震动(如果 android 设备支持的话)
  12. channel.enableVibration(true);
  13. channel.setVibrationPattern(pattern);
  14. } else {
  15. // 设置通知出现时不震动
  16. channel.enableVibration(false);
  17. channel.setVibrationPattern(new long[]{0});
  18. }
  19. notificationManager.createNotificationChannel(channel);
  20. }

删除app.然后重新运行。我第一次进来。发消息是没有震动的。正确。然后勾选cb。然后重新点击发送通知。结果通知是接受到了。可是没有震动。。。。气人不!!!气人。。。

仔细看了下。代码。确定不是因为我自己的粗心哪里写错了。那就是我用的哪个方法肯定没有作用。

经过一杯茶的冷静。我在思考会不会是channelId的原因。因为虽然我删除掉了 。但是系统会不会是像一般的后台一样是个假删除。然后再用相同的id去new的时候。系统又把之前的消息通道拿出来了。如果是这样的话。那属性是没办法修改的。为了测试。我把channelId修改成动态的了。我每次勾选cb的时候。i++。然后channelid="chat"+i;为了防止越来越多的channel.我用beforeId记录之前的channelId。然后再新建的时候。先去删除beforeId.然后再新建。代码如下:

  1. cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
  2. @Override
  3. public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
  4. i++;
  5. setChannerl(b);
  6. Log.e("zmm", "onCheckedChanged------------>" + b);
  7. }
  8. });
  1. private void setChannerl(boolean checked) {
  2. channelId = "chat" + i;//消息通道的id,以后可以通过该id找到该消息通道
  3. String channelName = "聊天消息" + i;//消息通道的name
  4. int importance = NotificationManager.IMPORTANCE_MAX;//通知的优先级
  5. // .具体的请自行百度。作用就是优先级的不同。可以导致消息出现的形式不一样。
  6. // MAX是会震动并且出现在屏幕的上方。设置优先级为low或者min时。来通知时都不会震动,
  7. // 且不会直接出现在屏幕上方
  8. createNotificationChannel(checked, channelId, channelName, importance);
  9. beforeChannelId = channelId;
  10. }
  1. @TargetApi(Build.VERSION_CODES.O)
  2. private void createNotificationChannel(boolean isVibrate, String channelId, String channelName,
  3. int
  4. importance) {
  5. if (!TextUtils.isEmpty(beforeChannelId)) {
  6. //先删除之前的channelId对应的消息通道.
  7. notificationManager.deleteNotificationChannel(beforeChannelId);
  8. }
  9. //重新new一个消息通道。
  10. NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
  11. //是否震动
  12. if (isVibrate) {
  13. // 设置通知出现时的震动(如果 android 设备支持的话)
  14. channel.enableVibration(true);
  15. channel.setVibrationPattern(pattern);
  16. } else {
  17. // 设置通知出现时不震动
  18. channel.enableVibration(false);
  19. channel.setVibrationPattern(new long[]{0});
  20. }
  21. notificationManager.createNotificationChannel(channel);
  22. }

别忘了修改createNotification()方法里面的

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    builder = new NotificationCompat.Builder(this, channelId);//该处写的应该是当前的channelId。
} else {
    builder = new NotificationCompat.Builder(this);
}

然后重新运行。第一次。发通知。没有震动。OK的。勾选震动。发通知。震动了。OK的!

至此问题就解决了。为了一探究竟。想看下deleteNotificationChannel源码的实现。发现我没有下载源码。所以看不了。于是去官方文档看了下。


。英语不好就不翻译了。但是还是能看到的。如果你新建的channel和要删除的channel是同一个channelId的话。新建的channel的属性和要删除的那个channel是相同的。。。。。我境界还没达到。不知道这样设计的目的。但是应该有他们的原因。。。

重点18.0以上消息震动是通过修改channel来实现的:

if (isVibrate) {
    // 设置通知出现时的震动(如果 android 设备支持的话)
    channel.enableVibration(true);
    channel.setVibrationPattern(pattern);
} else {
    // 设置通知出现时不震动
    channel.enableVibration(false);
    channel.setVibrationPattern(new long[]{0});
}

重点2:channel一旦被create出来。修改属性没有作用,可以通过删除掉。再重新create。但是要记得要删除的channelId和要新建的channelId不能一致.

我也好久没写博客了。。之前一个月。忙着交接工作。辞职。搬家。找工作。好在。一切都再慢慢步入正轨。从一个城市到另一个城市。说后悔谈不上。不舍却有的。只是在想。是不是当初可以有更好的选择。不过回到合肥以后。确定开心了很多。在这个城市。有很多我熟悉的朋友。还有一个待我很好的朋友。总是去她家蹭饭。而且一次噩梦也没有做过。离家也近了很多。而且。在这里。我不会觉得害怕。不会觉得孤单。虽然。新公司里面我还不熟悉。但是大家看着就是很好的人。我应该可以和他们好好好相处。。最后但愿我在新公司里面可以多学点东西。嗯。接下来的日子请继续加油!!!

每日语录:

决心走一条路的时候,就不要左顾右盼,风景再美也别流连,你应当清楚自己的目的,你应当清楚你心如钢铁地追求的东西是什么,在哪里,时不时给自己提个醒。加油!
单曲循环《这些年来》





声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/575608
推荐阅读
相关标签
  

闽ICP备14008679号