最近,小白弄一个通知,模拟器上通知显示还是正常的,但真机测试就出现通知不显示的问题,并且也不报错,嘿,可给它牛坏了。

百度半天也没解决问题,然后就在真机的应用权限设置里发现,原来通知权限是默认关闭的,打开后,唉,好了,通知可以接收了。

但问题又来了,用户又不知道要开启通知权限,所以我一开始是希望有没有相关的“危险权限”,借助运行时权限让用户打开应用时,直接让用户授权。比如:

//检测权限
if(Context.checkSelfPermission(this,Manifest.permission.权限名)
!= PackageMananger.PERMISSION_GRANTED){ActivityCompat.requestPermissions(this,new String[]{Manifest.Permission.权限名},1);
}
//对请求结果处理
@Override
public void onRequsetPermissionsResult(int requestCode,
String[] permissions,int[] grantResults){switch (requestCode){case 1:if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){//请求成功}}
}

当然,查了很久的权限表,没找到,(要是有小伙伴们找到了,记得告诉我哦,希望不是我眼花了)。

所以,我决定手动写一个检测通知权限是否开启的类,NotificationUtil.class, 这个类有一个静态方法,返回值Boolean为通知权限是否开启,在需要检测权限的地方 类名. 方法获取:
详细代码见一位大神的博客:
链接: Android获取应用通知栏权限,并跳转通知设置页面(全版本适配).

public class NotificationUtil {private static final String CHECK_OP_NO_THROW = "checkOpNoThrow";private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";//调用该方法获取是否开启通知栏权限public static boolean isNotifyEnabled(Context context) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {return isEnableV26(context);} else {return isEnabledV19(context);}}/*** 8.0以下判断** @param context api19  4.4及以上判断* @return*/@RequiresApi(api = Build.VERSION_CODES.KITKAT)private static boolean isEnabledV19(Context context) {AppOpsManager mAppOps =(AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);ApplicationInfo appInfo = context.getApplicationInfo();String pkg = context.getApplicationContext().getPackageName();int uid = appInfo.uid;Class appOpsClass = null;try {appOpsClass = Class.forName(AppOpsManager.class.getName());Method checkOpNoThrowMethod =appOpsClass.getMethod(CHECK_OP_NO_THROW,Integer.TYPE, Integer.TYPE, String.class);Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION);int value = (Integer) opPostNotificationValue.get(Integer.class);return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) ==AppOpsManager.MODE_ALLOWED);} catch (Exception e) {e.printStackTrace();}return false;}/*** 8.0及以上通知权限判断** @param context* @return*/private static boolean isEnableV26(Context context) {ApplicationInfo appInfo = context.getApplicationInfo();String pkg = context.getApplicationContext().getPackageName();int uid = appInfo.uid;try {NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);Method sServiceField = notificationManager.getClass().getDeclaredMethod("getService");sServiceField.setAccessible(true);Object sService = sServiceField.invoke(notificationManager);Method method = sService.getClass().getDeclaredMethod("areNotificationsEnabledForPackage", String.class, Integer.TYPE);method.setAccessible(true);return (boolean) method.invoke(sService, pkg, uid);} catch (Exception e) {return true;}}
}

当获取到权限是关闭状态,建立一个对话框AlertDialog引导用户开启,

 public void produceAlertDialog(){AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle("通知权限开启");builder.setMessage("检测到系统禁止了应用通知权限,我们希望您能开启通知权限,以便接收应用重要通知");builder.setCancelable(false);builder.setPositiveButton("允许", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {intenttoOpen();//跳转到打开权限通知界面}});builder.setNegativeButton("拒绝", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {finish();}});builder.show();}

打开系统通知权限界面的方法:

public void intenttoOpen(){Intent localIntent = new Intent();//直接跳转到应用通知设置的代码:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//8.0及以上localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");localIntent.setData(Uri.fromParts("package", getPackageName(), null));} else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0以上到8.0以下localIntent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");localIntent.putExtra("app_package", getPackageName());localIntent.putExtra("app_uid", getApplicationInfo().uid);} else if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {//4.4localIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);localIntent.addCategory(Intent.CATEGORY_DEFAULT);localIntent.setData(Uri.parse("package:" + getPackageName()));} else {//4.4以下没有从app跳转到应用通知设置页面的Action,可考虑跳转到应用详情页面,localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);if (Build.VERSION.SDK_INT >= 9) {localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");localIntent.setData(Uri.fromParts("package", getPackageName(), null));} else if (Build.VERSION.SDK_INT <= 8) {localIntent.setAction(Intent.ACTION_VIEW);localIntent.setClassName("com.android.settings", "com.android.setting.InstalledAppDetails");localIntent.putExtra("com.android.settings.ApplicationPkgName", getPackageName());}}startActivity(localIntent);
}

这样,通知问题就完美解决了,哦,对了, Android 8.0对于通知进行了一些小的修改,加入了一个 NotificationChannel类,对通知的部分属性进行了分类管理。具体实现如下:


//建立通知部分格式 NotificationChannel, 参数Channelid, Channel名, 优先级(1,2,3,4,5)public void createNotificationChanneler(String c_channelid,String c_channelname,int c_importance){NotificationManager manager  = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);//检测 Channel是否已经被创建了,避免重复创建if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//检测Android版本if (manager.getNotificationChannel(c_channelid)!=null){return; }//要是没被创建那么NotificationChannel notificationChannel = new NotificationChannel(c_channelid,c_channelname,c_importance);notificationChannel.enableLights(true);//开启提示灯notificationChannel.enableVibration(true);//开启震动notificationChannel.setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg")),null);notificationChannel.setBypassDnd(true);//可绕过免打扰模式notificationChannel.setImportance(c_importance);//设置优先级notificationChannel.setLightColor(Color.RED);//设置提示灯颜色notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);//设置锁屏界面图标可见notificationChannel.setShowBadge(true);//有图标notificationChannel.setVibrationPattern(new long[]{0,1000,1000,1000});manager.createNotificationChannel(notificationChannel);}else {return;}}//创建Notification//创建 notificationChannelcreateNotificationChanneler("channelone","channelonename", ConstantString.IMPORTANCE_DEFAULT);Intent intent = new Intent();intent.setClass(this,TenthtoActivity.class);PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);Notification notification = new NotificationCompat.Builder(this,"channelone").setContentTitle("一分钱抽Iphone~")//设置标题.setContentText("你参与的一分钱抽奖活动开始啦!机不可失失不再来!")//设置内容.setWhen(System.currentTimeMillis())//设置通知发出的时间.setSmallIcon(R.mipmap.orange)//设置左上方小图标.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.orange))//设置右边大图标.setContentIntent(pi)//设置跳转对象.setAutoCancel(true)//设置点击后自动取消标题栏图标提示.build();manager.notify(1,notification);

Android开发,关于模拟器通知显示正常,真机测试真机通知无效问题相关推荐

  1. Android开发笔记(一百六十八)为应用绑定通知渠道并展示消息角标

    为了分清消息通知的轻重缓急,从Android8开始新增了通知渠道,并且必须指定通知渠道才能正常推送消息.一个应用允许拥有多个通知渠道,每个渠道的重要性各不相同,有的渠道消息在通知栏被折叠成小行,有的渠 ...

  2. Android开发之模拟器

    1.转载:模拟器包含这些: https://blog.csdn.net/fuhanghang/article/details/96728205?ops_request_misc=%257B%2522r ...

  3. Android开发环境——模拟器AVD相关内容汇总

    Android开发环境将分为SDK相关内容.Eclipse ADT相关内容.模拟器AVD相关内容.调试器DDMS相关内容.日志LogCat相关内容.连接驱动ADB相关内容.内存泄露检测工具MAT相关内 ...

  4. Android开发:隐藏和显示底部导航栏

    描述:视频播放器实现全屏和小屏互相切换时,显示和隐藏底部导航栏的方法 该例子设置的Activity是去除状态栏和标题栏,全屏显示布局和电量等信息.Manifest文件 theme如下: <act ...

  5. Mac OSX Android 开发环境 模拟器报错

    直接下载ADT mac版 模拟器报错处理 1. 显示隐藏文件命令 显示:defaults write com.apple.finder AppleShowAllFiles -bool true 隐藏: ...

  6. Android开发--调试--模拟器--加快模拟器速度

    方法一: 关闭模拟器自动侦测手机旋转的设置 具体位置为:设置 - 声音和显示 - 关闭"方向"的选项 加大RAM的大小,启用snapshot 设定后模拟器运行速度明显提升了很多 方 ...

  7. Android开发之仿微信显示更多文字的View

    最近开发需求中要模仿微信朋友圈文章的展开收起功能,网上找了找,发现都有问题,于是乎自己在前辈的基础上进行了一定量的修改,下边将源码贴出来供大家参考: 1.主Activity布局文件就不粘贴了,很简单, ...

  8. 【Android 应用开发】Android开发 使用 adb logcat 显示 Android 日志

    作者 : 万境绝尘  转载请著名出处 eclipse 自带的 LogCat 工具太垃圾了, 开始用 adb logcat 在终端查看日志; 1. 解析 adb logcat 的帮助信息 在命令行中输入 ...

  9. Android开发-下载网络图片并显示到本地

    Android下载网络图片的流程是: 发送网络请求->将图片以流的形式下载下来->将流转换为Bitmap并赋给ImageView控件. 注意点 最新的Android系统不可以在主线程上请求 ...

最新文章

  1. 坑爹的微信支付(签名错误)
  2. 数据库范式的思考以及数据库的设计
  3. 【内网渗透工具】炫彩蛇安装教程
  4. WSDM 2021 | 基于双向推理的多跳知识库问答技术
  5. VTK:KDTree时序用法实战
  6. VTK:可视化算法之TubesWithVaryingRadiusAndColors
  7. redis 命令 释放连接_Redis---gt;02
  8. shell中的getopt与getopts
  9. ASP.NET验证码
  10. 工作基本功:问题解决不了或不满意,不要重复,应该向上级反映或投诉
  11. 处理器后面的字母含义_工业铝型材名称的含义是什么
  12. HyperX旋火游戏鼠标推荐——轻量化鼠标设计界的艺术品
  13. GUI 尚学堂马士兵视频上留的作业,自己改出来的
  14. Threejs导入OBJ模型出错的一些经验之谈
  15. 【Go】dep使用介绍
  16. [BZOJ5109]大吉大利,晚上吃鸡!
  17. 安兔兔苹果html5排行榜,iPhone8Plus最强?9月安兔兔手机性能排行榜出炉
  18. 水清冷冷:PSCC2019/PSCC2020安装教程和学习技巧(附工具)
  19. 有关session生命周期
  20. 何海涛算法面试题感悟之五:查找最…

热门文章

  1. 怎样养出一个快乐温暖的孩子?分享具体可行的方法
  2. 深入解析UUID及其应用
  3. Python学生成绩管理系统(源码+数据库)
  4. PHP利用websocket实现客户端请求ws协议功能
  5. 运维人员的职业升级道路
  6. git基于远程分支创建新分支
  7. Last Week in Milvus
  8. 给所有男人和女人的人生忠告Z
  9. 快速幂和矩阵快速幂详解+模板
  10. 集 成 运 算 同 相放大器和反 向放大器的选择