ArcGIS runtime for Android, map view location display crashes app

1713
5
01-22-2019 10:14 PM
EdL
by
New Contributor II

The app will use the map view's location display to show own location.

On enabling location display, if the user switches between 2 fragments (map & some other fragment) multiple times, the app will crash. Just before the app crashes, opening the drawer will be sluggish and then eventually crash. Disabling the location display however will not crash the app with fast response on drawer interaction.

I have a limited number of devices only and the crash seem to affect Samsung devices running Oreo.

Attached is a sample app replicating this. Try commenting/uncommenting line 72 & 93 of MapFragment.cs file.

The device used are:

Samsung S8+

Oreo 8.0, Samung Experience 9

ArcGIS Runtime, v100.4.0

VS 2017 Professional, v15.9.4

Xamarin android SDK, v9.1.4.2

Xamarin, v4.12.3.77

0 Kudos
5 Replies
dotMorten_esri
Esri Notable Contributor

Could you connect with logcat while reproducing the crash, and share what is reported for the apps's process ID when it crashes? This will also ensure that if we're able to reproduce, we can confirm whether we are seeing the same type of crash, and the logcat alone might give us a good indicator what is going on.

0 Kudos
RichZwaap
Occasional Contributor III

Looking at the sample, it appears the problem you're having is that you're not requesting the ACCESS_FINE_LOCATION permission.  First, you need to have this permission included in your manifest.  I'm guessing you've already done that in your production app and just overlooked it in your little reproducer app.  The part that's easier to miss is that, on Android 6.0 (API 23) and up, you also need to explicitly include logic in your app to request this permission at run-time.  Resources on that include:

It's definitely NOT intuitive to add that logic, however (at least I don't find it so), so I've taken the liberty of updating your sample with the necessary code and have attached that.  The relevant pieces of code are:

Implement ActivityCompat.IOnRequestPermissionsCallback in your MainActivity, checking that the response is coming from a location permissions check, and raising a notification for your fragment to handle:

/// <summary>
/// Handle the user-specified response from a request for permissions
/// </summary>
public void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
    // Check that the response is coming from our request for location permissions
    if (requestCode == LocationPermissionsRequestCode && grantResults.Length == 1)
    {
        // Raise the response received event so subscribers can respond accordingly
        LocationPermissionResponseReceived?.Invoke(this, grantResults[0]);
    }
}

// Arbitrary number (no greater than 65535) to use in distinguishing the location permissions request from other requests
internal static int LocationPermissionsRequestCode = 32987;

// Event that will be raised when a response to a location permissions request is received
internal event EventHandler<Android.Content.PM.Permission> LocationPermissionResponseReceived;

In your fragment, verify that location permission has been granted before enabling location display.  If it hasn't been, request it:

// Check if location permission has been granted
if (ContextCompat.CheckSelfPermission(this.Context, Android.Manifest.Permission.AccessFineLocation) == Android.Content.PM.Permission.Granted)
{
    // Location permission was granted, so go ahead and turn on location display

    //// Bug: Enabling the LocationDisplay will cause the app to crash when switching between drawer items
    this.mapView.LocationDisplay.IsEnabled = true;
}
else
{
    // Location permission has not yet been granted, so request it

    // Get the fragment's activity as the specific MainActivity type so we can hook to its LocationPermissionResponseReceived evetn
    var mainActivity = (MainActivity)this.Activity;

    // Wire up an event handler to listen for when a user response to the request for location permission is received
    EventHandler<Android.Content.PM.Permission> locationPermissionResponseReceivedHandler = null;
    locationPermissionResponseReceivedHandler = (o, e) =>
    {
        // Unhook from the event
        mainActivity.LocationPermissionResponseReceived -= locationPermissionResponseReceivedHandler;

        // If the user-response was to grant the permission, then turn location display on
        if (e == Android.Content.PM.Permission.Granted)
        {
            this.mapView.LocationDisplay.IsEnabled = true;
        }
    };

    // Subscribe to the event that will be raised when the user-response is received.
    mainActivity.LocationPermissionResponseReceived += locationPermissionResponseReceivedHandler;

    // Issue the permissions request
    Android.Support.V4.App.ActivityCompat.RequestPermissions(
        this.Activity, // The activity implementing ActivityCompat.IOnRequestPermissionsResultCallback and that will be notified of the user response
        new string[] { Android.Manifest.Permission.AccessFineLocation }, // The permissions being requested
        MainActivity.LocationPermissionsRequestCode // The arbitrary code that will distinguish this particular request when handling the response
    );
}

Hope this helps!

EdL
by
New Contributor II

Hi Zwaap, sorry for the late reply (off on Lunar New Year week).

Thanks for the updating the sample with permission granting.

Unfortunately, the error is still occurring (app freeze/crash) after toggling a few times. I have attached logs from logcat the ANR trace logs.

I hope some insights can be found from them.

0 Kudos
EdL
by
New Contributor II

Are there any new findings?

0 Kudos
STEEInfo
New Contributor

Are there any new findings?

0 Kudos