我已经设置了LocationManager以每2分钟获取当前位置:
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 120000, 0, this);
这很好用,onLocationChanged按预期每2分钟调用一次。但是,似乎在每隔 2分钟的10-40(随机量)第二跨度中多次调用它。我记录了onLocationChanged中收到的每个位置,所以这里有一些示例来了解发生了什么:
17:30
GPS 32.0 50.66318929195404 10.735434293746948 0.0 2010.08.07 17:30:10
GPS 32.0 50.66315710544586 10.735423564910889 0.0 2010.08.07 17:30:14
GPS 32.0 50.66314101219177 10.735418200492859 0.0 2010.08.07 17:30:17
GPS 32.0 50.66314101219177 10.735418200492859 0.0 2010.08.07 17:30:20
GPS 24.0 50.66313564777374 10.735418200492859 0.5 2010.08.07 17:30:24
GPS 32.0 50.663098096847534 10.735573768615723 0.0 2010.08.07 17:30:28
GPS 32.0 50.663065910339355 10.735611319541931 0.0 2010.08.07 17:30:31
然后我在2分钟内没有更新。
17:32
GPS 32.0 50.661821365356445 10.737022161483765 1.0 2010.08.07 17:32:39
GPS 16.0 50.66170871257782 10.737043619155884 1.8200275 2010.08.07 17:32:45
GPS 24.0 50.661579966545105 10.737027525901794 1.25 2010.08.07 17:32:50
GPS 16.0 50.66150486469269 10.73712408542633 1.0 2010.08.07 17:32:55
GPS 12.0 50.661579966545105 10.73715090751648 0.9013878 2010.08.07 17:33:01
GPS 24.0 50.66139221191406 10.737038254737854 1.5811388 2010.08.07 17:33:06
GPS 16.0 50.66141366958618 10.737301111221313 0.70710677 2010.08.07 17:33:12
GPS 16.0 50.66141366958618 10.737301111221313 0.70710677 2010.08.07 17:33:12
GPS 24.0 50.661311745643616 10.737070441246033 1.118034 2010.08.07 17:33:16
GPS 16.0 50.66122591495514 10.737177729606628 1.118034 2010.08.07 17:33:22
GPS 12.0 50.66124200820923 10.737220644950867 1.3462912 2010.08.07 17:33:26
GPS 12.0 50.661311745643616 10.737268924713135 3.6055512 2010.08.07 17:33:25
等等......然后在2分钟后的17:35进行另一组更新。
这是标准行为吗?我期望每2分钟只获得一个位置,并且它给我位置更新的时间跨度似乎相当随机。理想情况下,我宁愿只获得一个位置......有没有办法做到这一点?
答案 0 :(得分:13)
来自requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)
陈述minTime
参数的文档:
“通知的最短时间间隔,以毫秒为单位。此字段仅用作节省电量的提示,位置更新之间的实际时间可能大于或小于此值。”
所以问题的答案是肯定的,这是标准行为,不,你不能改变它。
如果这对您来说是个问题,如果还没有经过一定的时间,您可以忽略对回调方法的调用。
答案 1 :(得分:7)
我发现了这个问题,因为我遇到了同样的问题。
我相信我有答案。由于您将meter参数设置为0,因此正在触发快速更新。
将米参数更改为10,如果您的位置更改10或更多,它将每2分钟触发一次LocationChanged事件。
在我做这个更改之前,LocationChanged每秒都会多次触发。现在,它发射一次。然后每隔2分钟,您会在状态栏上看到GPS图标,但除非您的位置发生变化,否则事件不会触发。
我希望这会有所帮助。这就是为我解决的问题。没有必要添加任何额外的逻辑来防止虚假火灾。
答案 2 :(得分:1)
这是我的LocationListener实现,用于过滤掉不必要的onLocationChanged()事件:
注意我在我的服务中使用消息。
public class GPSlocationListener implements LocationListener
{
//member variables
private Handler mParentHandler;//points to Handler of parent
private long mTimeBetweenLocationEvents;
private long mTimeOfLastLocationEvent;
private boolean mAccuracyOverride;
private float mLastAccuracy;
private boolean mOverrideLocation;
//constants
private static final float INVALID_ACCURACY = 999999.0f;
private static final String TAG = "GPSlocationListener";
//constructor
public GPSlocationListener(Handler parentMsgHandler, long timeBetweenLocationEvents, boolean accuracyOverride)
{
mParentHandler = parentMsgHandler;
mTimeOfLastLocationEvent = 0;
mAccuracyOverride = accuracyOverride;
mLastAccuracy = INVALID_ACCURACY;
mOverrideLocation = false;
mTimeBetweenLocationEvents = timeBetweenLocationEvents;
}
//EVENT: onLocationChanged()
// send GPS coordinates to CommService
public void onLocationChanged(Location loc)
{
Log.d(TAG, "onLocationChanged() triggered. Accuracy = "+Float.toString(loc.getAccuracy()));
mOverrideLocation = false;
if (loc != null)
{
//if a more accurate coordinate is available within a set of events, then use it (if enabled by programmer)
if (mAccuracyOverride == true)
{
//whenever the expected time period is reached invalidate the last known accuracy
// so that we don't just receive better and better accuracy and eventually risk receiving
// only minimal locations
if (loc.getTime() - mTimeOfLastLocationEvent >= mTimeBetweenLocationEvents)
{
mLastAccuracy = INVALID_ACCURACY;
}
if (loc.hasAccuracy())
{
final float fCurrentAccuracy = loc.getAccuracy();
//the '<' is important here to filter out equal accuracies !
if ((fCurrentAccuracy != 0.0f) && (fCurrentAccuracy < mLastAccuracy))
{
mOverrideLocation = true;
mLastAccuracy = fCurrentAccuracy;
}
}
}
//ensure that we don't get a lot of events
// or if enabled, only get more accurate events within mTimeBetweenLocationEvents
if ( (loc.getTime() - mTimeOfLastLocationEvent >= mTimeBetweenLocationEvents)
||(mOverrideLocation == true) )
{
//be sure to store the time of receiving this event !
mTimeOfLastLocationEvent = loc.getTime();
//send message to parent containing the location object
Message msgToMain = mParentHandler.obtainMessage();
msgToMain.what = Constants.MSG_LOCATION_CHANGED;
msgToMain.obj = loc;
mParentHandler.sendMessage(msgToMain);
}
}
}
public void onProviderDisabled(String provider)
{
// TODO Auto-generated method stub
}
public void onProviderEnabled(String provider)
{
// TODO Auto-generated method stub
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
// TODO Auto-generated method stub
}
}
这在主代码中实现如下:
//create the APIthread (which exposes mAPIhandler back to this service)
mAPIthread = new APIthread(mApiHandler);
mAPIthread.start();
//use the LocationManager class to obtain GPS locations
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationListener = new GPSlocationListener(mApiHandler, Constants.LOCATION_UPDATE_PERIOD_MSEC, true);
//this will call GPSlocationListener.onLocationChanged()
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
//3 mins NOTE: approximate value
Constants.LOCATION_UPDATE_PERIOD_MSEC,
//no distance updates desired
0,
locationListener);