requestLocationUpdates parameters having no effect on Gingerbread device
I had previously coded an app with a location listener without access to a real device. Now that I have a Gingerbread phone (2.3.3), as expected my app is a battery killer.
I started examining the effect of the update time and minimum distance arguments to requestLocationUpdates as the documentation says that these will affect battery drain.
I had wondered how just adjusting these parameters could affect the battery drain, as far as I could see the GPS would have to remain on, in order to know what distance the device had moved and only the actual process of notifying the app would change whilst the chip continued using power.
This article Understanding the LocationListener in Android put forward a credible explanation, indicating that the status would change to 'temporarily unavailable' and the GPS icon would disappear from the screen for a while, until such time as it was necessary to turn back on again according to the update period specified.
This doesn't happen on my phone - the GPS icon stays on even with an update period of 90 seconds and I get no status changes and according to some of the posts at the end of the article, others find the same.
Do any users on SO experience the same thing with 2.3.3?
Or have Android given up on managing the GPS chip and expect users to write their own battery management regime for the GPS?
For info my minimum code to demonstrate this behaviour is shown below:
public class GpsTimeOutTestActivity extends Activity implements
LocationListener {
private LocationManager mLocMgr;
private long mUpdatePeriod = 90000; // 90 seconds
private float mMinDistance = 10.0f;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onResume() {
super.onResume();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mLocMgr = (LocationManager) getSystemService(LOCATION_SERVICE);
mLocMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,
mUpdatePeriod, mMinDistance, (LocationListener) this);
}
@Override
protected void onPause() {
mLocMgr.removeUpdates((LocationListener) this);
super.onPause();
}
@Override
public void onLocationChanged(Locat开发者_运维技巧ion loc) {
String str = null;
NumberFormat formatter = new DecimalFormat("##0.000");
String fLat = formatter.format(loc.getLatitude());
String fLon = formatter.format(loc.getLongitude());
String provider = loc.getProvider();
provider = (provider == null) ? "No provider" : provider;
str = "Locn chg " + provider + " Lat/Lon " + fLat + "/" + fLon;
if (loc.hasAccuracy())
str+= " accy " + loc.getAccuracy();
showSomeOutput(str);
}
@Override
public void onProviderDisabled(String provider) {
String str = "Prov disabled " + provider;
showSomeOutput(str);
}
@Override
public void onProviderEnabled(String provider) {
String str = "Prov enabled " + provider;
showSomeOutput(str);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
String str = "Status chg " + provider;
switch (status) {
case android.location.LocationProvider.OUT_OF_SERVICE:
str+= " OUT OF SERVICE";
break;
case android.location.LocationProvider.AVAILABLE:
str+= " AVAILABLE";
break;
case android.location.LocationProvider.TEMPORARILY_UNAVAILABLE:
str+= " TEMPORARILY UNAVAILABLE";
break;
default:
str+= " UNKNOWN STATUS";
}
showSomeOutput(str);
}
private void showSomeOutput(String str) {
Log.d("GPSTEST", str);
EditText et = (EditText) findViewById(R.id.editText1);
Editable existingText = et.getText();
existingText.append("\n" + str);
}
}
All comments will be gratefully received.
If you dig into the innards of the GPS provider, you will find that Android tells the native drivers the minimum update time. The native drivers can then decide what to do - in my experience, they all disregard this and keep running full-throttle.
This is annoying, but doesn't exactly violate the javadocs:
The frequency of notification may be controlled using the minTime and minDistance parameters. If minTime is greater than 0, the LocationManager could potentially rest for minTime milliseconds between location updates to conserve power
(emphasis added)
The solution is to only register your LocationListener as needed. If you need to target APIs before requestSingleUpdate was added, you have to register your listener and then unregister it when you are satisfied with the quality of the location. This will turn the GPS back off and save power.
If you are listening to gps the icon will appear in the menu bar, no matter what your interval it is set to. Your are correct in the assumption that setting the notification times and distances will just alert your application when those thresholds are met. The chip does have to remain on to alert you of changes.
What in your application needs constant gps updating? I usually use the requestSingleUpdate function to get the gps location.
精彩评论