Xamarin Android打开位置设置失败,旧方案失效求可行解决办法
问题描述
此前尝试通过Intent跳转到应用专属位置设置页,原方案现已失效。使用以下代码时,持续抛出ActivityNotFoundException:
try { CrossCurrentActivity.Current.Activity.StartActivity(new Intent( Android.Provider.Settings.ActionLocationSourceSettings, Android.Net.Uri.Parse("package:" + Android.App.Application.Context.PackageName))); } catch (Exception e) { OpenAppSettings(); }
错误日志如下:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.settings.LOCATION_SOURCE_SETTINGS dat=package: } at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2200) at android.app.Instrumentation.execStartActivity(Instrumentation.java:1839) at android.app.Activity.startActivityForResult(Activity.java:5471) at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:647) at android.app.Activity.startActivityForResult(Activity.java:5429) at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:628) at android.app.Activity.startActivity(Activity.java:5927) at android.app.Activity.startActivity(Activity.java:5894) at androidx.appcompat.app.AlertDialog_IDialogInterfaceOnClickListenerImplementor.n_onClick(Native Method) at androidx.appcompat.app.AlertDialog_IDialogInterfaceOnClickListenerImplementor.onClick(AlertDialog_IDialogInterfaceOnClickListenerImplementor.java:31) at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7872) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
另外发现Google Accompanist包中的bgLocationPermissionState.launchPermissionRequest()可打开位置设置,但不清楚其实现逻辑,寻求可行解决方案。
原因分析
ACTION_LOCATION_SOURCE_SETTINGS是系统级Intent Action,用于打开全局位置服务开关页,并不支持通过package: URI参数跳转到应用专属的位置设置页。部分旧Android版本可能存在兼容漏洞允许此操作,但当前系统已限制该Intent的参数格式,导致无法找到匹配的Activity处理请求。
可行解决方案
1. 直接打开系统全局位置设置页
如果仅需引导用户开启位置服务,可去掉package: URI参数,直接调用系统标准Intent:
try { var locationIntent = new Intent(Android.Provider.Settings.ActionLocationSourceSettings); CrossCurrentActivity.Current.Activity.StartActivity(locationIntent); } catch (Exception e) { OpenAppSettings(); }
2. 跳转到应用专属权限设置页(推荐)
若需引导用户配置应用的位置权限(而非全局位置开关),使用系统标准的ACTION_APPLICATION_DETAILS_SETTINGS Intent,该Intent兼容性强,可直接打开应用的详情设置页(包含权限管理模块):
try { var appSettingsIntent = new Intent(Android.Provider.Settings.ActionApplicationDetailsSettings); var appUri = Android.Net.Uri.FromParts("package", Android.App.Application.Context.PackageName, null); appSettingsIntent.SetData(appUri); CrossCurrentActivity.Current.Activity.StartActivity(appSettingsIntent); } catch (Exception e) { OpenAppSettings(); }
3. Accompanist launchPermissionRequest() 逻辑说明
Accompanist的权限组件会自动处理权限状态:当位置权限被用户永久拒绝(勾选“不再询问”)时,组件会触发跳转至应用权限设置页,其底层核心逻辑就是使用上述ACTION_APPLICATION_DETAILS_SETTINGS Intent。
如果项目已引入Accompanist,直接调用launchPermissionRequest()即可,它会自动完成权限状态判断和跳转;若未引入,使用上述原生代码可实现完全相同的效果。
内容的提问来源于stack exchange,提问作者zyzzyxx

