Android:判断应用程序接收通知开关是否打开
之前在使用某个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,确实存在这个方法,这样来判断就方便很多了。
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
boolean areNotificationsEnabled = notificationManagerCompat.areNotificationsEnabled();