Xamarin Android请求运行时权限无法正常工作



因此,我试图要求用户使用我要创建的应用程序上的位置。我在Android清单中包括了许可

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

以及在我的飞溅性页面中,启动屏幕在哪里,我希望我的权限出现给用户,我将以下代码放在:

中:
namespace Cabiee.Droid
{
[Activity(Theme  = "@style/Theme.Splash",
    MainLauncher = true,
    NoHistory = true,
    Icon = "@drawable/CabieBackground")]
public class SplashActivity : Activity
{
    protected async override void OnCreate(Bundle savedInstanceState)
    {
        await TryToGetPermissions();

        base.OnCreate(savedInstanceState);
        System.Threading.Thread.Sleep(500);
        StartActivity(typeof(Login));
        // Create your application here
    }

    #region RuntimePermissions
    async Task TryToGetPermissions()
    {
        if ((int)Build.VERSION.SdkInt >= 23)
        {
            await GetPermissionsAsync();
            return;
        }

    }
    const int RequestLocationId = 0;
    readonly string[] PermissionsGroupLocation =
        {
                        //TODO add more permissions
                        Manifest.Permission.AccessCoarseLocation,
                        Manifest.Permission.AccessFineLocation,
         };
    async Task GetPermissionsAsync()
    {
        const string permission = Manifest.Permission.AccessFineLocation;
        if (CheckSelfPermission(permission) == (int)Android.Content.PM.Permission.Granted)
        {
            //TODO change the message to show the permissions name
            Toast.MakeText(this, "Special permissions granted", ToastLength.Short).Show();
            return;
        }
        if (ShouldShowRequestPermissionRationale(permission))
        {
            //set alert for executing the task
            AlertDialog.Builder alert = new AlertDialog.Builder(this);
            alert.SetTitle("Permissions Needed");
            alert.SetMessage("The application need special permissions to continue");
            alert.SetPositiveButton("Request Permissions", (senderAlert, args) =>
            {
                RequestPermissions(PermissionsGroupLocation, RequestLocationId);
            });
            alert.SetNegativeButton("Cancel", (senderAlert, args) =>
            {
                Toast.MakeText(this, "Cancelled!", ToastLength.Short).Show();
            });
            Dialog dialog = alert.Create();
            dialog.Show();

            return;
        }
        RequestPermissions(PermissionsGroupLocation, RequestLocationId);
    }
    public override async void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
    {
        switch (requestCode)
        {
            case RequestLocationId:
                {
                    if (grantResults[0] == (int)Android.Content.PM.Permission.Granted)
                    {
                        Toast.MakeText(this, "Special permissions granted", ToastLength.Short).Show();
                    }
                    else
                    {
                        //Permission Denied :(
                        Toast.MakeText(this, "Special permissions denied", ToastLength.Short).Show();
                    }
                }
                break;
        }
        //base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }
    #endregion
}

但是,并未要求用户提供permssions。我认为这可能与等待的TryTogetpermissions()有关;朝向代码开始的线,实际上并未调用TryTogetPermissions,因此它不起作用。

任何帮助将不胜感激。

谢谢!

我对完全相同的事情有一个工作解决方案,这是以下内容:

在您的OnCreate方法中检查现有权限:

 if (!(CheckPermissionGranted(Manifest.Permission.AccessCoarseLocation) &&
            CheckPermissionGranted(Manifest.Permission.AccessFineLocation)))
        {
            RequestLocationPermission();
        }
        else
        {
            InitializeLocationManager();
        }
        InitPageWidgets();

何时获得检查权限是这样的方法:

 [Export]
    public bool CheckPermissionGranted(string Permissions)
    {
        // Check if the permission is already available.
        if (ActivityCompat.CheckSelfPermission(this, Permissions) != Permission.Granted)
        {
            return false;
        }
        else
        {
            return true;
        }

    }

和请求权限代码看起来像这样:

  private void RequestLocationPermission()
    {
        if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.AccessFineLocation))
        {
            // Provide an additional rationale to the user if the permission was not granted
            // and the user would benefit from additional context for the use of the permission.
            // For example if the user has previously denied the permission.
            ActivityCompat.RequestPermissions(this, PermissionsLocation, REQUEST_LOCATION);
        }
        else
        {
            // Camera permission has not been granted yet. Request it directly.
            ActivityCompat.RequestPermissions(this, PermissionsLocation, REQUEST_LOCATION);
        }
    }

如果您不需要异步/等待,则下面是我在需要相机权限的应用程序中所做的。它适合我的需求,也许也会对您。

您的实现将变得更加简单,因为您无需在OnRequestPermissionsResult()中迭代多个结果。我必须这样做,因为我的应用需要保存图片,因此在加载相机接口/活动之前需要相机和WriteExternalStroseprissions。

[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.Landscape)]
public class MainLoaderActivity : AppCompatActivity {
    private const string LOG_TAG = "CAMERA2_LOG";        
    private const int PERMISSION_REQUEST_CODE_CAMERA_USAGE = 4500;  // Arbitrary number to identify our permissions required for camera app usage
    private Button btnLoadCameraActivity;
    protected override void OnCreate(Bundle savedInstanceState) {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.main_loader);
        btnLoadCameraActivity = FindViewById<Button>(Resource.Id.btnLoadCameraActivity);
        btnLoadCameraActivity.Click += btnLoadCameraActivity_Click;
    }
    private void btnLoadCameraActivity_Click(object sender, EventArgs e) {
        // Using the camera on Android 6.0 and later requires a run-time permissions granting by the user.
        // So, check to see if user manually enabled in Settings, or previously was prompted in this app and was granted access.  If not, we'll prompt them...
        if (CheckSelfPermission(Android.Manifest.Permission.Camera) == Permission.Granted && 
            CheckSelfPermission(Android.Manifest.Permission.WriteExternalStorage) == Permission.Granted) {
            // We have both permissions necessary to run the Camera interface...
            StartActivity(typeof(CameraActivity));
            return;
        }
        // If we get here, at least one of the required permissions hasn't been approved, so find out which one and request accordingly...
        var listPermissions = new System.Collections.Generic.List<string>();
        // Build array of permissions needed for Camera usage
        if (CheckSelfPermission(Android.Manifest.Permission.Camera) != Permission.Granted) {
            Log.Warn(LOG_TAG, "CheckSelfPermission(Camera) not yet granted - will prompt user for permission");
            listPermissions.Add(Android.Manifest.Permission.Camera);
        }
        if (CheckSelfPermission(Android.Manifest.Permission.WriteExternalStorage) != Permission.Granted) {
            Log.Warn(LOG_TAG, "CheckSelfPermission(WriteExternalStorage) not yet granted - will prompt user for permission");
            listPermissions.Add(Android.Manifest.Permission.WriteExternalStorage);
        }
        // Make the request with the permissions needed...and then check OnRequestPermissionsResult() for the results
        RequestPermissions(listPermissions.ToArray(), PERMISSION_REQUEST_CODE_CAMERA_USAGE);
    }
    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults) {
        Log.Info(LOG_TAG, $"OnRequestPermissionsResult(requestCode={requestCode} - Permissions Count={permissions.Length} - GrantResults Count={grantResults.Length})");
        switch (requestCode) {
            // To use the camera, the user must grant privs to the Camera as well as writing to external storage, so this case checks both
            case PERMISSION_REQUEST_CODE_CAMERA_USAGE: {                    
                for (var i = 0; i < permissions.Length; i++) {
                    Log.Info(LOG_TAG, $"Checking permission for {permissions[i]}...");
                    if (grantResults[i] != Permission.Granted) {
                        Log.Info(LOG_TAG, $"Permission Denied for {permissions[i]}!");
                        Toast.MakeText(this, "You must approve all permissions prompted to use the camera.", ToastLength.Long).Show();
                        return;
                    }
                    Log.Info(LOG_TAG, $"Permission Granted for {permissions[i]}.");
                }
                // If we get here then all the permissions we requested were approved and we can now load the Camera interface
                StartActivity(typeof(CameraActivity));
                break;
            }
        }
    }
}

最新更新