我正在開發體育跟蹤應用程序,即使屏幕關閉並且手機在口袋裏,也使用位置管理器和GPS提供商獲取位置更新。定位服務被打盹模式停止
當用戶在我的活動中按下開始按鈕時,我在前臺啓動服務,顯示通知和註冊位置監聽器。
服務開始接收位置更新並將它們寫入我的跟蹤文件。
突然我收到日誌消息'電源管理器空閒模式:真',手機進入打盹模式,我的服務停止獲取任何位置更新,直到手機醒來。
我閱讀了關於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);
}
}
發現對M這個Android的bug:https://code.google.com/p/android/issues/detail?id=193802,也許這是我的情況太多,但我不知道,因爲我得到了相同的行爲也在android 7.1.1上。 –