我正在寻找一种解决方案,以获取具有纬度,经度和速度参数的设备的位置。该解决方案在Android OS 8和更低版本上均应适用。
答案 0 :(得分:3)
Fused Location Provider用于获取Android中的位置。
这是通过后台服务使用融合位置提供程序获取连续位置的分步过程。
1)在gradle中添加位置服务API。
implementation 'com.google.android.gms:play-services-location:16.0.0'
2)在AndroidMenifest.xml
中声明所有必要的权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
android.permission.ACCESS_COARSE_LOCATION 和 android.permission.ACCESS_FINE_LOCATION 用于获取设备的位置。
android.permission.FOREGROUND_SERVICE 用于在Android 9.0中运行服务
3)创建LocationService
以获得继续的位置。
import android.Manifest;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;
public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
public static final String TAG = LocationService.class.getSimpleName();
private static final long LOCATION_REQUEST_INTERVAL = 10000;
private static final float LOCATION_REQUEST_DISPLACEMENT = 5.0f;
private GoogleApiClient mGoogleApiClient;
private FusedLocationProviderClient mFusedLocationProviderClient;
private LocationRequest mLocationRequest;
private LocationCallback mLocationCallback;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
buildGoogleApiClient();
showNotificationAndStartForegroundService();
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
//here you get the continues location updated based on the interval defined in
//location request
}
};
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
return START_STICKY;
}
/**
* Method used for building GoogleApiClient and add connection callback
*/
private synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
/**
* Method used for creating location request
* After successfully connection of the GoogleClient ,
* This method used for to request continues location
*/
private void createLocationRequest() {
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(LOCATION_REQUEST_INTERVAL);
mLocationRequest.setSmallestDisplacement(LOCATION_REQUEST_DISPLACEMENT);
requestLocationUpdate();
}
/**
* Method used for the request new location using Google FusedLocation Api
*/
private void requestLocationUpdate() {
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;
}
mFusedLocationProviderClient.getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
//get the last location of the device
}
});
mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest, mLocationCallback,
Looper.myLooper());
}
private void removeLocationUpdate() {
mFusedLocationProviderClient.removeLocationUpdates(mLocationCallback);
}
/**
* This Method shows notification for ForegroundService
* Start Foreground Service and Show Notification to user for android all version
*/
private void showNotificationAndStartForegroundService() {
final String CHANNEL_ID = BuildConfig.APPLICATION_ID.concat("_notification_id");
final String CHANNEL_NAME = BuildConfig.APPLICATION_ID.concat("_notification_name");
final int NOTIFICATION_ID = 100;
NotificationCompat.Builder builder;
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_NONE;
assert notificationManager != null;
NotificationChannel mChannel = notificationManager.getNotificationChannel(CHANNEL_ID);
if (mChannel == null) {
mChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, importance);
notificationManager.createNotificationChannel(mChannel);
}
builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(getString(R.string.app_name));
startForeground(NOTIFICATION_ID, builder.build());
} else {
builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(getString(R.string.app_name));
startForeground(NOTIFICATION_ID, builder.build());
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.d(TAG, "GoogleApi Client Connected");
createLocationRequest();
}
@Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "GoogleApi Client Suspended");
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.d(TAG, "GoogleApi Client Failed");
}
@Override
public void onDestroy() {
super.onDestroy();
removeLocationUpdate();
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
}
在LocationService
中,您首先必须使用Fushed Location Provider来构建GoogleApiClient
,然后再构建新的位置
根据mLocationCallback
中提供的时间间隔,您在mLocationRequest
中获得新位置。
4)在AndroidMenifest.xml
中声明服务
<service
android:name=".LocationService"
android:exported="false" />
5)现在从活动启动服务
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startForegroundService(new Intent(this, LocationService.class));
else
startService(new Intent(this, LocationService.class));