У меня есть довольно простой фрагмент кода, который представляет собой службу, которая периодически запускается, записывает текущее местоположение (с использованием сетевого провайдера), отправляет его на сервер, а затем возвращается в спящий режим.
Я тестирую это на двух разных телефонах - SGS2 с регулярным ежемесячным тарифом и дешевый ZTE с предоплаченной SIM-картой (имеет данные, но минуты 10c / мин). Я обнаружил, что, когда я беру оба телефона и еду на диск, SGS2 работает отлично, но ZTE, похоже, теряет возможность исправить ситуацию.
ZTE просыпается, настраивает слушателя, получает определение местоположения, однако местоположение указывает на мой дом (где он получил последнее исправление на основе Wi-Fi), а не на текущее местоположение. Временная метка местоположения обновлена, поэтому, когда я получаю обновление местоположения, я действительно не могу сказать, является ли местоположение действительным (как в SGS2, или когда ZTE находится дома) или койкой (например, когда я за рулем с ZTE).
Кто-нибудь видел подобные проблемы раньше? Имеет ли это какое-либо отношение к карте предоплаты или к самому телефону ZTE? К сожалению, я не могу поменять SIM-карты (мне придется рутировать / разблокировать телефоны), поэтому я не могу это проверить.
Я включил приведенный ниже код, но, поскольку он хорошо работает на SGS2, я не думаю, что есть большая проблема.
public class LocationRecorder extends Service {
private volatile Location lastLocation;
private LocationManager locationManager;
private LocationListener locationListener;
private static volatile PowerManager.WakeLock wakeLock = null;
private static synchronized PowerManager.WakeLock getWakeLock(Context context) {
if (wakeLock == null) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "LocationRecorder");
wakeLock.acquire();
}
return wakeLock;
}
public static void startLocationRecorder(Context context, Intent service) {
getWakeLock(context);
context.startService(service);
}
@Override
public void onCreate() {
Log.d("LocationRecorder", "Starting Location Service");
locationManager = ((LocationManager)getSystemService(LOCATION_SERVICE));
locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.d("Location Changed", location.toString());
if (location.getExtras()!=null) {
String x = "";
for (String key : location.getExtras().keySet()) {
x+=key+":"+location.getExtras().get(key).toString()+", ";
}
Log.d("Location Changed Extras", x);
}
setLocation(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Status Changed", provider+" "+status);
if (extras!=null) {
String x = "";
for (String key : extras.keySet()) {
x+=key+":"+extras.get(key).toString()+", ";
}
Log.d("Status Changed Extras", x);
}
}
public void onProviderEnabled(String provider) {
Log.d("Provider Enabled", provider);
}
public void onProviderDisabled(String provider) {
Log.d("Provider Disabled", provider);
}
};
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
waitForLocation();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_REDELIVER_INTENT;
}
@Override
public void onDestroy() {
locationManager.removeUpdates(locationListener);
try {
wakeLock.release();
wakeLock = null;
}
catch (Exception e) {
wakeLock = null;
}
Log.d("LocationRecorder", "Destroying service");
super.onDestroy();
}
protected void waitForLocation() {
new Thread() {
@Override
public void run() {
setLocation(null);
for (int i=0; i<3;i++) {
Log.d("LocationRecorder", "Waiting for location");
try {Thread.sleep(10000);} catch(Exception e) {};
if (getLocation() != null) {
Log.d("LocationRecorder", "Sending new location!");
new Utilities(LocationRecorder.this).updateLocation(getLocation().getLatitude(),
getLocation().getLongitude(), getLocation().getAccuracy());
break;
}
}
stopSelf();
}
}.start();
}
public synchronized void setLocation(Location newLocation) {
lastLocation = newLocation;
}
public synchronized Location getLocation() {
return lastLocation;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}