我有一个android应用程序,它跟踪客户位置并每10秒发送一次位置信息,但是,在android O中,每小时都会获取几次位置更新,如有关android O中gps位置更新限制的文档所述无论如何,为了克服这个问题,我使用了带有通知的前台服务,以便gps位置更新在熔融位置保持更新。 之后,我面临另一个问题,即融合位置中的速度和方向为零,因为它从网络提供商和gps提供者那里获取位置,而当位置来自网络提供商时,速度和方向为零,这些信息对我很重要,并且我将位置服务切换为LocationManager而不是fusedLocation,因此我只能确定gps提供程序,因为fusedLocation中不提供此功能。 但是我注意到,即使我为此目的使用前台服务,Android O中的LocationManager在后台也不会获得位置更新。如何获得一种在后台不断更新位置并仅使用gps提供程序的解决方案?
我没有代码片段,我只想讨论这个问题。
答案 0 :(得分:0)
尝试下面的代码行
在AndroidManifest.xml中编写以下代码行
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application>
<service
android:name=".LocationTracker"
android:stopWithTask="true"
/>
</application>
从您要开始服务的地方编写代码行
LocationTracker.startLocationService(getApplicationContext());
在服务类中写入以下代码
public class LocationTracker extends Service{
private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 1000;
private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 1000;
private static int DISPLACEMENT = 0;
private FusedLocationProviderClient mFusedLocationClient;
private LocationRequest mLocationRequest;
private SettingsClient mSettingsClient;
private LocationSettingsRequest mLocationSettingsRequest;
private LocationCallback mLocationCallback;
private String TAG = LocationTracker.class.getSimpleName();
private final int NOTIFICATION_ID = 9083150;
public static final String CHANNEL_ID = "CHANNEL_ID";
public static final String CHANNEL_ID_NAME = "CHANNEL_ID_NAME";
@Override
public void onCreate() {
super.onCreate();
try {
if (Build.VERSION.SDK_INT >= 26) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID_NAME,
NotificationManager.IMPORTANCE_HIGH);
channel.setSound(null, null);
channel.setShowBadge(false);
NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.deleteNotificationChannel(CHANNEL_ID);
notificationManager.createNotificationChannel(channel);
Notification notification = createNotification(getApplicationContext(),CHANNEL_ID,0);
if (notification == null) {
notification = new NotificationCompat.Builder(this, CHANNEL_ID).build();
}
startForeground(NOTIFICATION_ID, notification);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private Notification createNotification(Context context, String channelid,int type) {
try {
return new NotificationCompat.Builder(context,channelid)
.setContentTitle("")
.setContentText("")
.setOnlyAlertOnce(true)
.setOngoing(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setVisibility(Notification.VISIBILITY_PRIVATE)
.setSmallIcon(R.mipmap.ic_launcher)
.build();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void setLocationUpdateCallback() {
try {
mLocationCallback = null;
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
Logger.i(TAG, "locationResult ==== " + locationResult);
}
};
}catch (Exception e){
e.printStackTrace();
}
}
private void init() {
try {
setLocationUpdateCallback();
mFusedLocationClient = null;
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mSettingsClient = LocationServices.getSettingsClient(this);
mLocationRequest = null;
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
mLocationSettingsRequest = null;
mLocationSettingsRequest = builder.build();
} catch (SecurityException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
init();
startLocationUpdates();
return START_STICKY;
}
@androidx.annotation.Nullable
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
protected void startLocationUpdates() {
mSettingsClient
.checkLocationSettings(
mLocationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@SuppressLint("MissingPermission")
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
Log.e(TAG, "LocationSettingsStatusCodes onSuccess");
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
int statusCode = ((ApiException) e).getStatusCode();
switch (statusCode) {
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.e(TAG, "LocationSettingsStatusCodes.RESOLUTION_REQUIRED");
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.e(TAG, "LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE");
}
}
});
}
public static void startLocationService(Context context) {
try {
Intent intent = new Intent(context, LocationTracker.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ContextCompat.startForegroundService(context, intent);
} else {
context.startService(intent);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
希望对您有帮助