Android,当屏幕关闭时获取位置 [英] Android, get the location when the screen is off

查看:106
本文介绍了Android,当屏幕关闭时获取位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将启动的服务与融合的api一起使用,并直接在其上实现位置侦听器. 即使屏幕被锁定,该位置也会不断更新,但是如果屏幕关闭,它就会停止.

I use a started service with the fused api, and implement the location listener directly on it. The Location keeps updating even when the screen is locked, But it stops if the screen goes off.

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

So, is there any way to make sure that the location will keep updating when the screen is off?

我读了很多其他问题,但我真的不知道我在想什么.

I read a lot of other questions and I don't really know what i'm missing.

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 {

    }
}

}

推荐答案

我不确定我是否有您的答案,但是由于您已经9天没事了,我会提出一些建议.

I'm not sure I have your answer but since you're 9 days in with nothing I'll give some suggestions.

我的应用正在执行您想做的事情.我使用了长期运行的服务,即使在手机关机的情况下也能保持位置更新.

My app is doing what you would like to do. I use a long running started Service to keep location updated even when the phone is off.

最有可能导致您的代码与应用程序之间发生不同行为的差异.我的是onStartCommand()的收益.您正在返回START_STICKY.推荐的回报是这样的:

The difference most likely to cause different behavior between your code & mine is the return from onStartCommand(). You are returning START_STICKY. This is the recommended return for something like this:

此模式对将要显式启动的事物有意义,并且 停止运行任意时间,例如服务 进行背景音乐播放.

This mode makes sense for things that will be explicitly started and stopped to run for arbitrary periods of time, such as a service performing background music playback.

但是,我在需要重新传送的Intent中发送信息,因此我将返回START_REDELIVER_INTENT.尝试执行此操作(即使您无需重新传输任何数据)也可以查看它是否可以解决您的问题.

However, I'm sending info in the Intent that I needed to have redelivered so I'm returning START_REDELIVER_INTENT. Try this (even if you have no need to redeliver any data) to see if it fixes your problem.

此外,我的实现中不需要WakeLock.也许您的实现需要这个.您尝试过没有它吗?

Also, I didn't need WakeLock in my implementation. Maybe your implementation needs this though. Have you tried without it?

最后,您正在使用哪种设备? 链接

Lastly, what kind of device are you using? link

这篇关于Android,当屏幕关闭时获取位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆