参考博文
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,