Search code examples
c#androidwebviewxamarin.androidgeolocation

no geolocation authorization with SDK28 webview


I have a problem to activate the gps on android with my code. I have my AlertDialog which asks me yes or no but no action afterwards. I have an "application does not have sufficient geolocation permissions" error. here is what I realized:

manifest :

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />

AssemblyInfo :

[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
[assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
[assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
[assembly: UsesPermission(Android.Manifest.Permission.AccessWifiState)]
[assembly: UsesPermission(Android.Manifest.Permission.ControlLocationUpdates)]
[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
[assembly: UsesPermission(Android.Manifest.Permission.AccessMockLocation)]
[assembly: UsesPermission(Android.Manifest.Permission_group.Location)]
[assembly: UsesPermission(Android.Manifest.Permission.SetAlarm)]

[assembly: UsesFeature("android.hardware.location", Required = false)]
[assembly: UsesFeature("android.hardware.location.gps", Required = false)]
[assembly: UsesFeature("android.hardware.location.network", Required = false)]

MainActivity :

namespace alerte
{

public class MainActivity : AppCompatActivity
{
 private void Getaffichagemap(string X, string Y, string Ldep, string Lcom, string Lco, string liststationmap)
{
      string myHtml = "bla bla bla";

        MapView.Settings.JavaScriptEnabled = true;
        MapView.Settings.SetGeolocationEnabled(true);
        MapView.Settings.SetGeolocationDatabasePath(MapView.Context.FilesDir.Path);



        MapView.SetWebChromeClient(new CustomChromeClient(MapView.Context));



        MapView.LoadDataWithBaseURL("https://null", myHtml, "text/html", "UTF-8", null);
    }


  }
    public class CustomChromeClient : WebChromeClient
{
    private readonly Context _context;

    public CustomChromeClient(Context context)
    {
        _context = context;
    }

    public override void OnGeolocationPermissionsShowPrompt(string origin, Android.Webkit.GeolocationPermissions.ICallback callback)
    {
        var builder = new AlertDialog.Builder(_context);
        builder.SetTitle("Localisation")
            .SetMessage(string.Format("Utiliser votre position actuelle", origin))
            .SetPositiveButton("Oui", (sender, args) => callback.Invoke(origin, true, false))
            .SetNegativeButton("Non", (sender, args) => callback.Invoke(origin, false, false));
        var alert = builder.Create();
        alert.Show();
    }
}



}

I am missing something to finish but I am not a pro in this field to make it functional. I take any remark or info. thanks in advance


Solution

  • Android applications run in their own sandbox and for security reasons do not have access to certain system resources or hardware on the device. The user must explicitly grant permission to the app before it may use these resources. For example, an application cannot access the GPS on a device without explicit permission from the user.

    For apps that targeted Android 5.1 (API level 22) or lower, the permission request occurred when the app was installed.

    Starting in Android 6.0 (API level 23), users were given more control over permissions, it requires to request the permission at runtime.

    Firstly, you need to added AccessFineLocation and AccessCoarseLocation permission to the AndroidManifest.xml.

    Then requesting the permission at runtime before you use it.

     private void checklocationpermission()
        {
            if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.AccessFineLocation) == (int)Permission.Granted)
            {
                // We have permission, go ahead and use the device location.
              
            }
            else
            {
                // location permission is not granted. If necessary display rationale & request.
                ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.AccessFineLocation }, 1);
               
            }
        }
    

    After the user is finished, Android will return the results to the Activity via a callback method, OnRequestPermissionResult. This method is a part of the interface ActivityCompat.IOnRequestPermissionsResultCallback which must be implemented by the Activity. This interface has a single method, OnRequestPermissionsResult, which will be invoked by Android to inform the Activity of the user's choices.

     public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    
            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    

    More detailed info about Runtime Permission, you can take a look:

    https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/permissions?tabs=windows#runtime-permission-checks-in-android-60