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();
posted on 2017-12-12 11:09  lishbo  阅读(652)  评论(0编辑  收藏  举报