zoukankan      html  css  js  c++  java
  • Android:判断应用程序接收通知开关是否打开

    之前在使用某个App的时候,经常收到推送广告通知,于是在系统设置里面,关闭接收通知,果然清静了很多。后来再次打开App使用的时候,发现里面弹出对话框,提示用户把接收通知的开关打开,于是有点好奇,这个App是如何判断用户通知开关关闭状态的。就是类似下面这样的东东:

    App通知开关

    后来查了一些资料,发现是通过反射来实现的,示例代码如下:

    package com.example.notificationtest;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import android.annotation.TargetApi;
    import android.app.Activity;
    import android.app.AppOpsManager;
    import android.content.Context;
    import android.content.pm.ApplicationInfo;
    import android.os.Build;
    import android.os.Bundle;
    import android.widget.TextView;
    
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            TextView tvHint = (TextView) findViewById(R.id.tvHint);
    
            tvHint.setText("通知开关是否打开-->" + isNotificationEnable(this));
        }
    
        /*
         * 判断通知权限是否打开
         */
        private boolean isNotificationEnable(Context context) {
            AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(APP_OPS_SERVICE);
            ApplicationInfo appInfo = context.getApplicationInfo();
    
            String pkg = context.getApplicationContext().getPackageName();
            int uid = appInfo.uid;
    
            Class appOpsClass = null; /* Context.APP_OPS_MANAGER */
    
            try{
                appOpsClass = Class.forName(AppOpsManager.class.getName());
                Method checkOpNoThrowMethod  = appOpsClass.getMethod("checkOpNoThrow", Integer.TYPE, Integer.TYPE, String.class);
    
                Field opPostNotificationValue = appOpsClass.getDeclaredField("OP_POST_NOTIFICATION");
                int value = (int)opPostNotificationValue.get(Integer.class);
                return ((int)checkOpNoThrowMethod.invoke(mAppOps,value, uid, pkg) == AppOpsManager.MODE_ALLOWED);
            }catch(Exception e){
                e.printStackTrace();
            }   
            return true;
        }
    }
    

    这个方法很好,但是还存在缺陷。AppOpsManager这个类是api 19以上才添加的,所以android4.3以下这个方法就失效了。

    据说android api 24可以使用NotificationManagerCompat.areNotificationsEnabled()来判断。查看官方Api,确实存在这个方法,这样来判断就方便很多了。
    Api

    NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
    boolean areNotificationsEnabled = notificationManagerCompat.areNotificationsEnabled();
  • 相关阅读:
    Spring MVC中@ControllerAdvice注解实现全局异常拦截
    IDEA一个窗口打开多个项目
    IntelliJ IDEA中Spring Boot项目使用spring-boot-devtools无法实现热部署/热更新的问题解决
    Java中String/StringBuffer/StringBuilder区别(转)
    IDEA查看源码时提示:Library source does not match the bytecode for class的问题分析
    忙的一天的复盘
    Apollo专题
    使用Spring JPA中Page、Pageable接口和Sort类完成分页排序【专题】
    公众号开发之wx-tools+springboot应用实战-音乐爬虫推送[JAVA]
    [LeetCode] 152. Maximum Product Subarray 求最大子数组乘积
  • 原文地址:https://www.cnblogs.com/lishbo/p/9956024.html
Copyright © 2011-2022 走看看