我在地图上创建了一个浮动按钮。我想通过单击该按钮在地图上显示当前位置。
答案 0 :(得分:0)
这些将最终用户视为一个进程。但是接收位置并将其显示在地图上实际上是两个过程。我建立了一个类,因为我在用例上需要它。但我可以向您展示如何与您的案子融为一体。
class LocationTracker(
val activity: FragmentActivity,
val locationTrackerListener: LocationTrackerListener
) {
private var fusedLocationClient: FusedLocationProviderClient =
LocationServices.getFusedLocationProviderClient(activity)
private var locationCallback: LocationCallback? = null
private var locationRequest: LocationRequest? = null
fun startLocationRequestProcess() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(
activity.applicationContext, Manifest.permission.ACCESS_COARSE_LOCATION
)
!= PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(
activity.applicationContext, Manifest.permission.ACCESS_FINE_LOCATION
)
!= PackageManager.PERMISSION_GRANTED
) {
activity.requestPermissions(
arrayOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
), REQUEST_LOCATION_PERMISSION
)
} else {
getUserLocation()
}
} else {
getUserLocation()
}
}
fun getUserLocation() {
locationRequest = LocationRequest.create()?.apply {
interval = 10000
fastestInterval = 5000
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
//please check the docs for other constants. this is the minimum used
}
val builder = LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest!!)
val client: SettingsClient = LocationServices.getSettingsClient(activity)
val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())
task.addOnSuccessListener {
updateLocation()
}
task.addOnFailureListener { exception ->
if (exception is ResolvableApiException) {
try {
exception.startResolutionForResult(
activity,
REQUEST_CHECK_LOCATION_SETTINGS
)
} catch (sendEx: IntentSender.SendIntentException) {
sendEx.printStackTrace()
}
}
}
}
fun updateLocation() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(
activity.applicationContext, Manifest.permission.ACCESS_COARSE_LOCATION
)
!= PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(
activity.applicationContext, Manifest.permission.ACCESS_FINE_LOCATION
)
!= PackageManager.PERMISSION_GRANTED
) {
activity.requestPermissions(
arrayOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
), REQUEST_LOCATION_PERMISSION
)
} else {
requestLocationUpdates()
}
} else {
requestLocationUpdates()
}
}
private fun requestLocationUpdates() {
try {
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
if (locationResult == null) {
locationTrackerListener.onLocationError()
} else {
//you've got the response
locationTrackerListener.onLocationResult(locationResult)
}
}
}
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null)
} catch (securityException: SecurityException) {
securityException.printStackTrace()
}
}
fun removeLocationRequest() {
fusedLocationClient.removeLocationUpdates(locationCallback)
}
}
设置了班级:按一下按钮onClick
:
fab.setOnClickListener{
//hope you have instatiated it
locationTracker.startLocationRequestProcess()
}
然后在课程中您需要纬度和经度:
override fun onLocationResult(locationResult: LocationResult) {
for (location in locationResult.locations) {
addMarkerToMapAndPerhapsZoom(location.latitude, location.longitude)
}
}
我正在使用的界面:
interface LocationTrackerListener {
fun onLocationError()
fun onLocationResult(locationResult: LocationResult)
}
请为权限使用重复的代码,但是在重构该代码时IDE会显示错误,我真的很讨厌它。您还可以考虑获取last known location,但是这样做的问题是,当用户首次访问该应用程序时,它会提供null。
答案 1 :(得分:0)
首先创建MyLocation
这样的类:
import java.util.Timer;
import java.util.TimerTask;
import android.annotation.SuppressLint;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
public class MyLocation {
Timer timer1;
LocationManager lm;
LocationResult locationResult;
boolean gps_enabled = false;
boolean network_enabled = false;
@SuppressLint("MissingPermission")
public boolean getLocation(Context context, LocationResult result) {
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult = result;
if (lm == null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
}
try {
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
}
//don't start listeners if no provider is enabled
if (!gps_enabled && !network_enabled)
return false;
if (gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if (network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1 = new Timer();
timer1.schedule(new GetLastLocation(), 20000);
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
LocationListener locationListenerNetwork = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
}
public void onStatusChanged(String provider, int status, Bundle extras) {
}
};
class GetLastLocation extends TimerTask {
@SuppressLint("MissingPermission")
@Override
public void run() {
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc = null, gps_loc = null;
if (gps_enabled)
gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (network_enabled)
net_loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if (gps_loc != null && net_loc != null) {
if (gps_loc.getTime() > net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if (gps_loc != null) {
locationResult.gotLocation(gps_loc);
return;
}
if (net_loc != null) {
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
public static abstract class LocationResult {
public abstract void gotLocation(Location location);
}
}
然后在您的googleMap类中使用它:
floatingButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& context.checkSelfPermission(
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
context.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
} else {
MyLocation.LocationResult locationResult = new MyLocation.LocationResult() {
@Override
public void gotLocation(Location location) {
if (location != null) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(latLng, 14);
mGoogleMap.animateCamera(update);
}
}
};
MyLocation myLocation = new MyLocation();
myLocation.getLocation(this, locationResult);
}
}
});
并且不要忘记在您的ACCESS_FINE_LOCATION
中添加权限AndroidManifest
:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />