Xamarin Android请求运行时权限不起作用

问题描述 投票:0回答:2

所以我试图让用户获得在我试图创建的应用程序上使用Location的权限。我在Android Manifest中包含了该权限

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

在Splash屏幕所在的SplashActivity页面以及我希望向用户显示权限的位置我已将以下代码放入:

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
}

但是,不会要求用户提供权限。我认为它可能与await TryToGetPermissions()有关;朝向代码的开头,它实际上没有调用TryToGetPermissions,因此它不起作用。

任何帮助将不胜感激。

谢谢!

c# android xamarin xamarin.forms xamarin.android
2个回答
0
投票

我有一个完全相同的工作解决方案,如下所示:

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

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

检查权限Granted是一种类似这样的方法:

 [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);
        }
    }

0
投票

如果你不需要async / await,下面是我在我的应用程序中所做的,我需要Camera权限。它非常适合我的需求,也许它也适合你。

您的实现将更简单,因为您不需要在OnRequestPermissionsResult()中迭代多个结果。我不得不这样做,因为我的应用程序需要保存图片,因此在我加载相机界面/活动之前需要Camera和WriteExternalStorage权限。

[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;
            }
        }
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.