2016-12-18 7 views
2

Я разрабатываю приложение для отслеживания спортивных событий, которое использует диспетчер местоположения и поставщик gps для получения обновлений местоположения каждую секунду, даже если экран выключен, а телефон находится в кармане.Служба определения местоположения была остановлена ​​в режиме Doze

Когда пользователь нажал кнопку запуска в своей деятельности, я запускаю службу на переднем плане, вывешиваю уведомление и регистрирую регистратор.

Служба начинает получать обновления местоположения и записывает их в файл трека.

Внезапно я получаю сообщение журнала «Режим ожидания в режиме ожидания: истина», телефон переходит в режим «Дозирование», и мое устройство перестает получать обновления местоположения до тех пор, пока телефон не проснется.

Я читал документы о Doze mode и вижу, что он не должен влиять на службы определения местоположения, но это происходит в моем случае.

Может быть, я делаю что-то неправильно. Вот код моего сервиса, любая помощь действительно оценена.

public class LocService 
    extends Service 
implements LocationListener, GpsStatus.Listener 
{ 

private String mName; 
private volatile Looper mServiceLooper; 
private volatile ServiceHandler mServiceHandler; 
private LocationManager locationManager; 

public LocService(String name) 
{ 
    super(); 
    mName = name; 
} 

private final class ServiceHandler extends Handler 
{ 
    public ServiceHandler(Looper looper) 
    { 
     super(looper); 
    } 

    @Override 
    public void handleMessage(Message msg) 
    { 
     if (msg != null && msg.obj != null) 
     { 
      onHandleIntent((Intent)msg.obj); 
     } 
     else 
     { 
      logMessage("msg for intent is not good"); 
     } 
    } 
} 

@Override 
public void onCreate() 
{ 
    super.onCreate(); 
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); 
    thread.start(); 

    mServiceLooper = thread.getLooper(); 
    mServiceHandler = new ServiceHandler(mServiceLooper); 

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
    { 
     logMessage("Enabling Doze mode listener"); 
     IntentFilter filter = new IntentFilter(); 
     filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); 
     registerReceiver(new BroadcastReceiver() 
     { 
      @Override 
      public void onReceive(Context context, Intent intent) 
      { 
       onDeviceIdleChanged(); 
      } 
     }, filter); 
    } 

    locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); 
} 

@TargetApi(Build.VERSION_CODES.M) 
private void onDeviceIdleChanged() 
{ 
    PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); 
    if(powerManager != null) 
    { 
     logMessage("Power manager idle mode: " + powerManager.isDeviceIdleMode()); 
    } else 
    { 
     logMessage("Power manager idle changed to ?"); 
    } 
} 

protected void onHandleIntent(Intent intent) 
{ 
    //call start/stop location logging on proper intent 
    if(intent.getIntExtra("cmd", -1) == 1) 
    { 
     startLogging(); 
    } else 
    { 
     stopLogging(); 
    } 
} 

private void startLogging() 
{ 
    logMessage("LocationService.startLogging"); 
    try 
    { 
     locationManager.addGpsStatusListener(this); 
     locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 0, this); 
     logMessage("requesting gps updates"); 

     startForeground(ONGOING_NOTIFICATION, getNotification(-1, -1, true, false)); 
     logMessage("Sending foreground service notification"); 

    } 
    catch (SecurityException ex) 
    { 
     logMessage(" SecurityException while requesting location info: " + ex); 
    } 
} 

private void stopLogging() 
{ 
    try 
    { 
     locationManager.removeUpdates(this); 

     stopForeground(true); 
     notificationManager.cancel(ONGOING_NOTIFICATION); 
    } 
    catch (SecurityException ex) 
    { 
     logMessage(" SecurityException on stopLogging with location manager: " + ex); 
    } 

} 


@Override 
public void onLocationChanged(Location location) 
{ 
    //save location lat, lon directly to track file 
    //flush file 
} 

@Override 
public void onStatusChanged(String provider, int status, Bundle extras) 
{ 
    //do nothing 
} 

@Override 
public void onProviderEnabled(String provider) 
{ 
    logMessage("Location provider enabled " + provider); 
} 

@Override 
public void onProviderDisabled(String provider) 
{ 
    logMessage("Location provider disabled " + provider); 
} 

@Override 
public void onGpsStatusChanged(int event) 
{ 
    try 
    { 
     logMessage(" *** onGpsStatusChanged with " + event); 
     GpsStatus status = locationManager.getGpsStatus(null); 
     int inFix = 0; 
     int total = 0; 
     for (GpsSatellite satellite : status.getSatellites()) 
     { 
      if (satellite.usedInFix()) inFix++; 
      total++; 
     } 
     logMessage(" Sats: " + total + " in fix " + inFix); 
    } 
    catch (SecurityException sex) 
    { 
    } 
    catch (Exception ex) 
    { 
    } 
} 

@Override 
public void onStart(Intent intent, int startId) 
{ 
    Message msg = mServiceHandler.obtainMessage(); 
    msg.arg1 = startId; 
    msg.obj = intent; 
    mServiceHandler.sendMessage(msg); 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) 
{ 
    onStart(intent, startId); 
    return START_STICKY; 
} 

@Override 
public void onDestroy() 
{ 
    mServiceLooper.quit(); 
    try 
    { 
     locationManager.removeUpdates(this); 
    } 
    catch (SecurityException ex) 
    { 
     logMessage(" SecurityException on Destroy service with location manager: " + ex); 
    } 
} 

@Override 
public IBinder onBind(Intent intent) 
{ 
    return null; 
} 

private void logMessage(String msg) 
{ 
    Log.i("LocServ", msg); 
} 
} 
+0

Найдено этот андроид ошибка для М: https://code.google.com/p/android/issues/detail?id=193802, наверное, это мой случай тоже, но я не уверен, как я получил то же самое поведение на android 7.1.1 тоже. –

ответ

-1

Это не факт, что, когда ACTION_DEVICE_IDLE_MODE_CHANGED обжигают, доза была либо включен или выключен. Есть больше факторов, которые могут повлиять на режим ожидания.

Попробуйте создать и приобрести WakeLock.

PowerManager.WakeLock getLock(Context context, String lockName) { 
     if (wakeLock == null) { 
      PowerManager mgr = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 
      wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName); 
     } 
     return wakeLock; 
    } 

    //on start service 
    getLock(ctxt.getApplicationContext(), "lockName").acquire(); 


    //on destroy service 
    @Override 
    public void onDestroy() { 
     PowerManager.WakeLock lock = getLock(this.getApplicationContext(), "lockName"); 
     if (lock.isHeld()) { 
      lock.release(); 
     } 
     super.onDestroy(); 
    } 
+1

У меня установлен слушатель, который делает этот вывод журнала о том, что устройство переходит в режим доз. Также в «Doze Restrictions» сказано, что «система игнорирует блокировки слежения». –

 Смежные вопросы

  • Нет связанных вопросов^_^