Android,在屏幕关闭时获取位置

时间:2017-01-31 19:20:24

标签: android service location android-gps

我使用融合api启动服务,并直接在其上实现位置监听器。 即使屏幕被锁定,位置也会不断更新,但如果屏幕熄灭,它会停止。

那么,有什么方法可以确保屏幕关闭时该位置会不断更新?

我读了很多其他问题而且我真的不知道自己错过了什么。

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 {

    }
}

}

1 个答案:

答案 0 :(得分:0)

我不确定我有你的答案但是因为你没有任何东西,我会提出一些建议。

我的应用正在做您想做的事情。即使手机关机,我也会使用长时间启动的服务来保持位置更新。

差异最有可能导致您的代码和代码之间出现不同的行为;我的是onStartCommand()的回归。您正在返回START_STICKY。这是建议的回报:

  

此模式适用于将明确启动的内容   停止运行任意时间段,例如服务   表演背景音乐播放。

但是,我在Intent发送了我需要重新传送的信息,所以我正在返回START_REDELIVER_INTENT。试试这个(即使你没有必要重新发送任何数据),看它是否能解决你的问题。

另外,我的实现中不需要WakeLock。也许你的实现需要这个。没有它你试过吗?

编辑:最后,您使用的是哪种设备? link