如何监听Google Nearby权限确认/拒绝?寻求兼容API16+的优化方案
解决方案:移除二级页面,依赖Google官方对话框兼容API 16+
针对你的需求,我整理了一套完全不需要二级页面、依赖Google官方权限/启用对话框,且兼容API 16+的可行方案,核心是利用Google API Client本身的resolution机制来替代自定义页面,具体步骤如下:
1. 重构OnConnectionFailedListener逻辑,直接调用官方对话框
当OnConnectionFailedListener触发时,不要启动自定义二级页面,而是判断ConnectionResult是否有可解决的方案,若有则直接调用官方的分辨率处理流程,这会自动弹出Google的权限提示或Nearby启用对话框:
private static final int REQUEST_CODE_NEARBY_RESOLUTION = 1001; private GoogleApiClient mGoogleApiClient; // 初始化GoogleApiClient时设置监听器 mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Nearby.MESSAGES_API) .addConnectionCallbacks(...) .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { if (connectionResult.hasResolution()) { try { // 启动官方权限/启用对话框,无需自定义二级页面 connectionResult.startResolutionForResult(MainActivity.this, REQUEST_CODE_NEARBY_RESOLUTION); } catch (IntentSender.SendIntentException e) { Log.e(TAG, "Failed to launch resolution dialog", e); // 异常情况下自动重试连接 mGoogleApiClient.connect(); } } else { // 无解决路径时,提示用户手动处理 Toast.makeText(MainActivity.this, "请手动开启Nearby功能并授予必要权限", Toast.LENGTH_LONG).show(); } } }) .build();
2. 在onActivityResult中自动重试Nearby连接
用户处理完官方对话框后,系统会回调onActivityResult,这里直接重新发起GoogleApiClient连接,自动检查Nearby是否可用:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_NEARBY_RESOLUTION) { // 用户完成对话框操作后,自动重试连接 if (mGoogleApiClient != null && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } }
3. 兼容API 16+的权限处理
针对不同API级别做适配,确保低版本设备也能正常工作:
- API 16-22:权限在安装时授予,只需通过上述resolution流程处理Nearby功能启用即可。
- API 23+:需要提前检查危险权限(如
ACCESS_FINE_LOCATION,Nearby核心依赖),若未授予则发起权限请求,之后再尝试连接:
private static final int REQUEST_CODE_LOCATION_PERMISSION = 1002; private void attemptNearbyConnection() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_LOCATION_PERMISSION); return; } } // 权限就绪,发起Nearby连接 if (mGoogleApiClient != null && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE_LOCATION_PERMISSION) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 权限授予成功,继续连接Nearby attemptNearbyConnection(); } else { Toast.makeText(this, "需要位置权限才能使用Nearby功能", Toast.LENGTH_LONG).show(); } } }
4. 额外优化建议
- 避免重复连接:每次发起连接前检查
mGoogleApiClient.isConnected()和mGoogleApiClient.isConnecting()状态,防止重复请求。 - 配置变化处理:在
onResume或onRestoreInstanceState中重新尝试连接,避免屏幕旋转等场景下连接断开。 - 兜底提示:若
startResolutionForResult失败,可引导用户前往系统设置的Nearby页面手动开启功能。
内容的提问来源于stack exchange,提问作者Ortiz
相关产品推荐
相关产品推荐

