屏幕关闭时,Android背景位置更新未到来

问题描述 投票:5回答:1

我们正在开发移动跟踪应用。对于位置更新,Fused location API以高精度作为优先级使用。

即使屏幕关闭,也需要更新位置。所以,我们正在使用背景Service。背景Service也获得部分WakeLock,以便设备不会进入睡眠状态。在后台Service,我们请求更新Service的位置更新。

问题是我们只在屏幕打开时接收位置更新。一旦屏幕关闭,位置更新就会停止。还有一个由Thread运行的Service,它在任何时候都没有被杀死。

BroadcastReceiver关闭屏幕时再次创建位置请求也不起作用。

这是背景Service类(RouteExecution):

private static final String TAG = "RouteExecution";

private static RouteExecution routeExecution = null;

private static GoogleApiClient mGoogleApiClient;
private static PendingIntent pendingIntent = null;
private PowerManager.WakeLock waitLock;
/**
 * Creates an IntentService.  Invoked by your subclass's constructor.
 */
public RouteExecution() {
    super(TAG);

    RouteExecution.routeExecution = this;
}

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

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

    mGoogleApiClient.connect();

    IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
    filter.addAction(Intent.ACTION_SCREEN_OFF);
    BroadcastReceiver mReceiver = new PowerButtonReceiver();
    registerReceiver(mReceiver, filter);

    PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    waitLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
    waitLock.acquire();
}

@Override
protected void onHandleIntent(Intent intent) {

    if (LocationResult.hasResult(intent)) {

        LocationResult locationResult = LocationResult.extractResult(intent);
        Location location = locationResult.getLastLocation();

        GPSLocation gpsLocation = new GPSLocation(location);

        Log.d(TAG, "Location Accuracy: " + location.getAccuracy() + " "
                + " has: " + location.hasAccuracy() + " Provider: " + location.getProvider()
                + " long: " + location.getLongitude() + " lat: " + location.getLatitude());
    }
}



public boolean checkLocationPermission() {

    if (ActivityCompat.checkSelfPermission(routeExecution, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(routeExecution, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        //    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 false;
    }

    return true;
}

public void createLocationListener() {

    if (!this.checkLocationPermission()) {
        return;
    }

    LocationRequest mLocationRequest = LocationRequest.create();
    mLocationRequest.setInterval(5000);
    mLocationRequest.setFastestInterval(5000);
    mLocationRequest.setSmallestDisplacement(0);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    PendingResult<Status> statusPendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
            mLocationRequest, pendingIntent);
}

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

    Log.d(TAG, mGoogleApiClient.isConnected() + "   On Connected");
    synchronized (this) {

            createLocationListener();
    }
}


public static GoogleApiClient getmGoogleApiClient() {
    return mGoogleApiClient;
}

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


    waitLock.release();
    mGoogleApiClient.disconnect();
}

public static RouteExecution getRouteExecution() {
    return routeExecution;
}

public static void setPendingIntent(PendingIntent pendingIntent) {
    RouteExecution.pendingIntent = pendingIntent;
}

Service开始使用AlarmManager。这是提取:

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent updateServiceIntent = new Intent(context, RouteExecution.class);
PendingIntent pendingUpdateIntent = PendingIntent.getService(context, 0, updateServiceIntent, 0);
RouteExecution.setPendingIntent(pendingUpdateIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP, 50000, pendingUpdateIntent);

BroadcastReceiver

public class PowerButtonReceiver extends BroadcastReceiver {
    private static final String TAG = "PowerButton";

    @Override
    public void onReceive(Context context, Intent intent) {

        Log.d(TAG, "Power Button");
        if (RouteExecution.getRouteExecution() != null) {
            RouteExecution.getRouteExecution().createLocationListener();
        }
    }
}

即使屏幕关闭,如何继续获取位置更新。

谢谢您的帮助。

android location background-service fusedlocationproviderapi android-fusedlocation
1个回答
1
投票

首先,在qazxsw poi中获得一个qazxsw poi根本不可靠。在执行代码之前,设备可以返回休眠状态。

我会打电话给WakeLock而不是Service,因为PendingIntent.getBroadcast()在技术上保证在PendingIntent.getService(),并从那里开始WakeLock

要么在qazxsw poi中获得一个qazxsw poi,在适当的时候开始你的qazxsw poi并从onReceive()释放Service

要么

使用WakeLock,基本上也是如此,而不必自己实现大部分逻辑。

另一个可能的问题是在棉花糖设备上使用onReceive()

如果Service处于活动状态,则此方法设置的警报不会在这些设备上触发。

在API级别23+上使用WakeLock而不是Service

© www.soinside.com 2019 - 2024. All rights reserved.