То же местоположение обновляется в фоновом режиме, хотя я значительно переместился
У меня есть сервис, который запрашивает обновления сетевого расположения в onCreateMethod. Я использовал LocationListener для получения новых местоположений, статуса провайдеров и statusChange в провайдере.
Когда устройство находится в состоянии низкого энергопотребления (экран телефона выключен), я получаю такое же исправление местоположения, которое было у поставщика сети, когда экран телефона был активен (экран включен).
public class LocationRegisterService extends Service implements LocationListener{
private String TAG = LocationRegisterService.class.getName();
private LocationManager lm;
public void onCreate()
{
Log.d(TAG,"Entering LocationRegisterService::onCreate()");
//Register for network location updates
lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
Log.i(TAG,"Regsitering for Network Location Updates");
Log.i(TAG,"minTime = 0,minDistance = 0");
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
Log.d(TAG,"Exiting LocationRegisterSerivce::onCreate()");
}
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d(TAG,"Entering LocationRegisterService::onStartCommand()");
Log.d(TAG,"Exiting LocationRegisterService::onStartCommand()");
return Service.START_STICKY;
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
public void onDestroy()
{
super.onDestroy();
Log.d(TAG,"Entering LocationRegisterService::onDestroy()");
lm.removeUpdates(this);
Log.d(TAG,"Exiting LocationRegisterService::onDestroy()");
}
@Override
public void onLocationChanged(Location location) {
Helpers.logScreenStatus(this);
double latitude = location.getLatitude();
double longitude = location.getLongitude();
double accuracy = location.getAccuracy();
String location_timestamp = formatTime(location.getTime());
String log = latitude + "," + longitude +","+accuracy+","+location_timestamp;
Log.i(TAG,log);
}
@Override
public void onProviderDisabled(String provider) {
String log = "Network Provider Disabled";
}
@Override
public void onProviderEnabled(String provider) {
String log = "Network Provider Enabled";
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
String log = "";
switch(status){
case LocationProvider.AVAILABLE:
log = "Network Available";
break;
case LocationProvider.OUT_OF_SERVICE:
log = "Network Out Of Service";
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE:
log = "Network Temporarily Unavailable";
break;
}
setServiceWakeUpTime();
stopSelf();
}
private void setServiceWakeUpTime()
{
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this,AlarmReceiver.class);
PendingIntent operation = PendingIntent.getBroadcast(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
long wakeAt = System.currentTimeMillis() + (60 * 1000);
am.set(AlarmManager.RTC_WAKEUP, wakeAt , operation);
FileLogger.log(this, "Service will wake up after one minute");
}
private String formatTime(long epoch)
{
Date date = new Date(epoch);
String pattern = "y/M/d H:m:s.S";
SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
return dateFormat.format(date);
}
}
Я запустил этот сервис с активности и проехал почти 50 км с выключенным экраном устройства. Я прилагаю журналы путешествий.
2013/3/21 0:29:58.743 Entering Broadcast Receiver
2013/3/21 0:29:58.756 Screen is off
2013/3/21 0:29:58.778 Exiting Broadcast Receiver
2013/3/21 0:29:58.783 Registering for network location updates
2013/3/21 0:30:53.571 Screen is off
2013/3/21 0:30:53.587 13.07383585,80.22151335000001,50.0,2013/3/21 0:30:8.551
2013/3/21 0:30:53.593 Screen is off
2013/3/21 0:30:53.595 Network Temporarily Unavailable
2013/3/21 0:30:53.613 Service will wake up after one minute
2013/3/21 0:30:53.619 UnRegistering listener for location updates
2013/3/21 0:31:53.676 Entering Broadcast Receiver
2013/3/21 0:31:53.689 Screen is off
2013/3/21 0:31:53.710 Exiting Broadcast Receiver
2013/3/21 0:31:58.516 Registering for network location updates
2013/3/21 0:32:17.583 Screen is off
2013/3/21 0:32:17.594 13.07383585,80.22151335000001,50.0,2013/3/21 0:32:3.544
Один и тот же журнал повторяется почти час. Этот код был запущен в HTC Explorer с Android 2.3.3. У кого-нибудь есть ответ за такое поведение?
1 ответ
Проблема получения одинаковых обновлений местоположения возникает только в мобильных телефонах HTC. Я не знаю, происходит ли это на всех телефонах HTC Android. Но это происходит наверняка на моем HTC Explorer.
Причина получения обновлений для одного и того же местоположения в фоновом режиме заключается в том, что, если телефон не используется более 15 минут, HTC отключает добавление активных подключений к Интернету (WIFI или мобильное подключение для передачи данных). Чтобы проверить это, я написал следующий код.
- Операция, которая запланирует вызов AlarmReceiver через одну минуту.
- Приемник тревог проверяет, есть ли какое-либо соединение, через которое может быть установлено интернет-соединение.
- Приемник тревог регистрирует тревогу для вызова через одну минуту
Я сделал код, чтобы пробежать всю ночь.
public class AlarmReceiver extends BroadcastReceiver {
private static String TAG = AlarmReceiver.class.getName();
@Override
public void onReceive(Context context, Intent intent)
{
Log.i(TAG, "Entering Broadcast Receiver onReceive");
FileLogger.log(context, "Entering Broadcast Receiver");
logActiveNetworkInfo(context);
setAlarm(context);
FileLogger.log(context, "Exiting Broadcast Receiver");
Log.i(TAG, "Exiting Broadcast Receiver onReceive");
}
private void logActiveNetworkInfo(Context context)
{
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if(networkInfo == null)
{
FileLogger.log(context, "No network connectivity");
return;
}
String networkTypeName = networkInfo.getTypeName();
boolean isConnected = networkInfo.isConnected();
String log = "";
if(isConnected == true)
{
log = "Internet available through " + networkTypeName;
}
else
log = "Internet not available through "+ networkTypeName;
FileLogger.log(context, log);
Log.i(TAG,log);
return;
}
private void setAlarm(Context context)
{
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
long wakeUpAt = System.currentTimeMillis() + (60 * 1000);
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent operation = PendingIntent.getBroadcast(context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, wakeUpAt , operation);
Log.i(TAG,"Alarm set to ring after "+wakeUpAt + " milliseconds");
}
}
Поэтому разработчики приложений должны быть осторожны: если вы хотите сделать HTTP-вызов в фоновом режиме в телефоне HTC, произойдет сбой, если телефон не будет работать более пятнадцати минут.
Об этой проблеме было сообщено HTC Deep Sleep