2017-01-31 3 views
1

Я использую запущенный сервис с плавленым api и реализую прослушиватель местоположения прямо на нем. Местоположение сохраняется, даже когда экран заблокирован, но он останавливается, если экран выключается.Android, получить местоположение, когда экран выключен

Итак, есть ли способ убедиться, что местоположение будет продолжать обновляться, когда экран выключен?

Я прочитал много других вопросов, и я не знаю, что мне не хватает.

public class CLocationService extends Service implements GoogleApiClient.ConnectionCallbacks, LocationListener, 
    GoogleApiClient.OnConnectionFailedListener { 

private GoogleApiClient mGoogleApiClient; 
private PowerManager.WakeLock mWakeLock; 
private LocationRequest mLocationRequest; 
// Flag that indicates if a request is underway. 
private boolean mInProgress; 

private Boolean servicesAvailable = false; 

private boolean isStarted; 

public static final int LOCATION_SERVICE_NOTIFICATION_ID = 4567654; 

private void showNotification() { 

    Intent notificationIntent = new Intent(this, MainActivity.class); 
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 

    Notification notification = new Notification.Builder(this) 
      .setContentTitle(getText(R.string.app_name)) 
      .setContentText("") 
      .setSmallIcon(R.mipmap.ic_notification) 
      .setContentIntent(pendingIntent) 
      .setTicker("") 
      .build(); 

    startForeground(LOCATION_SERVICE_NOTIFICATION_ID, notification); 
} 

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

@Override 
public void onCreate() { 
    super.onCreate(); 

    /* 
    * Create a new location client, using the enclosing class to 
    * handle callbacks. 
    */ 
    setUpLocationClientIfNeeded(); 

    startLocationServices(); 
} 

/* 
* Create a new location client, using the enclosing class to 
* handle callbacks. 
*/ 
protected synchronized void buildGoogleApiClient() { 
    this.mGoogleApiClient = new GoogleApiClient.Builder(this) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .addApi(LocationServices.API) 
      .build(); 
} 

private boolean servicesConnected() { 

    // Check that Google Play services is available 
    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); 

    // If Google Play services is available 
    if (ConnectionResult.SUCCESS == resultCode) { 

     return true; 
    } else { 

     return false; 
    } 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

    PowerManager mgr = (PowerManager) getSystemService(Context.POWER_SERVICE); 

    /* 
    WakeLock is reference counted so we don't want to create multiple WakeLocks. So do a check before initializing and acquiring. 
    This will fix the "java.lang.Exception: WakeLock finalized while still held: MyWakeLock" error that you may find. 
    */ 
    if (this.mWakeLock == null) { //**Added this 
     this.mWakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock"); 
    } 

    if (!this.mWakeLock.isHeld()) { //**Added this 
     this.mWakeLock.acquire(); 
    } 

    if (!servicesAvailable || mGoogleApiClient.isConnected() || mInProgress) 
     return START_STICKY; 

    setUpLocationClientIfNeeded(); 
    if (!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting() && !mInProgress) { 
     mInProgress = true; 
     mGoogleApiClient.connect(); 
    } 

    return START_STICKY; 
} 

private void setUpLocationClientIfNeeded() { 
    if (mGoogleApiClient == null) 
     buildGoogleApiClient(); 
} 

@Override 
public void onDestroy() { 

    stopLocationServices(); 

    super.onDestroy(); 
} 

private void startLocationServices() { 

    mInProgress = false; 
    // Create the LocationRequest object 
    mLocationRequest = LocationRequest.create(); 
    // Use high accuracy 
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    // Set the update interval to 5 seconds 
    mLocationRequest.setInterval(5000); 
    // Set the fastest update interval to 1 second 
    mLocationRequest.setFastestInterval(1000); 
    mLocationRequest.setSmallestDisplacement(0); 

    servicesAvailable = servicesConnected(); 
} 

private void stopLocationServices() { 

    // Turn off the request flag 
    this.mInProgress = false; 

    if (this.servicesAvailable && this.mGoogleApiClient != null) { 
     this.mGoogleApiClient.unregisterConnectionCallbacks(this); 
     this.mGoogleApiClient.unregisterConnectionFailedListener(this); 
     this.mGoogleApiClient.disconnect(); 
     // Destroy the current location client 
     this.mGoogleApiClient = null; 
    } 
    // Display the connection status 
    // Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": 
    // Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show(); 

    if (this.mWakeLock != null) { 
     this.mWakeLock.release(); 
     this.mWakeLock = null; 
    } 
} 

private void cancelNotification() { 
    NotificationManager nMgr = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); 
    nMgr.cancel(LOCATION_SERVICE_NOTIFICATION_ID); 
} 

@Override 
public void onLocationChanged(Location location) { 
    // log the new location 
} 

@Override 
public void onConnected(@Nullable Bundle bundle) { 

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     // TODO: Consider calling 
     // ActivityCompat#requestPermissions 
     // here to request the missing permissions, and then overriding 
     // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
     //           int[] grantResults) 
     // to handle the case where the user grants the permission. See the documentation 
     // for ActivityCompat#requestPermissions for more details. 
     return; 
    } 
    LocationServices.FusedLocationApi.requestLocationUpdates(this.mGoogleApiClient, 
      mLocationRequest, this); // This is the changed line. 
} 

@Override 
public void onConnectionSuspended(int i) { 

    // Turn off the request flag 
    mInProgress = false; 
    // Destroy the current location client 
    mGoogleApiClient = null; 
} 

@Override 
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 

    mInProgress = false; 

    /* 
    * Google Play services can resolve some errors it detects. 
    * If the error has a resolution, try sending an Intent to 
    * start a Google Play services activity that can resolve 
    * error. 
    */ 
    if (connectionResult.hasResolution()) { 

     // If no resolution is available, display an error dialog 
    } else { 

    } 
} 

}

ответ

0

Я не уверен, что у меня есть свой ответ, но так как вы 9 дней ни с чем я дам несколько советов.

Мое приложение делает то, что вы хотели бы сделать. Я использую давно запущенную службу, чтобы поддерживать обновление, даже когда телефон выключен.

Разница, которая может привести к поведению между вашим кодом & mine is is return from onStartCommand(). Вы возвращаетесь START_STICKY. Это рекомендуемое возвращение что-то вроде этого:

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

Однако, я посылаю информацию в Intent, что мне нужно было, чтобы я повторно доставлена ​​я возвращаюсь START_REDELIVER_INTENT. Попробуйте это (даже если вам нет необходимости переадресовывать любые данные), чтобы узнать, исправляет ли он вашу проблему.

Кроме того, мне не нужно было WakeLock в моей реализации. Возможно, это требует вашей реализации. Вы пробовали без него?

Редактировать: Наконец, какое устройство вы используете? link

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