gpt4 book ai didi

屏幕关闭时,Android 后台位置更新不会到来

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:11:16 31 4
gpt4 key购买 nike

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

即使在屏幕关闭时也需要更新位置。因此,我们正在使用后台 Service。后台 Service 也在获取部分 WakeLock,这样设备就不会进入休眠状态。在后台 Service 中,我们通过 Service 的未决更新请求位置更新。

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

在屏幕关闭时通过 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);

广播接收器:

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();
}
}
}

如何在屏幕关闭时继续获取位置更新。

感谢您的帮助。

最佳答案

首先,获取 WakeLockService一点都不可靠。设备可以在该代码执行之前返回休眠状态。

我会调用 PendingIntent.getBroadcast()而不是 PendingIntent.getService() , 因为 WakeLock onReceive()期间技术保证, 并启动 Service从那里开始。

要么获得 WakeLockonReceive() , 开始你的 Service并释放 WakeLock来自 Service , 在适当的时候

使用 WakefulBroadcastReceiver ,它基本上做同样的事情,而不必自己实现大部分逻辑。

另一个可能的问题是使用 AlarmManager.set()在 Marshmallow 设备上。

如果 Doze,通过此方法设置的警报将不会在这些设备上触发处于 Activity 状态。

使用 setAndAllowWhileIdle()而不是 set() API 级别 23+。

关于屏幕关闭时,Android 后台位置更新不会到来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39343632/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com