使用服务内的 AlarmManager 定期更新 GPS 位置 [英] Android Periodic GPS location updates with AlarmManager inside a Service

查看:33
本文介绍了使用服务内的 AlarmManager 定期更新 GPS 位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里阅读了很多问题,但无法弄清楚问题所在.

I read a lot of questions on here but couldn't figure out what the problem is.

我正在为 Android 编写一个现场服务应用程序.在一个活动(MyActivity.java)中,我有两个按钮:开始和停止.

I'm writing a field service application for Android. In one of the Activities (MyActivity.java) I have two buttons: Start and Stop.

当现场工作人员按下开始时,我需要通过 GPS 获取他的当前位置并及时将其发送到服务器(假设默认为 5 分钟,这里我将其设置为 20 秒以进行测试).客户想看看工人在交通上花费了多长时间,我所在城市(伊斯坦布尔)的交通一团糟.

When the field worker presses start I need to get his current location with GPS and send it to server in timely intervals (say it be 5 minutes default, here I set it to 20 secs. for testing). The customer wants this to see how long the workers spend time in traffic, the traffic in my city (Istanbul) is a mess.

我的活动中有一个 AlarmManager,当按下开始按钮时,警报由 AlarmManager.setRepeating() 设置以启动服务 (ServiceClass.java).

I have an AlarmManager in my activity, when the start button is pressed the alarm is set by AlarmManager.setRepeating() to start the service (ServiceClass.java).

Intent intent = new Intent (MyActivity.this, ServiceClass.class);
mPendingIntent = PendingIntent.getService(MyActivity.this, 0, intent,
                                              PendingIntent.FLAG_CANCEL_CURRENT);
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mAlarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), 20*1000,
                                                                  mPendingIntent);

我用停止按钮取消警报.

I cancel the Alarm with the Stop button.

到这里为止,它工作得很好,服务开始了.它的 onCreate()onStart()onDestroy() 方法被执行.但是我找不到位置.我不在真实设备上工作,所以我使用 DDMS 发送位置.但是应用程序会跳过该步骤并将我所在位置的经度和纬度打印为 Lon:0 Lat:0.

It works perfectly till here, the Service starts. Its onCreate(), onStart() and onDestroy() methods are executed. But I can't get the location. I'm not working on a real device so I'm using DDMS to send locations. But the application skips that step and prints Longitude and Latitude of my location as Lon:0 Lat:0.

这是服务内部的代码:

public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
    Log.d("Testing", "Service got started, calling location updates:");
    mLocationManager.requestSingleUpdate(mCriteria, mLocationListener,
                                                                getMainLooper());
    Log.i("TESTING LOCATION UPDATE: LOCATION:", "
Lat:"   + mLatitude +
                                                          "  Lon:" + mLongitude);
    stopSelf(startId);
    Log.d("Testing", "Service Stopped!");

最后,这是我的 LocationListener:

And finally, here's my LocationListener:

 mLocationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {

            if(location != null){
                mLatitude = location.getLatitude();
                mLongitude = location.getLongitude();
                Log.i("onLocationChanged(Location location)", "Lat:"+mLatitude + "
                                                            Lon:" + mLongitude);
}

当我运行代码时,还有一些东西引起了我的注意:

Also something caught my eye, when I run the code:

mLocationProvider = mLocationManager.getBestProvider(mCriteria, true);
Log.i("BEST PROVIDER IS:", mLocationProvider);

上面写着最好的供应商是:gps.但是 onProviderEnabled() 中的这个日志永远不会显示在 logcat 中.

It says BEST PROVIDER IS: gps. But this log inside onProviderEnabled() is never shown in logcat.

@Override
public void onProviderEnabled(String s) {
    Log.v("onProviderEnabled", "ENABLED");
}

如果我使用,要添加两件事:

Two things to add, if I use:

mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
                                                              mLocationListener);

它也不起作用.

但是这可行,我可以获得 LastKnownLocation:

This however works and I can get the LastKnownLocation:

Location lastKnown = mLocationManager.getLastKnownLocation(
                                                   LocationManager.GPS_PROVIDER);

首先,这是一个很好的方法吗?如果是,请检查我缺少什么.如果不是,您能告诉我如何更好地实现这一点吗?

First of all, is this a good approach for doing this? If it is please check to see what I am missing. If it is not, can you please tell me how can I implement this any better?

谢谢.:)

推荐答案

首先不能注册位置更新,然后关闭服务.充其量,你会泄漏线程.在最坏的情况下,Android 将终止您的进程(认为其中没有任何运行)并且您将无法获得更新.此外,GPS 需要一段时间才能预热,因此您可能无法在 20 秒内得到修复,尤其是在城市环境中.此外,您必须确保在尝试收集修复时设备保持唤醒状态.

First, you cannot register for location updates, then shut down the service. At best, you will leak threads. At worst, Android will terminate your process (thinking there is nothing running in it) and you will not get the update. Also, GPS takes a while to warm up, so you might not get a fix within 20 seconds, particularly in an urban setting. Also, you have to make sure the device stays awake while you are trying to collect a fix.

因此,在后台定期获取位置修复是一个相当复杂的问题.

As a result, getting periodic location fixes in the background is a rather complicated problem.

我写了一个现已停产的 LocationPoller 来尝试解决这个问题,并且 另一个开发人员已经分叉并扩展了它.你可以试试 fork 或者干脆把它当作灵感的来源.

I wrote a now-discontinued LocationPoller to try to address this, and another developer has forked and extended it. You could try the fork or simply use it as a source of ideas.

这篇关于使用服务内的 AlarmManager 定期更新 GPS 位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆