TLDR: is it possible to access location in Direct Boot mode?
I want to receive location updates for a device (testing on Pixel 3a) when the phone boots. This is a companion feature for a regular app, so assume required permission grants etc are taken care of.
The following code is also taken from components that work fine when invoked from a MainActivity.
The steps to set up the location callbacks are as follows:
Firstly, a DirectBootAware BroadcastReceiver that listens for ACTION_LOCKED_BOOT_COMPLETED means I can run code when the device boot and before the screen is unlocked.
[BroadcastReceiver(Enabled = true, Exported = true, DirectBootAware = true)]
[IntentFilter(new string[] { Intent.ActionLockedBootCompleted })]
public class StartForegroundServiceReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
From here I can verify that the permissions for Corse and Fine location are granted (which they are!)
var permissionCheckResult = context.CheckSelfPermission(Manifest.Permission.AccessFineLocation);
Android.Util.Log.Info("TestingTag", $"AccessFineLocation CheckSelfPermission {permissionCheckResult.ToString()}");
permissionCheckResult = context.CheckSelfPermission(Manifest.Permission.LocationHardware);
Android.Util.Log.Info("TestingTag", $"LocationHardware CheckSelfPermission {permissionCheckResult.ToString()}");
permissionCheckResult = context.CheckSelfPermission(Manifest.Permission.AccessCoarseLocation);
Android.Util.Log.Info("TestingTag", $"AccessCoarseLocation CheckSelfPermission {permissionCheckResult.ToString()}");
and that the Network, GPS, and Passive Location Providers are enabled (again, they're all enabled!)
var locationManager = (LocationManager)context.GetSystemService(Context.LocationService);
var enabled = locationManager.IsProviderEnabled(LocationManager.PassiveProvider);
Log.Info("TestingTag", $"PassiveProvider IsProviderEnabled {(enabled ? "yes" : "no")}");
enabled = locationManager.IsProviderEnabled(LocationManager.GpsProvider);
Log.Info("TestingTag", $"GpsProvider IsProviderEnabled {(enabled ? "yes" : "no")}");
enabled = locationManager.IsProviderEnabled(LocationManager.NetworkProvider);
Log.Info("TestingTag", $"NetworkProvider IsProviderEnabled {(enabled ? "yes" : "no")}");
If I check GetLastKnownLocation
var location = locationManager.GetLastKnownLocation(LocationManager.GpsProvider);
if (location == null)
{
location = locationManager.GetLastKnownLocation(LocationManager.NetworkProvider);
}
if (location == null)
{
location = locationManager.GetLastKnownLocation(LocationManager.PassiveProvider);
}
if (location == null)
Log.Error("TestingTag", $"Location is null");
This always returns null, perhaps because the device has just booted? Or maybe it's because of the same root cause as not receiving any location updates?
Finally, I register for location updates with the LocationManager
var callback = new LocationCallback();
Log.Info("TestingTag", "Starting RequestLocationUpdates via PassiveProvider..");
locationManager.RequestLocationUpdates(LocationManager.PassiveProvider, 3000, 3, callback);
Log.Info("TestingTag", "Starting RequestLocationUpdates via GpsProvider..");
locationManager.RequestLocationUpdates(LocationManager.GpsProvider, 3000, 3, callback);
Log.Info("TestingTag", "Starting RequestLocationUpdates via NetworkProvider..");
locationManager.RequestLocationUpdates(LocationManager.NetworkProvider, 3000, 3, callback);
Here's the location callback code:
public class LocationCallback : ScanCallback, Android.Locations.ILocationListener
{
public void OnLocationChanged(Location location)
{
Log.Info("TestingTag", $"OnLocationChanged {location.Latitude} ~ {location.Longitude}");
}
public void OnProviderDisabled(string provider)
{
Log.Info("TestingTag", $"OnProviderDisabled {provider}");
}
public void OnProviderEnabled(string provider)
{
Log.Info("TestingTag", $"OnProviderEnabled {provider}");
}
public void OnStatusChanged(string provider, [GeneratedEnum] Availability status, Bundle extras)
{
Log.Info("TestingTag", $"OnStatusChanged {provider} ~ {status.ToString()}");
}
}
The callback is never invoked :-(
I've added a BluetoothManager
to scan for BLE signals (omitted code for that) and that works, ScanResults are returned fine and the phone / BroadcastReceiver is still alive. So it's not as if the BroadcastReceiver is just dying...
Any tips / suggestions / or confirmation that what I'm trying to do is not possible would be greatly appreciated!
Thanks!
from Xamarin.Android Not Receiving Location Updates in Direct Boot Mode
No comments:
Post a Comment