J'ai une application Android qui nécessite l'emplacement actuel du périphérique (latitude et longitude). J'ai essayé un didacticiel sur Internet et plus particulièrement des solutions de débordement de pile, mais elles ne fonctionnent pas bien. Mon exigence est si simple: d’abord, j’ai besoin d’être rapide et de localiser le fragment une fois que j’ai commencé. Ensuite, j’ai besoin d’être aussi précis que possible. utiliser le fournisseur de réseau.
Par exemple, j'ai essayé cette solution mais elle retourne à zéro après 30 secondes, mais je sais qu'il y en a toutes les choses qui vont, car Google Map et d'autres applications fonctionnent bien !!!
Quelque chose que presque toutes les réponses suggèrent est d'utiliser getLastKnownLocation (), mais je suppose que ce n'est pas le courant et que je ne le veux pas s'il en est ainsi.
quelqu'un peut-il me suggérer une méthode simple et rapide pour obtenir l'emplacement UNE FOIS?!
Merci d'avance
Ici, vous pouvez utiliser ceci ...
Exemple d'utilisation:
public void foo(Context context) {
// when you need location
// if inside activity context = this;
SingleShotLocationProvider.requestSingleUpdate(context,
new SingleShotLocationProvider.LocationCallback() {
@Override public void onNewLocationAvailable(GPSCoordinates location) {
Log.d("Location", "my location is " + location.toString());
}
});
}
Vous voudrez peut-être vérifier que les lat/long sont des valeurs réelles et non 0 ou quelque chose. Si je me souviens bien, cela ne devrait pas générer un NPE, mais vous voudrez peut-être vérifier.
public class SingleShotLocationProvider {
public static interface LocationCallback {
public void onNewLocationAvailable(GPSCoordinates location);
}
// calls back to calling thread, note this is for low grain: if you want higher precision, swap the
// contents of the else and if. Also be sure to check gps permission/settings are allowed.
// call usually takes <10ms
public static void requestSingleUpdate(final Context context, final LocationCallback callback) {
final LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (isNetworkEnabled) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_COARSE);
locationManager.requestSingleUpdate(criteria, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
callback.onNewLocationAvailable(new GPSCoordinates(location.getLatitude(), location.getLongitude()));
}
@Override public void onStatusChanged(String provider, int status, Bundle extras) { }
@Override public void onProviderEnabled(String provider) { }
@Override public void onProviderDisabled(String provider) { }
}, null);
} else {
boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (isGPSEnabled) {
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
locationManager.requestSingleUpdate(criteria, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
callback.onNewLocationAvailable(new GPSCoordinates(location.getLatitude(), location.getLongitude()));
}
@Override public void onStatusChanged(String provider, int status, Bundle extras) { }
@Override public void onProviderEnabled(String provider) { }
@Override public void onProviderDisabled(String provider) { }
}, null);
}
}
}
// consider returning Location instead of this dummy wrapper class
public static class GPSCoordinates {
public float longitude = -1;
public float latitude = -1;
public GPSCoordinates(float theLatitude, float theLongitude) {
longitude = theLongitude;
latitude = theLatitude;
}
public GPSCoordinates(double theLatitude, double theLongitude) {
longitude = (float) theLongitude;
latitude = (float) theLatitude;
}
}
}
AndroidManifest.xml
<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" /> <uses-feature Android:name="Android.hardware.location.gps" />
build.gradle (Module: app)
dependencies {
...
implementation 'com.google.Android.gms:play-services-location:15.0.0'
...
}
Si vous recevez une erreur, vérifiez que votre build.gradle de niveau supérieur contient une référence au référentiel google () ou à maven {url " https://maven.google.com "}
Configurer les services Google Play
LocationService.kt
import Android.Manifest
import Android.annotation.SuppressLint
import Android.app.Activity
import Android.content.Intent
import Android.content.pm.PackageManager
import Android.location.Location
import Android.net.Uri
import Android.os.Looper
import Android.provider.Settings
import Android.support.v4.app.ActivityCompat
import Android.support.v4.content.ContextCompat
import com.google.Android.gms.common.api.ApiException
import com.google.Android.gms.common.api.ResolvableApiException
import com.google.Android.gms.location.*
import org.jetbrains.anko.alert
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.okButton
object LocationService {
@SuppressLint("StaticFieldLeak")
private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
private lateinit var locationRequest: LocationRequest
private val locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
doAsync {
location = locationResult.lastLocation
onSuccess(location)
}
}
}
private lateinit var onSuccess: (location : Location) -> Unit
private lateinit var onError: () -> Unit
lateinit var location: Location
fun init(activity: Activity) {
fusedLocationProviderClient = FusedLocationProviderClient(activity)
locationRequest = LocationRequest().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY).setInterval(1000).setFastestInterval(1000).setNumUpdates(1)
}
private fun checkLocationStatusAndGetLocation(activity: Activity) {
doAsync {
when {
ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED -> LocationServices.getSettingsClient(activity).checkLocationSettings(LocationSettingsRequest.Builder().addLocationRequest(locationRequest).setAlwaysShow(true).build()).addOnCompleteListener { task ->
doAsync {
try {
task.getResult(ApiException::class.Java)
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
} catch (exception: ApiException) {
when (exception.statusCode) {
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
try {
(exception as ResolvableApiException).startResolutionForResult(activity, 7025)
} catch (ex: Exception) {
promptShowLocation(activity)
}
}
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
promptShowLocation(activity)
}
}
}
}
}
ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_FINE_LOCATION) -> activity.runOnUiThread {
activity.alert("To continue, allow the device to use location, witch uses Google's Location Service") {
okButton {
val ite = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.fromParts("package", activity.packageName, null))
ite.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
activity.startActivity(ite)
onError()
}
negativeButton("Cancelar", { onError() })
onCancelled { onError() }
}.show()
}
else -> ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 7024)
}
}
}
private fun promptShowLocation(activity: Activity) {
activity.runOnUiThread {
activity.alert("To continue, allow the device to use location, witch uses Google's Location Service") {
okButton {
activity.startActivity(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS))
onError()
}
negativeButton("Cancelar", { onError() })
onCancelled { onError() }
}.show()
}
}
fun onRequestPermissionsResult(activity: Activity, requestCode: Int, grantResults: IntArray) {
if (requestCode == 7024) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
checkLocationStatusAndGetLocation(activity)
} else {
onError()
}
}
}
fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int) {
if (requestCode == 7025) {
if (resultCode == Activity.RESULT_OK) {
checkLocationStatusAndGetLocation(activity)
} else {
onError()
}
}
}
fun getLocation(activity: Activity, onSuccess: () -> Unit, onError: () -> Unit) {
this.onSuccess = onSuccess
this.onError = onError
checkLocationStatusAndGetLocation(activity)
}
}
votre activité
override fun onCreate(savedInstanceState: Bundle?) {
...
LocationService.init(this)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
LocationService.onRequestPermissionsResult(this, requestCode, grantResults)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
LocationService.onActivityResult(this, requestCode, resultCode)
}
private fun yourFunction() {
LocationService.getLocation(this, { location ->
//TODO: use the location
}, {
//TODO: display error message
})
}
AndroidManifest.xml:
<uses-permission Android:name="Android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" />
<uses-feature Android:name="Android.hardware.location.gps" />
MainActivity.Java:
public class MainActivity extends AppCompatActivity implements LocationListener {
private LocationManager locationManager;
private Location onlyOneLocation;
private final int REQUEST_FINE_LOCATION = 1234;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION);
}
@Override public void onLocationChanged(Location location) {
onlyOneLocation = location;
locationManager.removeUpdates(this);
}
@Override public void onStatusChanged(String provider, int status, Bundle extras) { }
@Override public void onProviderEnabled(String provider) { }
@Override public void onProviderDisabled(String provider) { }
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_FINE_LOCATION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d("gps", "Location permission granted");
try {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates("gps", 0, 0, this);
}
catch (SecurityException ex) {
Log.d("gps", "Location permission did not work!");
}
}
break;
}
}
// Get LocationManager object
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// Create a criteria object to retrieve provider
Criteria criteria = new Criteria();
// Get the name of the best provider
String provider = locationManager.getBestProvider(criteria, true);
// Get Current Location
Location myLocation = locationManager.getLastKnownLocation(provider);
//latitude of location
double myLatitude = myLocation.getLatitude();
//longitude og location
double myLongitude = myLocation.getLongitude();
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;
}
Ce que vous voulez faire est réalisé en utilisant le LocationManager#requestSingleUpdate
. Cette méthode attache un écouteur dans un boucleur donné (si vous le souhaitez ou le possédez) et notifie l'emplacement une fois qu'il est reçu, une seule fois. La méthode que vous suggérez n’est utilisée que comme une position inexacte avant que la vraie ne vous soit donnée.
Dans tous les cas, ce sera plus rapide que quelques millisecondes (à moins que vous n'ayez la chance de commencer à écouter lorsqu'un emplacement est arrivé sur l'appareil). Pensez au GPS comme un élément que vous activez lorsque vous attendez des emplacements et que vous désactivez lorsque vous supprimez cette écoute. Ce comportement est fait pour éviter de vider la batterie de l'utilisateur.
Pour résumer:
Toutes les réponses ci-dessus ne fonctionnent pas pour moi, alors j'ai répondu à cette question. Initialement, ajoutez les dépendances.
<uses-permission Android:name="Android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" />
<uses-feature Android:name="Android.hardware.location.gps" />
après avoir ajouté la classe MyLocationListiner.Java
package com.example.firebase_auth;
/**
* Created by Chromicle(Ajay Prabhakar).
*/
import Android.content.Context;
import Android.content.pm.PackageManager;
import Android.location.Location;
import Android.location.LocationListener;
import Android.location.LocationManager;
import Android.os.Build;
import Android.os.Bundle;
import Android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import static Android.content.Context.LOCATION_SERVICE;
public class MyLocationListener implements LocationListener {
public static double latitude;
Context ctx;
Location location;
LocationManager locationManager;
boolean isGPSEnabled = false;
boolean isNetworkEnabled = false;
public static double longitude;
MyLocationListener(Context ctx) {
this.ctx = ctx;
try {
locationManager = (LocationManager) ctx.getSystemService(LOCATION_SERVICE);
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
Toast.makeText(ctx, "GPS Enable " + isGPSEnabled, Toast.LENGTH_LONG).show();
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
Toast.makeText(ctx, "Network Enable " + isNetworkEnabled, Toast.LENGTH_LONG).show();
if ( Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission
( ctx, Android.Manifest.permission.ACCESS_FINE_LOCATION )
!= PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission( ctx,
Android.Manifest.permission.ACCESS_COARSE_LOCATION) !=
PackageManager.PERMISSION_GRANTED) { }
if (isGPSEnabled == true) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 0, 0, this);
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
if (isNetworkEnabled==true) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0, this);
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
latitude = location.getLatitude();
longitude = location.getLongitude();
// Toast.makeText(ctx,"latitude: "+latitude+" longitude: "+longitude,Toast.LENGTH_LONG).show();
}
catch(Exception ex)
{
Toast.makeText(ctx,"Exception "+ex, Toast.LENGTH_LONG).show();
}
}
@Nullable
@Override
public void onLocationChanged(Location loc)
{
loc.getLatitude();
loc.getLongitude();
latitude=loc.getLatitude();
longitude=loc.getLongitude();
}
@Override
public void onProviderDisabled(String provider)
{
//print "Currently GPS is Disabled";
}
@Override
public void onProviderEnabled(String provider)
{
//print "GPS got Enabled";
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
Pour utiliser cette classe ajouter cet emplacement de méthode est stocké dans la chaîne d'adresse
public void getLocation(){
Double latitude = 0.0, longitude;
String message = "";
LocationManager mlocManager = null;
LocationListener mlocListener;
mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener(this);
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;
}
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
if (mlocManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
latitude = MyLocationListener.latitude;
longitude = MyLocationListener.longitude;
message = message +"https://www.google.com/maps/dir/@"+ latitude +","+ longitude;
address=message;
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
if (latitude == 0.0) {
Toast.makeText(getApplicationContext(), "Currently gps has not found your location....", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getApplicationContext(), "GPS is currently off...", Toast.LENGTH_LONG).show();
}
}
J'espère que ça vous sera utile