You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Android中RequestLocationUpdates无法正常工作问题求助

Xamarin Android LocationService 无法接收位置更新的解决方法

问题描述

在Xamarin Android中实现LocationService后,调用RequestLocationUpdates始终无法获取位置更新。已完成以下调试:

  • 验证_locationProvider与_locationManager的有效性检查均返回true
  • 已在AndroidManifest.xml中注册该服务
  • OnStartCommand方法已正常触发
  • 设备显示GPS正在使用的系统通知
  • 已尝试实地走动测试,但仍无位置更新回调

相关实现代码:

using Android.App;
using Android.Content;
using Android.Locations;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.Support;

namespace App3.Droid
{
[Service]
public class LocationService : Service, ILocationListener
{

    LocationManager _locationManager;
    Context c;
    string _locationProvider;
    //const int REQUEST_FOREGROUND_SERVICE = 0;
        

    const int NOTIFICATION_ID = 1;
    NotificationManager manager;

    //private string _notificationTitle = "App is running in background";
    //private string _notificationText = "App is tracking your location";
    public override IBinder OnBind(Intent intent)
    {
        return null;
    }

    public override void OnCreate()
    {
        base.OnCreate();
        c = this;
    }
        

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId) {

        Android.Util.Log.Debug("LocationService", "OnStartCommand Called");


        _locationManager = (LocationManager)c.GetSystemService(LocationService);
        _locationProvider = LocationManager.GpsProvider;
        System.Diagnostics.Debug.WriteLine(_locationManager);
        System.Diagnostics.Debug.WriteLine(_locationProvider);
        System.Diagnostics.Debug.WriteLine(_locationManager.IsProviderEnabled(_locationProvider) + "," + _locationManager.AllProviders.Contains(_locationProvider));
            

        if (_locationManager.IsProviderEnabled(_locationProvider) && _locationManager.AllProviders.Contains(_locationProvider))
        {
                
            _locationManager.RequestLocationUpdates(_locationProvider, 0, 0, this);

            manager = (NotificationManager)GetSystemService(NotificationService);
            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                //var channel = new NotificationChannel("channel_01", "My Channel", NotificationImportance.High);
                //manager.CreateNotificationChannel(channel);
                //var notificationBuilder = new Notification.Builder(this)
                //.SetContentTitle(_notificationTitle)
                //.SetContentText(_notificationText)
                //.SetSmallIcon(Resource.Mipmap.icon);
                //var notification = notificationBuilder.Build();
                //manager = (NotificationManager)GetSystemService(Context.NotificationService);
                //manager.Notify(NOTIFICATION_ID, notification);
                Toast.MakeText(this, "Notifcations On", ToastLength.Short).Show();

            }
            else
            {
                Toast.MakeText(this, "Notifications not supported", ToastLength.Long).Show();
            }
        }
        else
        {
            Toast.MakeText(this, "Please enable GPS.", ToastLength.Long).Show();
        }

        return StartCommandResult.Sticky;
    }
      
    public override void OnDestroy()
    {
        Log.Debug("LocationService", "StopService called");
        base.OnDestroy();
        _locationManager.RemoveUpdates(this);
    }

    public void OnLocationChanged(Location location)
    {
        double latitude = location.Latitude;
        double longitude = location.Longitude;
        string coordinates = latitude + "," + longitude;

        System.Diagnostics.Debug.WriteLine(latitude + "," + longitude);
        String msg = "New Latitude: " + latitude + "New Longitude: " + longitude;

        Toast.MakeText(this, msg, ToastLength.Long).Show();
    }
}
}

解决步骤

1. 补全ILocationListener的所有接口实现

ILocationListener接口包含4个必须实现的方法,仅实现OnLocationChanged会导致系统无法正常触发回调,需补全剩余三个方法(空实现即可):

public void OnProviderDisabled(string provider)
{
    // 可选:添加日志或用户提示逻辑
}

public void OnProviderEnabled(string provider)
{
    // 可选:添加日志或用户提示逻辑
}

public void OnStatusChanged(string provider, Availability status, Bundle extras)
{
    // 可选:添加日志或状态处理逻辑
}

2. 强制设置前台服务通知(Android 8.0+)

Android 8.0(API 26)及以上版本要求前台服务必须显示通知,否则服务会被系统立即终止。取消代码中通知相关注释,并调用StartForeground方法替换单纯的Notify:

if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
    var channel = new NotificationChannel("channel_01", "位置跟踪", NotificationImportance.High);
    manager.CreateNotificationChannel(channel);
}

var notificationBuilder = new Notification.Builder(this, "channel_01")
    .SetContentTitle("应用在后台运行")
    .SetContentText("正在跟踪你的位置")
    .SetSmallIcon(Resource.Mipmap.icon);

var notification = notificationBuilder.Build();
// 必须调用StartForeground确保服务在前台运行
StartForeground(NOTIFICATION_ID, notification);

3. 确认位置权限已正确配置

  • 静态权限:在AndroidManifest.xml中添加必要权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Android 10+ 后台定位需额外添加 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  • 动态权限:Android 6.0(API 23)及以上版本需在运行时主动申请定位权限,建议在启动服务前执行:
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.AccessFineLocation) != Permission.Granted)
{
    ActivityCompat.RequestPermissions(this, new string[] { Manifest.Permission.AccessFineLocation, Manifest.Permission.AccessCoarseLocation }, 1001);
}

4. 调整位置更新参数

RequestLocationUpdates的0毫秒间隔、0米距离参数过于严格,GPS模块无法及时返回数据,建议调整为合理值:

// 间隔1000毫秒、移动10米时触发一次位置更新
_locationManager.RequestLocationUpdates(_locationProvider, 1000, 10, this);

同时可先获取最后已知位置测试功能是否正常:

var lastLocation = _locationManager.GetLastKnownLocation(_locationProvider);
if (lastLocation != null)
{
    System.Diagnostics.Debug.WriteLine($"最后已知位置:{lastLocation.Latitude},{lastLocation.Longitude}");
}

5. 优化上下文使用

直接使用this获取系统服务即可,无需额外赋值给c,简化代码:

_locationManager = (LocationManager)GetSystemService(LocationService);

内容的提问来源于stack exchange,提问作者Lazy Boi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 01:10:29