Android 通知开关状态工具类

参考博文
http://blog.csdn.net/zcllige/article/details/52444258
注意:
1.通知开关状态的获取,上面博文已经整的很详细了,本人也尝试过通过反射得到属性去越过最后系统的对是否为系统应用的检测,发现压根得不到INotificationManager的那个mAppOps属性。设置在studio中INotificationManager直接是红的,都无法去查看源代码,所以基本可以确定系统的checkCallerIsSystem();是无法跳过的,也就是说<4.3的系统是无法获取通知开关状态的。
2.关于小米手机的奇怪现象
第一次安装,是可以在通知管理中进行开关通知
卸载应用有,再次重新安装,再去通知栏管理中去开关通知,发现压根没有效果,通知栏会一直处于开启状态,并且关不掉。
功具类功能描述:
1.查看开关状态
2.提供获取状态后的回调接口
3.如果没有开启通知,且不需要自己处理,则默认会弹出对话框,提示去设置中开启通知,如果需要自己处理,则在回调中自己处理即可。
4.如果开启了通知,则在回调中写有通知的业务逻辑。
5.有一个基于DialogFragment的BaseDialog,可通过构造形式适配标题、内容、左按钮、右按钮形式的Dialog。
代码:

package com.gjg.utils;

import android.app.Activity;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.RequiresApi;
import android.support.v4.app.FragmentManager;

import com.gjg.R;
import com.gjg.base.dialog.BaseDialog;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author : gjg
 * @date : 2017/6/12
 * FileName: NotificationCheckUtil
 * @description:
 *  4.3以下,由于系统使用的AIDL机制中无法通过反射去改变其检测是否为系统应用的逻辑,所以无法得到通知开关状态
 *  这个是系统强制要求,所以该方法只适用于4.3及其以上,以下默认返回true
 */


public class NotificationCheckUtil {
   
    private static final String CHECK_OP_NO_THROW = "checkOpNoThrow";
    private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";

    public static boolean notificationIsOpen(Context context){
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
  //API19+
            return notificationCheckFor19Up(context);
        }
        return false;
    }
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private static boolean notificationCheckFor19Up(Context context){
        AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        ApplicationInfo applicationInfo = context.getApplicationInfo();
        String pkg = context.getApplicationContext().getPackageName();
        int uid = applicationInfo.uid;
        Class appOpsClass;

        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 op = (int) opPostNotificationValue.get(Integer.class);
            return ((int)checkOpNoThrowMethod.invoke(appOpsManager,op,uid,pkg) == AppOpsManager.MODE_ALLOWED);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }

    public interface NotificationCheckResultListener{
   
        void checkResult(boolean hasOpenNotification);
    }

    public static void checkNotificationOpend(final Activity context,
                                              NotificationCheckResultListener listener,
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值