使用Foreground服务在Android的背景中获取GPS位置更新的最佳方法是什么
答案 0 :(得分:0)
每当应用程序在后台运行时,它都会消耗设备某些有限的资源,例如RAM。这会导致用户体验受损,尤其是在用户使用资源密集型应用程序(例如玩游戏或观看视频)的情况下。为了改善用户体验,Android 8.0(API级别26)对应用程序在后台运行时可以执行的操作施加了限制。
我已经开发了以下代码,并且在我这方面工作正常。
希望对您有帮助
(1)请在您的项目的Manifest.xml文件中的代码下面放置
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application>
<service
android:name="com.yourpackagename.location.LocationTracker"
android:stopWithTask="true"
/>
</application>
(2)在app.gradle文件中
implementation 'com.google.android.gms:play-services-location:16.0.0'
(2)请在您的项目中的服务行类代码下面放置,可以将位置结果(纬度,经度)保存在共享首选项或静态变量中,也可以在需要的地方绑定服务
public class LocationTracker extends Service implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
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 GoogleApiClient mGoogleApiClient;
private final int NOTIFICATION_ID = 9083150;
private final String CHANNEL_ID = "test123";
private final String CHANNEL_ID_NAME = "test123";
@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(Constant.CHANNEL_ID);
notificationManager.createNotificationChannel(channel);
Notification notification = createNotification(getApplicationContext(),Constant.CHANNEL_ID,0);
if (notification == null) {
notification = new NotificationCompat.Builder(this, Constant.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)
.setContentText("TEST")
.setOnlyAlertOnce(true)
.setOngoing(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.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);
//You can put location in sharedpreferences or static varibale and can use in app where need
}
@Override
public void onLocationAvailability(LocationAvailability locationAvailability) {
super.onLocationAvailability(locationAvailability);
}
};
}catch (Exception e){
e.printStackTrace();
}
}
private void init() {
try {
setLocationUpdateCallback();
buildGoogleApiClient();
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();
}
}
protected synchronized void buildGoogleApiClient() {
try {
mGoogleApiClient = null;
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
mGoogleApiClient.connect();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
init();
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onConnected(@Nullable Bundle bundle) {
startLocationUpdates();
}
public void requestingLocationUpdates() {
try {
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
} catch (SecurityException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
protected void startLocationUpdates() {
try {
if (mGoogleApiClient != null) {
mSettingsClient
.checkLocationSettings(
mLocationSettingsRequest)
.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@SuppressLint("MissingPermission")
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
Log.e(TAG, "LocationSettingsStatusCodes onSuccess");
requestingLocationUpdates();
}
})
.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");
requestingLocationUpdates();
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.e(TAG, "LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE");
}
}
});
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onDestroy() {
WakeLocker.releasePartialLock();
super.onDestroy();
}
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
}
public void stopLocationService(Context context) {
try {
stopForeground(true);
stopSelf();
} catch (Exception e) {
e.printStackTrace();
}
}
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();
}
}
}