android实现检测app是否有通知权限,没有就跳转去设置,设置成功返回时并测试发出一条通知消息

本文详细介绍了如何在Android应用程序中检查和管理通知权限,包括使用AppOpsManager API进行权限检查和更改,以及如何在权限被拒绝时引导用户前往设置页面开启通知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.判断是否有通知权限

2.没有的话,弹出一个对话框,提示用户是否去设置,用户点击确定后跳转到设置页面

3.手动设置权限成功后,结果会返回到

onActivityResult方法中,其中返回的请求码等于传入的码时,并且结果码等于2,编辑正确设置了,此时就可以调用发起通知。

4.正式开始:首先先写好一个工具类,用来判断是否有通知权限。

工具类名:NotificationPermissions

首先我们需要理解什么是appOps,这是一个android的原生权限管理,当手机系统启动时,就会自动启动这个相关的服务。

api:appopsmanager

整体的工作框架:

解释:当我们打开了设置页面的ui,并点击允许通知时,就会change permission

,改变app权限主要是通过appopsmanager这个类来实现。appopsmanager将会和appopsservice进行交互,  用户改变的权限将会存储在/data/system/appops.xml文件中。appopsservice也会被注入到其他各种服务中,进行权限的检测。

相关接口的api:

int checkop(String op,int uid,String  packageName)判断应用是否含有某个权限

int noteop(string op,int uid,String packageName)和checkop使用一样,但是会在检测的时候记录一下

int checkopnothrow(string op,int uid,String packageName)和checkop类似,但是权限错误,不会报SecurityException错误,会返回appopsmanager.mode_error

int noteopnothrow(string op,int uid,String packageName)和checkopnothrow类似,但是不会返回appopsmanager.mode_error

void setMode(int code,int uid,String packageName,int mode)这个是我们最需要的方法,用来改变APP的权限。code代表具体的权限,mode表示(允许/禁止/提示)。

正式代码:

public class NotificationPermissions{

           private final string checkopnothrow="CHECKOPNOTHROW";//将要获取的方法,

           private final string op_post_notification="OP_POST_NOTIFICATION";将要获取的字段

 

           public boolean isNotification(Context context){//需要将上下文传入进来

                        //1.获取appopsmanager

                  AppOpsManager   appopsmanager=(AppOpsManager   )context.getSystemtService(Context.APP_OPS_SERBIVE);

                  //2.获取applicationContextInfo信息

         ApplicationInfo appInfo =context.getApplicationInfo();

                //3.获取包名

                     String  packageName=appInfo,packageName;//或者                                                   packageName=context.getAppliacationContext().getPackageName();       

                     int uid=appInfo.uid;用户身份                                       

                //4.实例化该packageName类

                 Class cla=class.forName(AppOpsManager.class.getName());

               //5.通过反射获取要调用的appopsmanager中的方法

                Method  checkOpNoThrowMethod=appopsmanager.getMthod(checkopnothrow,Integer.TYPE,Integer.TYPE,String.class);

                 checkOpNoThrowMethod这个方法就是上面提到过的红色第三个方法。

               Field opPostNotificationValue=appopsmanager.getDeclaredField(op_post_notification);

              int value=(Integer)opPostNotificationValue.get(Integer.class);

           return   checkOpNoThrowMethod.invoke(appopsmanager,value,uid,packageName)==AppOpsManager.MODE_ALLOWED;//MODE_ALLOWED表示已经允许了

           }

}

 

 

//6.以下代码是在mainactivity中,当权限检测没有时,执行的方法

//创建通知消息的方法
private void createNotification(){
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);//使用NotificationCompat build通知消息
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setContentTitle("新消息");
        builder.setContentText("你有一条新的消息");
        builder.setNumber(num++);
        builder.setAutoCancel(true);//设置点击通知跳转页面后,通知消失
        Intent intent = new Intent(this,MainActivity.class);//点击后要跳转的页面
//PendingIntent ,不会立即跳转,是将要跳转到某个页面,正好用于点击通知后的操作
        PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(pi);
        Notification notification = builder.build();
    NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);//通知管理器
    Log.e("xx","新消息");
    mNotificationManager.notify(NO_1,notification);//发送
    Log.e("xx","你有一条新的消息");
}

//若是没有权限 ,跳转
private void gotoSet(){
    if (!NotificationPermissions.isNotificationEnabled(this)) {
        final AlertDialog dialog = new AlertDialog.Builder(this).create();
        dialog.show();
        View view = View.inflate(this, R.layout.dialog, null);
        dialog.setContentView(view);
        TextView context = (TextView) view.findViewById(R.id.tv_dialog_context);
        context.setText("检测到您没有打开通知权限,是否去打开");
        TextView confirm = (TextView) view.findViewById(R.id.btn_confirm);
        confirm.setText("确定");
        confirm.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                dialog.cancel();
                Intent localIntent = new Intent();
                localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                if (Build.VERSION.SDK_INT >= 9) {//系统8.0以上的
                    localIntent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
                    localIntent.setData(Uri.fromParts("package", MainActivity.this.getPackageName(), null));
                } else if (Build.VERSION.SDK_INT <= 8) {//系统8.0以下的
                    localIntent.setAction(Intent.ACTION_VIEW);
                    localIntent.setClassName("com.android.settings",
                            "com.android.settings.InstalledAppDetails");
                    localIntent.putExtra("com.android.settings.ApplicationPkgName",
                            MainActivity.this.getPackageName());
                }
                startActivityForResult(localIntent,REQUESTCODE);
            }
        });

        TextView cancel = (TextView) view.findViewById(R.id.btn_off);
        cancel.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                dialog.cancel();
            }
        });
    }
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode==2){
            if(requestCode==REQUESTCODE){
                createNotification();//发送测试通知
            }
    }
}

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值