【问题标题】:GPS tracking app in Xamarin stop working in the background after a whileXamarin 中的 GPS 跟踪应用程序在一段时间后停止在后台工作
【发布时间】:2021-09-05 10:42:34
【问题描述】:

我正在尝试在Xamarin 中制作一个也可以在后台运行的 GPS 跟踪应用程序。目前我已经创建了一个每两秒检查一次设备位置的服务。

我目前正在 Android Honor 10 上对其进行测试,我注意到当我使用 Visual Studio 在调试中启动应用程序时,保持手机连接到 PC 可以正常工作永不停歇。

另一方面,如果我在没有调试的情况下尝试应用程序,如果我把它放在后台,一段时间后它会停止跟踪 gps。

这是我在主项目中的服务

public class TrackingService
{
    readonly bool stopping = false;
    public TrackingService()
    {
    }

    public async Task Run(CancellationToken token)
    {
        await Task.Run(async () => {
            while (!stopping)
            {
                token.ThrowIfCancellationRequested();
                try
                {
                    await Task.Delay(2000);

                    var request = new GeolocationRequest(GeolocationAccuracy.Best);
                    var location = await Geolocation.GetLocationAsync(request);
                    //Other stuff like writing coordinates into a local database
                }
                catch (Exception ex)
                {
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        //Error
                    });
                }
            }
            return;
        }, token);
    }
}

这是 Android 项目服务的开始:

[Register("com.companyname.dolomicchiostreetapp.TrackingService")]
public class AndroidLocationService : Service
{
    CancellationTokenSource _cts;
    public const int SERVICE_RUNNING_NOTIFICATION_ID = 10000;

    public override IBinder OnBind(Intent intent)
    {
        return null;
    }

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {
        _cts = new CancellationTokenSource();

        Notification notif = DependencyService.Get<INotification>().ReturnNotif();
        StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notif);

        Task.Run(() => {
            try
            {
                var locShared = new TrackingService();
                locShared.Run(_cts.Token).Wait();
            }
            catch (OperationCanceledException)
            {
            }
            finally
            {
                if (_cts.IsCancellationRequested)
                {
                    var message = new StopServiceMessage();
                    Device.BeginInvokeOnMainThread(
                        () => MessagingCenter.Send(message, "ServiceStopped")
                    );
                }
            }
        }, _cts.Token);

        return StartCommandResult.Sticky;
    }

    public override void OnDestroy()
    {
        if (_cts != null)
        {
            _cts.Token.ThrowIfCancellationRequested();
            _cts.Cancel();
        }
        base.OnDestroy();
    }
}

这是我的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.dolomicchiostreetapp">
    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
    <application android:label="dolomicchiostreetapp.Android" android:theme="@style/MainTheme">
      <service android:enabled="true" android:foregroundServiceType="location" android:exported="false" android:name="com.companyname.dolomicchiostreetapp.TrackingService" />
    </application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
</manifest>

我遵循了这个 github 示例:XamarinForms.LocationService

有人遇到过这个问题吗?

感谢那些帮助我的人。

【问题讨论】:

    标签: c# xamarin xamarin.forms gps tracking


    【解决方案1】:

    请参阅Limited Updates to Background Tracking - “Android 8.0(API 级别 26)及更高版本 - Android 通过以下方式延长设备电池寿命...如果您的应用在后台运行,则每次只能接收几次位置更新小时”。

    如果您想要更频繁的更新,那么您需要Foreground Service

    【讨论】:

    • 我在这个例子中实现了:github.com/shernandezp/XamarinForms.LocationService/blob/master/… 事实上,当我启动服务时,状态栏中的图标作为通知对我来说保持活动状态
    • 好的。我错过了您代码中的StartForeground。在那个和状态图标之间,(当然还有权限,我看到你有那个),你已经做了我知道要做的事情。
    猜你喜欢
    • 2021-07-31
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 2016-04-07
    • 2019-08-08
    • 2018-03-17
    • 2014-10-13
    • 1970-01-01
    相关资源
    最近更新 更多