2016-12-18 5 views
2

私は、画面がオフで携帯電話がポケットに入っていても毎秒位置情報を取得するために位置マネージャとGPSプロバイダーを使用するスポーツ追跡アプリケーションを開発しています。ドーズモードで位置サービスが停止しました

アクティビティでユーザが[開始]ボタンを押すと、サービスがフォアグラウンドで開始され、通知が表示され、ロケーションリスナが登録されます。

サービスは、ロケーション更新を受信し始め、トラックファイルに書き込みます。

突然、「Power manager idle mode:true」というメッセージが表示され、電話がDozeモードになり、電話機がスリープ状態になるまでサービスが停止します。

私はDoze modeに関するドキュメントを読んで、ロケーションサービスには影響してはいけないと考えていますが、私の場合はそうです。

私は何か間違っているかもしれません。ここに私のサービスのコードは、任意のヘルプは本当に感謝しています。 ACTION_DEVICE_IDLE_MODE_CHANGEDが発射されるとき

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

それは与えられた、居眠りをオンまたはオフにされたされていないこと。アイドルモードに影響する可能性がある要因はほかにもあります。

WakeLockを作成して取得してください。 Mのために、このアンドロイドのバグ発見

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モードに入ることについて、このログ出力を行うリスナーをインストールしました。また、 'Doze Restrictions'では、 'システムはウェイクロックを無視する'と述べています。 –

関連する問題