Ich habe diesen GPS-Tracker verwendet, der von Android API 21 bis 30 ziemlich gut funktioniert:
- Es funktioniert auch, wenn das Netzwerk deaktiviert und GPS aktiviert ist.
- Funktioniert auch, wenn beide aktiviert sind :)
- Fordert den Benutzer auf, GPS zu aktivieren, falls es nicht aktiviert ist, und führt ihn zu den GPS-Einstellungen
- Ruft die Standortaktualisierungen bei Standortwechsel ab
- Kann die Adresse aus Längen- und Breitengraden ermitteln
- Gibt dem Netzbetreiber Vorrang und verbraucht weniger Akku
- Sie können die Standortaktualisierung jederzeit stoppen.
Einfuhren:
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import java.util.List;
import java.util.Objects;
Hier ist die Klasse GPSTracker:
public class GPSTracker extends Service implements LocationListener,
OnClickListener {
private final Context mContext;
private Location location = null;
protected LocationManager locationManager;
private double latitude;
private double longitude;
private boolean isGPSEnabled = false;
private boolean canGetLocation = false;
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
private static final long MIN_TIME_BW_UPDATES = 1000 * 60; // 1 minute
private final String TAG = "GPSTracker";
public GPSTracker(Context context) {
mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (isGPSEnabled || isNetworkEnabled) {
this.canGetLocation = true;
// if Network enabled lat/long using Network Provider
if (isNetworkEnabled) {
Log.d(TAG, "Network Provider");
if (locationManager != null) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
} else { // if GPS Enabled get lat/long using GPS Services
Log.d(TAG, "GPS Provider");
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
} else {
showSettingsAlert(this, this);
}
} catch (SecurityException e) {
e.printStackTrace();
}
return location;
}
@Override
public void onLocationChanged(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
Log.d(TAG, "Location changed: latitude: " + latitude + " , longitude: " + longitude);
}
@Override
public void onProviderDisabled(String provider) {
Log.d(TAG, "onProviderDisabled called");
}
@Override
public void onProviderEnabled(String provider) {
Log.d(TAG, "onProviderEnabled called");
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
/**
* Function to get latitude
*/
public double getLatitude() {
if (location != null) {
latitude = location.getLatitude();
}
return latitude;
}
/**
* Function to get longitude
*/
public double getLongitude() {
if (location != null) {
longitude = location.getLongitude();
}
return longitude;
}
/**
* Function to check if best network provider
*
* @return boolean
*/
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog
*/
public AlertDialog showSettingsAlert(
OnClickListener _positiveButtonClickListener,
OnClickListener _negativeButtonClickListener) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialogBuilder.setTitle("GPS settings");
// Setting Dialog Message
alertDialogBuilder.setMessage("Please enable GPS to proceed.");
// On pressing Settings button
alertDialogBuilder.setPositiveButton("Settings",
_positiveButtonClickListener);
// on pressing cancel button
alertDialogBuilder.setNegativeButton("Cancel", _negativeButtonClickListener);
alertDialogBuilder.setCancelable(false);
AlertDialog alertDialog = alertDialogBuilder.create();
// Showing Alert Message
alertDialogBuilder.show();
return alertDialog;
}
/**
* Function to show settings alert dialog
*/
public AlertDialog showGPSOffSettingsAlert(
OnClickListener _positiveButtonClickListener,
OnClickListener _negativeButtonClickListener) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialogBuilder.setTitle("GPS settings");
// Setting Dialog Message
alertDialogBuilder.setMessage("Do you want to turn off GPS?");
// On pressing Settings button
alertDialogBuilder.setPositiveButton("Settings", _positiveButtonClickListener);
// on pressing cancel button
alertDialogBuilder.setNegativeButton("Cancel", _negativeButtonClickListener);
alertDialogBuilder.setCancelable(false);
AlertDialog alertDialog = alertDialogBuilder.create();
// Showing Alert Message
alertDialogBuilder.show();
return alertDialog;
}
/**
* Stop using GPS listener Calling this function will stop using GPS in your
* app
*/
public void stopUsingGPS() {
if (locationManager != null) {
locationManager.removeUpdates(GPSTracker.this);
}
}
public boolean isGPSEnabled() {
return isGPSEnabled;
}
public boolean isGooglePlayServicesAvailable() {
GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
int status = googleApiAvailability.isGooglePlayServicesAvailable(mContext);
if (status != ConnectionResult.SUCCESS) {
if (googleApiAvailability.isUserResolvableError(status)) {
Objects.requireNonNull(googleApiAvailability.getErrorDialog((Activity) mContext, status, 2404)).show();
}
return false;
}
return true;
}
public Address getAddress(double latitude, double longitude) {
boolean networkAvailable = AppUtils.INSTANCE.isNetworkAvailable(mContext);
Address address = new Address();
if (!networkAvailable) {
return address;
}
Geocoder geocoder = new Geocoder(mContext);
try {
List<android.location.Address> fromLocation = geocoder.getFromLocation(latitude, longitude, 1);
if (fromLocation != null && !fromLocation.isEmpty()) {
android.location.Address geoAddress = fromLocation.get(0);
address.setAddress(geoAddress.getAddressLine(0));
address.setCity(geoAddress.getLocality());
address.setCountry(geoAddress.getCountryName());
address.setPostalCode(geoAddress.getPostalCode());
address.setKnownName(geoAddress.getFeatureName());
address.setState(geoAddress.getAdminArea());
address.setCountryCode(geoAddress.getCountryCode());
address.setArea(geoAddress.getSubLocality());
}
} catch (Exception e) {
e.printStackTrace();
}
return address;
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == dialog.BUTTON_POSITIVE) {
mContext.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
dialog.dismiss();
}
}
Ermitteln Sie den Standort aus Ihrer Aktivität wie:
private fun getLocationInfo() {
val gpsTracker = GPSTracker(this)
if (gpsTracker.canGetLocation() && gpsTracker.isGooglePlayServicesAvailable) {
val latitude = gpsTracker.latitude
val longitude = gpsTracker.longitude
val address = gpsTracker.getAddress(latitude, longitude)
FileLogUtil(this).logInfo(
"GPSTracker",
"Latitude: $latitude , Longitude: $longitude , Address: ${address.address}"
)
}
}
Adressklasse:
public class Address {
private String address;
private String city;
private String state;
private String country;
private String postalCode;
private String knownName;
private String countryCode;
private String area;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getKnownName() {
return knownName;
}
public void setKnownName(String knownName) {
this.knownName = knownName;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
}
Überprüfen Sie den Netzbetreiber wie folgt:
fun isNetworkAvailable(context: Context): Boolean {
val connectivityManager =
context.getSystemService(AppCompatActivity.CONNECTIVITY_SERVICE) as ConnectivityManager
val activeNetworkInfo = connectivityManager.activeNetworkInfo
return activeNetworkInfo != null && activeNetworkInfo.isConnected
}
Vergessen Sie nicht, diese Berechtigungen im Manifest hinzuzufügen:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Wir können dies nutzen, um die erforderlichen Genehmigungen einzuholen:
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import java.util.*
class PermissionUtils(var activity: Activity) {
private var permissionsList = arrayListOf<String>()
companion object {
const val REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124
const val REQUEST_CALL_PERMISSION = 4
fun isPermissionGranted(context: Context, permission: String): Boolean {
val res = context.checkCallingOrSelfPermission(permission)
return res == PackageManager.PERMISSION_GRANTED
}
}
fun requestForAllMandatoryPermissions() {
permissionsList = ArrayList<String>()
//addPermissionIfNotGranted(Manifest.permission.CAMERA)
//addPermissionIfNotGranted(Manifest.permission.CALL_PHONE)
addPermissionIfNotGranted(Manifest.permission.ACCESS_FINE_LOCATION)
addPermissionIfNotGranted(Manifest.permission.ACCESS_COARSE_LOCATION)
//addPermissionIfNotGranted(Manifest.permission.READ_PHONE_STATE)
//addPermissionIfNotGranted(Manifest.permission.READ_EXTERNAL_STORAGE)
//addPermissionIfNotGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)
if (permissionsList.isNotEmpty()) {
ActivityCompat.requestPermissions(
activity,
permissionsList.toTypedArray(),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS
)
}
}
private fun addPermissionIfNotGranted(permission: String) {
if (ContextCompat.checkSelfPermission(activity, permission) !=
PackageManager.PERMISSION_GRANTED
) {
permissionsList.add(permission)
ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)
}
}
}
Rufen Sie die Berechtigungen aus Ihrer Aktivität auf:
if (Build.VERSION.SDK_INT >= 23) {
try {
val permissionUtils = PermissionUtils(this)
permissionUtils.requestForAllMandatoryPermissions()
} catch (e: Exception) {
e.printStackTrace()
}
}
1 Stimmen
Sie könnten eine einfache Bibliothek verwenden, die all die Dinge abstrahiert, die "unter der Haube" passieren müssen: github.com/delight-im/Android-SimpleLocation
0 Stimmen
Hier finden Sie die Antwort in Kotlin: stackoverflow.com/a/53800632/2201814
0 Stimmen
Sie können in Android verschmolzene Techniken zur Standorterfassung verwenden.
0 Stimmen
FusedLocation funktioniert gut (ich weiß allerdings immer noch nicht, warum getCurrentLocation() veraltet sein musste).