Cordova自定义插件请求权限抛异常:SDK22迁23后找不到onRequestPermissionResult
Cordova自定义插件SDK23迁移:解决
NoSuchMethodException: onRequestPermissionResult问题 刚碰到过一模一样的坑,给你拆解下问题根源和解决办法:
问题根源
Android 6.0(API 23)引入了动态权限机制,而Cordova插件的权限处理逻辑在这个版本后有了明确的规范要求。你的报错是因为插件里的deliverPermissionResult方法通过反射调用onRequestPermissionResult时,找不到符合签名要求的方法——要么是你没正确实现这个方法,要么是反射的参数匹配错了。
解决方案
1. 确保onRequestPermissionResult方法签名完全正确
Cordova要求插件类中的权限结果回调方法必须是以下签名(不能改参数类型、数量,必须是public):
@Override public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) throws JSONException { super.onRequestPermissionResult(requestCode, permissions, grantResults); // 在这里写你的权限结果处理逻辑 if (requestCode == YOUR_PERMISSION_REQUEST_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限通过,执行原本的插件逻辑 } else { // 权限被拒绝,给用户提示或者终止操作 } } }
注意:必须加上@Override注解(确保覆盖CordovaPlugin的方法),而且方法的访问修饰符是public,参数类型一个都不能错。
2. 修复deliverPermissionResult中的反射逻辑
如果你的插件里是通过反射传递权限结果,要确保反射调用的是正确的方法签名。错误的反射代码会找不到方法,比如之前可能写的是无参或者参数类型不匹配的方法查找。正确的反射代码应该是:
private void deliverPermissionResult(int requestCode, String[] permissions, int[] grantResults) { try { // 查找带有int, String[], int[]参数的onRequestPermissionResult方法 Method method = getClass().getDeclaredMethod( "onRequestPermissionResult", int.class, String[].class, int[].class ); method.invoke(this, requestCode, permissions, grantResults); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } }
3. 升级Cordova Android依赖版本
确保你的Cordova Android版本至少是5.0.0以上(这个版本开始适配Android 6.0的动态权限)。如果是更旧的版本,不仅权限处理逻辑不兼容,还可能出现各种奇怪的API不匹配问题。
4. 推荐:改用Cordova官方权限处理方式
避免自己写反射逻辑,直接用Cordova提供的API请求权限:
在插件的execute方法中,当需要权限时,调用:
cordova.requestPermissions(this, YOUR_PERMISSION_REQUEST_CODE, new String[]{Manifest.permission.YOUR_PERMISSION});
然后上面写的onRequestPermissionResult就会自动被Cordova调用,不需要自己写deliverPermissionResult的反射逻辑,从根源上避免反射出错。
验证步骤
- 修正方法签名和反射代码后,重新编译插件
- 卸载旧的App,重新安装测试
- 触发权限请求,检查是否还会抛出
NoSuchMethodException
内容的提问来源于stack exchange,提问作者Sharon
相关产品推荐
相关产品推荐

