I need to get my current location using GPS programmatically. How can i achieve it?
我需要以编程方式使用GPS获取当前位置。我怎样才能实现它?
22 个解决方案
#1
I have created a small application with step by step description to get current location's GPS coordinates.
我创建了一个小型应用程序,逐步描述获取当前位置的GPS坐标。
Complete example source code is in Get Current Location coordinates , City name - in Android.
完整的示例源代码位于获取当前位置坐标,城市名称 - 在Android中。
See how it works:
看看它怎么运作:
-
All we need to do is add this permission in the manifest file:
我们需要做的就是在清单文件中添加此权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-
And create a LocationManager instance like this:
并创建一个这样的LocationManager实例:
LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
-
Check if GPS is enabled or not.
检查GPS是否启用。
-
And then implement LocationListener and get coordinates:
然后实现LocationListener并获取坐标:
LocationListener locationListener = new MyLocationListener();locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
-
Here is the sample code to do so
以下是执行此操作的示例代码
/*---------- Listener class to get coordinates ------------- */private class MyLocationListener implements LocationListener { @Override public void onLocationChanged(Location loc) { editLocation.setText(""); pb.setVisibility(View.INVISIBLE); Toast.makeText( getBaseContext(), "Location changed: Lat: " + loc.getLatitude() + " Lng: " + loc.getLongitude(), Toast.LENGTH_SHORT).show(); String longitude = "Longitude: " + loc.getLongitude(); Log.v(TAG, longitude); String latitude = "Latitude: " + loc.getLatitude(); Log.v(TAG, latitude); /*------- To get city name from coordinates -------- */ String cityName = null; Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault()); List<Address> addresses; try { addresses = gcd.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1); if (addresses.size() > 0) { System.out.println(addresses.get(0).getLocality()); cityName = addresses.get(0).getLocality(); } } catch (IOException e) { e.printStackTrace(); } String s = longitude + "\n" + latitude + "\n\nMy Current City is: " + cityName; editLocation.setText(s); } @Override public void onProviderDisabled(String provider) {} @Override public void onProviderEnabled(String provider) {} @Override public void onStatusChanged(String provider, int status, Bundle extras) {}}
#2
Here is additional information for other answers.
以下是其他答案的其他信息。
Since Android has
自Android以来
GPS_PROVIDER and NETWORK_PROVIDER
you can register to both and start fetch events from onLocationChanged(Location location)
from two at the same time. So far so good. Now the question do we need two results or we should take the best. As I know GPS_PROVIDER
results have better accuracy than NETWORK_PROVIDER
.
您可以注册两者并同时从两个开始从onLocationChanged(位置位置)获取事件。到现在为止还挺好。现在问题是我们需要两个结果,还是我们应该采取最好的结果。据我所知,GPS_PROVIDER结果的准确度要高于NETWORK_PROVIDER。
Let's define Location
field:
让我们定义位置字段:
private Location currentBestLocation = null;
Before we start listen on Location change we will implement the following method. This method returns the last known location, between the GPS and the network one. For this method newer is best.
在我们开始听取位置更改之前,我们将实现以下方法。该方法返回GPS和网络之间的最后已知位置。对于这种方法,新方法最好。
/** * @return the last know best location */private Location getLastBestLocation() { Location locationGPS = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); Location locationNet = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); long GPSLocationTime = 0; if (null != locationGPS) { GPSLocationTime = locationGPS.getTime(); } long NetLocationTime = 0; if (null != locationNet) { NetLocationTime = locationNet.getTime(); } if ( 0 < GPSLocationTime - NetLocationTime ) { return locationGPS; } else { return locationNet; }}
Each time when we retrieve a new location we will compare it with our previous result.
每当我们检索新位置时,我们都会将其与之前的结果进行比较。
...static final int TWO_MINUTES = 1000 * 60 * 2;...
I add a new method to onLocationChanged
:
我在onLocationChanged中添加了一个新方法:
@Overridepublic void onLocationChanged(Location location) { makeUseOfNewLocation(location); if(currentBestLocation == null){ currentBestLocation = location; } ....}/** * This method modify the last know good location according to the arguments. * * @param location The possible new location. */void makeUseOfNewLocation(Location location) { if ( isBetterLocation(location, currentBestLocation) ) { currentBestLocation = location; }}..../** Determines whether one location reading is better than the current location fix * @param location The new location that you want to evaluate * @param currentBestLocation The current location fix, to which you want to compare the new one. */protected boolean isBetterLocation(Location location, Location currentBestLocation) { if (currentBestLocation == null) { // A new location is always better than no location return true; } // Check whether the new location fix is newer or older long timeDelta = location.getTime() - currentBestLocation.getTime(); boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; boolean isNewer = timeDelta > 0; // If it's been more than two minutes since the current location, use the new location, // because the user has likely moved. if (isSignificantlyNewer) { return true; // If the new location is more than two minutes older, it must be worse. } else if (isSignificantlyOlder) { return false; } // Check whether the new location fix is more or less accurate int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); boolean isLessAccurate = accuracyDelta > 0; boolean isMoreAccurate = accuracyDelta < 0; boolean isSignificantlyLessAccurate = accuracyDelta > 200; // Check if the old and new location are from the same provider boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider()); // Determine location quality using a combination of timeliness and accuracy if (isMoreAccurate) { return true; } else if (isNewer && !isLessAccurate) { return true; } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { return true; } return false;}// Checks whether two providers are the sameprivate boolean isSameProvider(String provider1, String provider2) { if (provider1 == null) { return provider2 == null; } return provider1.equals(provider2);}....
#3
You can find the location either by GPS_PROVIDER or NETWORK_PROVIDER
.
您可以通过GPS_PROVIDER或NETWORK_PROVIDER找到该位置。
Overview of location services in Android.
Android中的位置服务概述。
Here is one example which try to find the location using GPS. If your GPS is not available then try to use network for find the location.
以下是尝试使用GPS查找位置的一个示例。如果您的GPS不可用,请尝试使用网络查找位置。
GPSTracker.java
public class GPSTracker extends Service implements LocationListener { private final Context mContext; // Flag for GPS status boolean isGPSEnabled = false; // Flag for network status boolean isNetworkEnabled = false; // Flag for GPS status boolean canGetLocation = false; Location location; // Location double latitude; // Latitude double longitude; // Longitude // The minimum distance to change Updates in meters private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters // The minimum time between updates in milliseconds private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute // Declaring a Location Manager protected LocationManager locationManager; public GPSTracker(Context context) { this.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 isNetworkEnabled = locationManager .isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (!isGPSEnabled && !isNetworkEnabled) { // No network provider is enabled } else { this.canGetLocation = true; if (isNetworkEnabled) { locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("Network", "Network"); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } // If GPS enabled, get latitude/longitude using GPS Services if (isGPSEnabled) { if (location == null) { locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("GPS Enabled", "GPS Enabled"); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.GPS_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } } } } catch (Exception e) { e.printStackTrace(); } return location; } /** * Stop using GPS listener * Calling this function will stop using GPS in your app. * */ public void stopUsingGPS(){ if(locationManager != null){ locationManager.removeUpdates(GPSTracker.this); } } /** * Function to get latitude * */ public double getLatitude(){ if(location != null){ latitude = location.getLatitude(); } // return latitude return latitude; } /** * Function to get longitude * */ public double getLongitude(){ if(location != null){ longitude = location.getLongitude(); } // return longitude return longitude; } /** * Function to check GPS/Wi-Fi enabled * @return boolean * */ public boolean canGetLocation() { return this.canGetLocation; } /** * Function to show settings alert dialog. * On pressing the Settings button it will launch Settings Options. * */ public void showSettingsAlert(){ AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext); // Setting Dialog Title alertDialog.setTitle("GPS is settings"); // Setting Dialog Message alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?"); // On pressing the Settings button. alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog,int which) { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); mContext.startActivity(intent); } }); // On pressing the cancel button alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); // Showing Alert Message alertDialog.show(); } @Override public void onLocationChanged(Location location) { } @Override public void onProviderDisabled(String provider) { } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public IBinder onBind(Intent arg0) { return null; }}
Activity -AndroidGPSTrackingActivity.java
public class AndroidGPSTrackingActivity extends Activity { Button btnShowLocation; // GPSTracker class GPSTracker gps; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnShowLocation = (Button) findViewById(R.id.btnShowLocation); // Show location button click event btnShowLocation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // Create class object gps = new GPSTracker(AndroidGPSTrackingActivity.this); // Check if GPS enabled if(gps.canGetLocation()) { double latitude = gps.getLatitude(); double longitude = gps.getLongitude(); // \n is for new line Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show(); } else { // Can't get location. // GPS or network is not enabled. // Ask user to enable GPS/network in settings. gps.showSettingsAlert(); } } }); }}
Layout- main.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/btnShowLocation" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Show Location" android:layout_centerVertical="true" android:layout_centerHorizontal="true"/></RelativeLayout>
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.INTERNET" />
#4
There are already many answers there but I want to show latest way to get location using Google API, so new programmers can use new method:
那里已经有很多答案,但我想展示使用Google API获取位置的最新方式,因此新程序员可以使用新方法:
I have written detailed tutorial on current location in android at my blog demonuts.com You can also find full source code developed with android studio.
我在我的博客demonuts.com上写了关于android当前位置的详细教程。你也可以找到用android studio开发的完整源代码。
First of all, put this in gradle file
首先,将它放在gradle文件中
compile 'com.google.android.gms:play-services:9.0.2'
then implement necessary interfaces
然后实现必要的接口
public class MainActivity extends BaseActivitiy implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener
declare instances
private GoogleApiClient mGoogleApiClient; private Location mLocation; private LocationManager locationManager; private LocationRequest mLocationRequest;
put this in onCreate()
把它放在onCreate()
mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
At last, override necessary methods
最后,重写必要的方法
@Override public void onConnected(Bundle bundle) { 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; } startLocationUpdates(); mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); if(mLocation == null){ startLocationUpdates(); } if (mLocation != null) { double latitude = mLocation.getLatitude(); double longitude = mLocation.getLongitude(); } else { // Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show(); } } protected void startLocationUpdates() { // Create the location request mLocationRequest = LocationRequest.create() .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) .setInterval(UPDATE_INTERVAL) .setFastestInterval(FASTEST_INTERVAL); // Request location updates 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; } LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); Log.d("reque", "--->>>>"); } @Override public void onConnectionSuspended(int i) { Log.i(TAG, "Connection Suspended"); mGoogleApiClient.connect(); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode()); } @Override public void onStart() { super.onStart(); mGoogleApiClient.connect(); } @Override public void onStop() { super.onStop(); if (mGoogleApiClient.isConnected()) { mGoogleApiClient.disconnect(); } } @Override public void onLocationChanged(Location location) { }
Don't forget to start GPS in your device before running app.
在运行应用程序之前,请不要忘记在设备中启动GPS。
#5
Since I didn't like some of the code in the other answers, here's my simple solution. This solution is meant to be usable in an Activity or Service to track the location. It makes sure that it never returns data that's too stale unless you explicitly request stale data. It can be run in either a callback mode to get updates as we receive them, or in poll mode to poll for the most recent info.
由于我不喜欢其他答案中的一些代码,这是我的简单解决方案。此解决方案旨在可用于活动或服务以跟踪位置。除非您明确请求陈旧数据,否则它确保它永远不会返回太陈旧的数据。它可以在回调模式下运行以在我们收到更新时获得更新,也可以在轮询模式下轮询以查询最新信息。
Generic LocationTracker interface. Allows us to have multiple types of location trackers and plug the appropriate one in easily:
通用LocationTracker接口。允许我们拥有多种类型的位置跟踪器并轻松插入相应的位置跟踪器:
package com.gabesechan.android.reusable.location;import android.location.Location;public interface LocationTracker { public interface LocationUpdateListener{ public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime); } public void start(); public void start(LocationUpdateListener update); public void stop(); public boolean hasLocation(); public boolean hasPossiblyStaleLocation(); public Location getLocation(); public Location getPossiblyStaleLocation();}
ProviderLocationTracker- this class will track the location for either GPS or NETWORK.
ProviderLocationTracker-此类将跟踪GPS或NETWORK的位置。
package com.gabesechan.android.reusable.location;import android.content.Context;import android.location.Location;import android.location.LocationListener;import android.location.LocationManager;import android.os.Bundle;public class ProviderLocationTracker implements LocationListener, LocationTracker { // The minimum distance to change Updates in meters private static final long MIN_UPDATE_DISTANCE = 10; // The minimum time between updates in milliseconds private static final long MIN_UPDATE_TIME = 1000 * 60; private LocationManager lm; public enum ProviderType{ NETWORK, GPS }; private String provider; private Location lastLocation; private long lastTime; private boolean isRunning; private LocationUpdateListener listener; public ProviderLocationTracker(Context context, ProviderType type) { lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); if(type == ProviderType.NETWORK){ provider = LocationManager.NETWORK_PROVIDER; } else{ provider = LocationManager.GPS_PROVIDER; } } public void start(){ if(isRunning){ //Already running, do nothing return; } //The provider is on, so start getting updates. Update current location isRunning = true; lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE, this); lastLocation = null; lastTime = 0; return; } public void start(LocationUpdateListener update) { start(); listener = update; } public void stop(){ if(isRunning){ lm.removeUpdates(this); isRunning = false; listener = null; } } public boolean hasLocation(){ if(lastLocation == null){ return false; } if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){ return false; //stale } return true; } public boolean hasPossiblyStaleLocation(){ if(lastLocation != null){ return true; } return lm.getLastKnownLocation(provider)!= null; } public Location getLocation(){ if(lastLocation == null){ return null; } if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){ return null; //stale } return lastLocation; } public Location getPossiblyStaleLocation(){ if(lastLocation != null){ return lastLocation; } return lm.getLastKnownLocation(provider); } public void onLocationChanged(Location newLoc) { long now = System.currentTimeMillis(); if(listener != null){ listener.onUpdate(lastLocation, lastTime, newLoc, now); } lastLocation = newLoc; lastTime = now; } public void onProviderDisabled(String arg0) { } public void onProviderEnabled(String arg0) { } public void onStatusChanged(String arg0, int arg1, Bundle arg2) { }}
The is the FallbackLocationTracker, which will track by both GPS and NETWORK, and use whatever location is more accurate.
这是FallbackLocationTracker,它将通过GPS和NETWORK进行跟踪,并使用任何更准确的位置。
package com.gabesechan.android.reusable.location;import android.content.Context;import android.location.Location;import android.location.LocationManager;public class FallbackLocationTracker implements LocationTracker, LocationTracker.LocationUpdateListener { private boolean isRunning; private ProviderLocationTracker gps; private ProviderLocationTracker net; private LocationUpdateListener listener; Location lastLoc; long lastTime; public FallbackLocationTracker(Context context) { gps = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.GPS); net = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.NETWORK); } public void start(){ if(isRunning){ //Already running, do nothing return; } //Start both gps.start(this); net.start(this); isRunning = true; } public void start(LocationUpdateListener update) { start(); listener = update; } public void stop(){ if(isRunning){ gps.stop(); net.stop(); isRunning = false; listener = null; } } public boolean hasLocation(){ //If either has a location, use it return gps.hasLocation() || net.hasLocation(); } public boolean hasPossiblyStaleLocation(){ //If either has a location, use it return gps.hasPossiblyStaleLocation() || net.hasPossiblyStaleLocation(); } public Location getLocation(){ Location ret = gps.getLocation(); if(ret == null){ ret = net.getLocation(); } return ret; } public Location getPossiblyStaleLocation(){ Location ret = gps.getPossiblyStaleLocation(); if(ret == null){ ret = net.getPossiblyStaleLocation(); } return ret; } public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime) { boolean update = false; //We should update only if there is no last location, the provider is the same, or the provider is more accurate, or the old location is stale if(lastLoc == null){ update = true; } else if(lastLoc != null && lastLoc.getProvider().equals(newLoc.getProvider())){ update = true; } else if(newLoc.getProvider().equals(LocationManager.GPS_PROVIDER)){ update = true; } else if (newTime - lastTime > 5 * 60 * 1000){ update = true; } if(update){ if(listener != null){ listener.onUpdate(lastLoc, lastTime, newLoc, newTime); } lastLoc = newLoc; lastTime = newTime; } }}
Since both implement the LocationTracker interface, you can easily change your mind about which one to use. To run the class in poll mode, just call start(). To run it in update mode, call start(Listener).
由于两者都实现了LocationTracker接口,因此您可以轻松改变您对使用哪个接口的想法。要在轮询模式下运行类,只需调用start()。要在更新模式下运行它,请调用start(Listener)。
Also take a look at my blog post on the code
另请查看关于代码的博客文章
#6
Get location of gps by -
获取gps的位置 -
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);LocationListener locationListener = new LocationListener() { @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onLocationChanged(Location location) { // TODO Auto-generated method stub double latitude = location.getLatitude(); double longitude = location.getLongitude(); double speed = location.getSpeed(); //spedd in meter/minute speed = (speed*3600)/1000; // speed in km/minute Toast.makeText(GraphViews.this, "Current speed:" + location.getSpeed(),Toast.LENGTH_SHORT).show(); } }; locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);}
#7
You need to use latest/newest
你需要使用最新/最新
GoogleApiClient Api
Basically what you need to do is:
基本上你需要做的是:
private GoogleApiClient mGoogleApiClient;mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build();
Then
@Override public void onConnected(Bundle connectionHint) { mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mLastLocation != null) { mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude())); mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude())); } }
for the most accurate and reliable location. See my post here:
为了最准确和可靠的位置。在这里看我的帖子:
https://*.com/a/33599228/2644905
Do not use LocationListener which is not accurate and has delayed response. To be honest this is easier to implement.Also read documentation: https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient
不要使用不准确且响应延迟的LocationListener。说实话,这更容易实现。另外阅读文档:https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient
#8
class MyLocation { Timer timer1; LocationManager lm; LocationResult locationResult; boolean gps_enabled = false; boolean network_enabled = false; 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 the 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(), 5000); 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 { @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); }}
I hope this will help you...
我希望这能帮到您...
#9
Now that Google Play locations services are here, I recommend that developers start using the new fused location provider. You will find it easier to use and more accurate. Please watch the Google I/O video Beyond the Blue Dot: New Features in Android Location by the two guys who created the new Google Play location services API.
既然Google Play位置服务已经存在,我建议开发人员开始使用新的融合位置提供商。您会发现它更容易使用且更准确。请观看创建新Google Play位置服务API的两个人观看Google I / O视频超越蓝点:Android位置的新功能。
I've been working with location APIs on a number of mobile platforms, and I think what these two guys have done is really revolutionary. It's gotten rid of a huge amount of the complexities of using the various providers. Stack Overflow is littered with questions about which provider to use, whether to use last known location, how to set other properties on the LocationManager, etc. This new API that they have built removes most of those uncertainties and makes the location services a pleasure to use.
我一直在许多移动平台上使用位置API,我认为这两个人所做的真的是革命性的。它摆脱了使用各种提供商的大量复杂性。 Stack Overflow充斥着关于使用哪个提供商,是否使用最后已知位置,如何在LocationManager上设置其他属性等问题。他们构建的这个新API消除了大部分不确定性并使位置服务成为愉快的选择。使用。
I've written an Android app that periodically gets the location using Google Play location services and sends the location to a web server where it is stored in a database and can be viewed on Google Maps. I've written both the client software (for Android, iOS, Windows Phone and Java ME) and the server software (for ASP.NET and SQL Server or PHP and MySQL). The software is written in the native language on each platform and works properly in the background on each. Lastly, the software has the MIT License. You can find the Android client here:
我编写了一个Android应用程序,定期使用Google Play位置服务获取该位置,并将该位置发送到Web服务器,并将其存储在数据库中,并可在Google地图上查看。我已经编写了客户端软件(适用于Android,iOS,Windows Phone和Java ME)和服务器软件(适用于ASP.NET和SQL Server或PHP和MySQL)。该软件在每个平台上都以母语编写,并在每个平台的后台正常工作。最后,该软件具有MIT许可证。您可以在此处找到Android客户端:
https://github.com/nickfox/GpsTracker/tree/master/phoneClients/android
#10
LocationManager is a class that provides in-build methods to get last know location
LocationManager是一个提供构建方法以获取最后知道位置的类
STEP 1 :Create a LocationManager Object as below
第1步:创建一个LocationManager对象,如下所示
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
LocationManager locationManager =(LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
STEP 2 : Add Criteria
第2步:添加标准
*Criteria is use for setting accuracy*Criteria criteria = new Criteria();int currentapiVersion = android.os.Build.VERSION.SDK_INT;if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) { criteria.setSpeedAccuracy(Criteria.ACCURACY_HIGH); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(true); criteria.setBearingRequired(true); criteria.setSpeedRequired(true);}
STEP 3 :GET Avaliable Provider
第3步:获得Avaliable Provider
Threre are two types of provider GPS and network
Threre是提供商GPS和网络的两种类型
String provider = locationManager.getBestProvider(criteria, true);
STEP 4: Get Last Know Location
第4步:获取最后知道的位置
Location location = locationManager.getLastKnownLocation(provider);
STEP 5: Get Latitude and Longitude
第5步:获取纬度和经度
If location object is null then dont try to call below methods
如果location对象为null,则不要尝试调用以下方法
getLatitude and getLongitude is methods which returns double values
getLatitude和getLongitude是返回double值的方法
#11
Simplest you can find
最简单的你可以找到
package com.javapapers.android.geolocationfinder; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.widget.TextView; import android.util.Log; public class MainActivity extends Activity implements LocationListener{ protected LocationManager locationManager; protected LocationListener locationListener; protected Context context; TextView txtLat; String lat; String provider; protected String latitude,longitude; protected boolean gps_enabled,network_enabled; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); txtLat = (TextView) findViewById(R.id.textview1); locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); } @Override public void onLocationChanged(Location location) { txtLat = (TextView) findViewById(R.id.textview1); txtLat.setText("Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude()); } @Override public void onProviderDisabled(String provider) { Log.d("Latitude","disable"); } @Override public void onProviderEnabled(String provider) { Log.d("Latitude","enable"); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { Log.d("Latitude","status"); } }
#12
Getting location updates requires lots of bolierplate code in Android, You need to take care of
获取位置更新需要在Android中使用大量的bolierplate代码,您需要注意
- Google Play services availablity Check,
- Update Google play Service if it is old or not available
- Dialog Creation of GoogleApiClient and its callbacks connected,disconnected etc.
- Stopping and releasing resources for location updates
- Handling Location permission scenarios
- Checking Location services are On or Off
- Getting lastknown location is not so easy either
- Fallback to last known location if not getting location after certain duration
Google Play服务可用性检查,
如果旧版或不可用,请更新Google Play服务
对话创建GoogleApiClient及其回调连接,断开连接等。
停止和释放资源以进行位置更新
处理位置权限方案
检查位置服务是开还是关
获取最后的位置也不是那么容易
如果在一定时间后没有获得位置,则回退到最后已知位置
To ease out all these steps i have created Android-EasyLocation (small android library) which will take care all this stuff and you can focus on business logic.
为了简化所有这些步骤,我创建了Android-EasyLocation(小型android库),它将关注所有这些内容,您可以专注于业务逻辑。
All you need is extend EasyLocationActivity and this
您只需要扩展EasyLocationActivity和它
requestSingleLocationFix(easyLocationRequest);
or
requestLocationUpdates(easyLocationRequest);
Checkout sample app and steps needed here at https://github.com/akhgupta/Android-EasyLocation
通过https://github.com/akhgupta/Android-EasyLocation查看示例应用程序和步骤
#13
I have made a project from which we can get the accurate location using Google Play Services, GPS and Network providers. This project can be found here.
我制作了一个项目,通过Google Play服务,GPS和网络提供商,我们可以从中获得准确的位置。这个项目可以在这里找到。
Strategy in finding the best location is that first get the location from google play services if location is found then check weather it is better or not, if location found is null restart google play services and try to fetch the location from Android Location API. Register the location on change listeners and when ever the better location is found the call back returns it to the main activity.
找到最佳位置的策略是首先从谷歌播放服务获取位置,如果找到位置然后检查天气是否更好,如果找到的位置是null重新启动谷歌播放服务并尝试从Android位置API获取位置。在更改侦听器上注册位置,当找到更好的位置时,回叫将其返回到主活动。
It is very simple to use and implement in code only two classes we need to embed i.e. LocationManagerInterface
and SmartLocationManager
, LocationActivity
is implementing the interface and using SmartLocationManager to fetch location.
在代码中使用和实现非常简单,我们需要嵌入两个类,即LocationManagerInterface和SmartLocationManager,LocationActivity正在实现接口并使用SmartLocationManager来获取位置。
/** * Created by Syed Raza Mehdi Naqvi on 8/10/2016. */public interface LocationManagerInterface { String TAG = LocationManagerInterface.class.getSimpleName(); void locationFetched(Location mLocation, Location oldLocation, String time, String locationProvider);}
here is the location manager class
这是位置管理器类
import android.Manifest;import android.app.Activity;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.content.IntentSender;import android.content.pm.PackageManager;import android.location.Location;import android.location.LocationManager;import android.os.Build;import android.os.Bundle;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v7.app.AlertDialog;import android.util.Log;import android.widget.Toast;import com.google.android.gms.common.ConnectionResult;import com.google.android.gms.common.GooglePlayServicesUtil;import com.google.android.gms.common.api.GoogleApiClient;import com.google.android.gms.location.LocationListener;import com.google.android.gms.location.LocationRequest;import com.google.android.gms.location.LocationServices;import java.text.DateFormat;import java.util.Date;/** * Created by Syed Raza Mehdi Naqvi on 8/9/2016. */public class SmartLocationManager implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { private static final String TAG = SmartLocationManager.class.getSimpleName(); private static final int TWO_MINUTES = 1000 * 60 * 2; private static final int PERMISSION_REQUEST_CODE = 1000; private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000; // default value is false but user can change it private String mLastLocationUpdateTime; // fetched location time private String locationProvider; // source of fetched location private Location mLastLocationFetched; // location fetched private Location mLocationFetched; // location fetched private Location networkLocation; private Location gpsLocation; private int mLocationPiority; private long mLocationFetchInterval; private long mFastestLocationFetchInterval; private Context mContext; // application context private Activity mActivity; // activity context private LocationRequest mLocationRequest; private GoogleApiClient mGoogleApiClient; private LocationManagerInterface mLocationManagerInterface; private android.location.LocationManager locationManager; private android.location.LocationListener locationListener; boolean isGPSEnabled; boolean isNetworkEnabled; private int mProviderType; public static final int NETWORK_PROVIDER = 1; public static final int ALL_PROVIDERS = 0; public static final int GPS_PROVIDER = 2;// private final double STANDARD_LOCATION_ACCURACY = 100.0;// private final double STANDARD_LOCATION_SEED_LIMIT = 6.95; public static final int LOCATION_PROVIDER_ALL_RESTICTION = 1; public static final int LOCATION_PROVIDER_RESTRICTION_NONE = 0; public static final int LOCATION_PROVIDER_GPS_ONLY_RESTICTION = 2; public static final int LOCATION_PROVIDER_NETWORK_ONLY_RESTICTION = 3; private int mForceNetworkProviders = 0; public SmartLocationManager(Context context, Activity activity, LocationManagerInterface locationInterface, int providerType, int locationPiority, long locationFetchInterval, long fastestLocationFetchInterval, int forceNetworkProviders) { mContext = context; mActivity = activity; mProviderType = providerType; mLocationPiority = locationPiority; mForceNetworkProviders = forceNetworkProviders; mLocationFetchInterval = locationFetchInterval; mFastestLocationFetchInterval = fastestLocationFetchInterval; mLocationManagerInterface = locationInterface; initSmartLocationManager(); } public void initSmartLocationManager() { // 1) ask for permission for Android 6 above to avoid crash // 2) check if gps is available // 3) get location using awesome strategy askLocationPermission(); // for android version 6 above checkNetworkProviderEnable(mForceNetworkProviders); // if (isGooglePlayServicesAvailable()) // if googleplay services available initLocationObjts(); // init obj for google play service and start fetching location else getLocationUsingAndroidAPI(); // otherwise get location using Android API } private void initLocationObjts() { // Create the LocationRequest object mLocationRequest = LocationRequest.create() .setPriority(mLocationPiority) .setInterval(mLocationFetchInterval) // 10 seconds, in milliseconds .setFastestInterval(mFastestLocationFetchInterval); // 1 second, in milliseconds if (mGoogleApiClient == null) { mGoogleApiClient = new GoogleApiClient.Builder(mActivity) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } startLocationFetching(); // connect google play services to fetch location } @Override public void onConnected(Bundle connectionHint) { Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); startLocationUpdates(); if (location == null) { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); getLocationUsingAndroidAPI(); } else { setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); } } @Override public void onLocationChanged(Location location) { if (location == null) { getLastKnownLocation(); } else { setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); } } @Override public void onConnectionSuspended(int i) { Log.i(TAG, "Connection suspended"); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { if (connectionResult.hasResolution()) { try { connectionResult.startResolutionForResult(mActivity, CONNECTION_FAILURE_RESOLUTION_REQUEST); // Start an Activity that tries to resolve the error getLocationUsingAndroidAPI(); // try to get location using Android API locationManager } catch (IntentSender.SendIntentException e) { e.printStackTrace(); } } else { Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode()); } } private void setNewLocation(Location location, Location oldLocation) { if (location != null) { mLastLocationFetched = oldLocation; mLocationFetched = location; mLastLocationUpdateTime = DateFormat.getTimeInstance().format(new Date()); locationProvider = location.getProvider(); mLocationManagerInterface.locationFetched(location, mLastLocationFetched, mLastLocationUpdateTime, location.getProvider()); } } private void getLocationUsingAndroidAPI() { // Acquire a reference to the system Location Manager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); setLocationListner(); captureLocation(); } public void captureLocation() { if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } try { if (mProviderType == SmartLocationManager.GPS_PROVIDER) { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); } else if (mProviderType == SmartLocationManager.NETWORK_PROVIDER) { locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); } else { locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); } } catch (Exception e) { Log.e(TAG, e.getMessage()); } } private void setLocationListner() { // Define a listener that responds to location updates locationListener = new android.location.LocationListener() { public void onLocationChanged(Location location) { // Called when a new location is found by the network location provider. if (location == null) { getLastKnownLocation(); } else { setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);// if (isLocationAccurate(location) && location.getAccuracy() < STANDARD_LOCATION_ACCURACY && location.getSpeed() < STANDARD_LOCATION_SEED_LIMIT) {// no use of this if// setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);// } else {// setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);// } } } public void onStatusChanged(String provider, int status, Bundle extras) { } public void onProviderEnabled(String provider) { } public void onProviderDisabled(String provider) { } }; } public Location getAccurateLocation() { if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return null; } try { gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); Location newLocalGPS, newLocalNetwork; if (gpsLocation != null || networkLocation != null) { newLocalGPS = getBetterLocation(mLocationFetched, gpsLocation); newLocalNetwork = getBetterLocation(mLocationFetched, networkLocation); setNewLocation(getBetterLocation(newLocalGPS, newLocalNetwork), mLocationFetched); } } catch (Exception ex) { Log.e(TAG, ex.getMessage()); } return mLocationFetched; } protected void startLocationUpdates() { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } public void startLocationFetching() { mGoogleApiClient.connect(); if (mGoogleApiClient.isConnected()) { startLocationUpdates(); } } public void pauseLocationFetching() { if (mGoogleApiClient.isConnected()) { LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); mGoogleApiClient.disconnect(); } } public void abortLocationFetching() { mGoogleApiClient.disconnect(); // Remove the listener you previously added if (locationManager != null && locationListener != null) { if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } try { locationManager.removeUpdates(locationListener); locationManager = null; } catch (Exception ex) { Log.e(TAG, ex.getMessage()); } } } public void resetLocation() { mLocationFetched = null; mLastLocationFetched = null; networkLocation = null; gpsLocation = null; } // Android M Permission check public void askLocationPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) { if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_FINE_LOCATION)) { final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); builder.setMessage("Please allow all permissions in App Settings for additional functionality.") .setCancelable(false) .setPositiveButton("Allow", new DialogInterface.OnClickListener() { public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) { Toast.makeText(mContext, "Welcome", Toast.LENGTH_SHORT).show(); } }) .setNegativeButton("Deny", new DialogInterface.OnClickListener() { public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) { mActivity.finish(); } }); final AlertDialog alert = builder.create(); alert.show(); } else ActivityCompat.requestPermissions(mActivity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION , Manifest.permission.ACCESS_FINE_LOCATION }, PERMISSION_REQUEST_CODE); } } } public void checkNetworkProviderEnable(int enforceActive) { locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (!isGPSEnabled && !isNetworkEnabled) { buildAlertMessageTurnOnLocationProviders("Your location providers seems to be disabled, please enable it", "OK", "Cancel"); } else if (!isGPSEnabled && mForceNetworkProviders == LOCATION_PROVIDER_GPS_ONLY_RESTICTION) { buildAlertMessageTurnOnLocationProviders("Your GPS seems to be disabled, please enable it", "OK", "Cancel"); } else if (!isNetworkEnabled && mForceNetworkProviders == LOCATION_PROVIDER_NETWORK_ONLY_RESTICTION) { buildAlertMessageTurnOnLocationProviders("Your Network location provider seems to be disabled, please enable it", "OK", "Cancel"); } // getting network status if (!isGPSEnabled && !isNetworkEnabled) { Toast.makeText(mContext, "Location can't be fetched!", Toast.LENGTH_SHORT).show(); // show alert mActivity.finish(); } } private void buildAlertMessageTurnOnLocationProviders(String message, String positiveButtonText, String negativeButtonText) { final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); builder.setMessage(message) .setCancelable(false) .setPositiveButton(positiveButtonText, new DialogInterface.OnClickListener() { public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) { Intent mIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(mIntent); } }) .setNegativeButton(negativeButtonText, new DialogInterface.OnClickListener() { public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) { mActivity.finish(); } }); final AlertDialog alert = builder.create(); alert.show(); } public Location getLastKnownLocation() { locationProvider = LocationManager.NETWORK_PROVIDER; Location lastKnownLocation = null; // Or use LocationManager.GPS_PROVIDER if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return lastKnownLocation; } try { lastKnownLocation = locationManager.getLastKnownLocation(locationProvider); return lastKnownLocation; } catch (Exception e) { Log.e(TAG, e.getMessage()); } return lastKnownLocation; } public boolean isGooglePlayServicesAvailable() { int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext); if (status == ConnectionResult.SUCCESS) { return true; } else { return false; } } /** * Determines whether one Location reading is better than the current Location fix * * @param location The new Location that you want to evaluate * @param currentBestLocation The current Location fix, to which you want to compare the new one */ protected Location getBetterLocation(Location location, Location currentBestLocation) { if (currentBestLocation == null) { // A new location is always better than no location return location; } // Check whether the new location fix is newer or older long timeDelta = location.getTime() - currentBestLocation.getTime(); boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; boolean isNewer = timeDelta > 0; // If it's been more than two minutes since the current location, use the new location // because the user has likely moved if (isSignificantlyNewer) { return location; // If the new location is more than two minutes older, it must be worse } else if (isSignificantlyOlder) { return currentBestLocation; } // Check whether the new location fix is more or less accurate int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); boolean isLessAccurate = accuracyDelta > 0; boolean isMoreAccurate = accuracyDelta < 0; boolean isSignificantlyLessAccurate = accuracyDelta > 200; // Check if the old and new location are from the same provider boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider()); // Determine location quality using a combination of timeliness and accuracy if (isMoreAccurate) { return location; } else if (isNewer && !isLessAccurate) { return location; } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { return location; } return currentBestLocation; } /** * Checks whether two providers are the same */ private boolean isSameProvider(String provider1, String provider2) { if (provider1 == null) { return provider2 == null; } return provider1.equals(provider2); } public boolean isLocationAccurate(Location location) { if (location.hasAccuracy()) { return true; } else { return false; } } public Location getStaleLocation() { if (mLastLocationFetched != null) { return mLastLocationFetched; } if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return null; } if (mProviderType == SmartLocationManager.GPS_PROVIDER) { return locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); } else if (mProviderType == SmartLocationManager.NETWORK_PROVIDER) { return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } else { return getBetterLocation(locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER), locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)); } }}
we can use it with activity or a fragment, here i am using it with activity
我们可以将它与活动或片段一起使用,我在这里使用它与活动
import android.location.Location;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.widget.TextView;import android.widget.Toast;import com.example.raza.locationaware.location.LocationManagerInterface;import com.example.raza.locationaware.location.SmartLocationManager;import com.google.android.gms.location.LocationRequest;public class LocationActivity extends AppCompatActivity implements LocationManagerInterface { public static final String TAG = LocationActivity.class.getSimpleName(); SmartLocationManager mLocationManager; TextView mLocalTV, mLocationProviderTV, mlocationTimeTV; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_location); mLocationManager = new SmartLocationManager(getApplicationContext(), this, this, SmartLocationManager.ALL_PROVIDERS, LocationRequest.PRIORITY_HIGH_ACCURACY, 10 * 1000, 1 * 1000, SmartLocationManager.LOCATION_PROVIDER_RESTRICTION_NONE); // init location manager mLocalTV = (TextView) findViewById(R.id.locationDisplayTV); mLocationProviderTV = (TextView) findViewById(R.id.locationProviderTV); mlocationTimeTV = (TextView) findViewById(R.id.locationTimeFetchedTV); } protected void onStart() { super.onStart(); mLocationManager.startLocationFetching(); } protected void onStop() { super.onStop(); mLocationManager.abortLocationFetching(); } @Override protected void onPause() { super.onPause(); mLocationManager.pauseLocationFetching(); } @Override public void locationFetched(Location mLocal, Location oldLocation, String time, String locationProvider) { Toast.makeText(getApplication(), "Lat : " + mLocal.getLatitude() + " Lng : " + mLocal.getLongitude(), Toast.LENGTH_LONG).show(); mLocalTV.setText("Lat : " + mLocal.getLatitude() + " Lng : " + mLocal.getLongitude()); mLocationProviderTV.setText(locationProvider); mlocationTimeTV.setText(time); }}
Hope it helps, if you can suggest any improvement kindly post it on git. Thanks.
希望它有所帮助,如果你可以建议任何改进,请将它发布在git上。谢谢。
#14
GoogleSamples has verbose example using latest FusedLocationProviderApi.Unfortunately the most upvoted answers are out of date.
GoogleSamples使用最新的FusedLocationProviderApi进行了详细示例。遗憾的是,最受欢迎的答案已过时。
Follow the below examples to implement Location Services using FusedLocationProviderApi
按照以下示例使用FusedLocationProviderApi实现位置服务
https://github.com/googlesamples/android-play-location/tree/master/LocationUpdates
#15
If you are creating new location projects for Android you should use the new Google Play location services. It is much more accurate and much simpler to use.
如果您要为Android创建新的位置项目,则应使用新的Google Play位置服务。它使用起来更准确,更简单。
I have been working on an open source GPS tracker project, GpsTracker, for several years. I recently updated it to handle periodic updates from Android, iOS, Windows Phone and Java ME cell phones. It is fully functional and does what you need and has the MIT License.
多年来,我一直致力于开源GPS跟踪器项目GpsTracker。我最近对其进行了更新,以处理来自Android,iOS,Windows Phone和Java ME手机的定期更新。它功能齐全,可满足您的需求并拥有MIT许可证。
The Android project within GpsTracker uses the new Google Play services and there are also two server stacks (ASP.NET and PHP) to allow you to track those phones.
GpsTracker中的Android项目使用新的Google Play服务,还有两个服务器堆栈(ASP.NET和PHP),可让您跟踪这些手机。
#16
For just location checking you can use following code. You can put it in your onStart() of main activity and display alert dialog if return is false.
对于只是位置检查,您可以使用以下代码。您可以将它放在主活动的onStart()中,如果return为false,则显示警告对话框。
private boolean isLocationAccurate() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { String provider = Settings.Secure .getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); if (provider != null && !provider.contains("gps")) { return false; } } else { try { int status = Settings.Secure .getInt(this.getContentResolver(), Settings.Secure.LOCATION_MODE); if (status != Settings.Secure.LOCATION_MODE_HIGH_ACCURACY) { return false; } } catch (Settings.SettingNotFoundException e) { Log.e(TAG, e.getMessage()); } } return true; }
#17
I have published a small library that can make it easy to get location data in Android, it even takes care of Android M runtime permissions.
我已经发布了一个小型库,可以很容易地在Android中获取位置数据,它甚至可以处理Android M运行时权限。
You might check it out here: https://github.com/julioromano/RxLocation and use it or its source code as examples for your implementation.
您可以在这里查看:https://github.com/julioromano/RxLocation并使用它或其源代码作为您的实现示例。
#18
Simple Find Write Code in On Location Method
在定位方法中简单查找写代码
public void onLocationChanged(Location location) { if (mCurrLocationMarker != null) { mCurrLocationMarker.remove(); } //Place current location marker LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng); markerOptions.title("Current Position"); markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); mCurrLocationMarker = mMap.addMarker(markerOptions); //move map camera mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); mMap.animateCamera(CameraUpdateFactory.zoomTo(18)); PolylineOptions pOptions = new PolylineOptions() .width(5) .color(Color.GREEN) .geodesic(true); for (int z = 0; z < routePoints.size(); z++) { LatLng point = routePoints.get(z); pOptions.add(point); } line = mMap.addPolyline(pOptions); routePoints.add(latLng);}
#19
I will recommend using Smart Location Library
Very simple to use and it wraps the location logic nicely.
我将建议使用智能位置库非常简单易用,它很好地包装了位置逻辑。
For starting the location service:
要启动位置服务:
SmartLocation.with(context).location() .start(new OnLocationUpdatedListener() { ... });
If you just want to get a single location (not periodic) you can just use the oneFix modifier. Example:
如果您只想获得一个位置(非周期性),您可以使用oneFix修改器。例:
SmartLocation.with(context).location() .oneFix() .start(new OnLocationUpdatedListener() { ... });
#20
I have got very accurate location using FusedLocationProviderClient
(Google Play services required)
我使用FusedLocationProviderClient获得了非常准确的位置(需要Google Play服务)
Permissions Required
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_COARSE_LOCATION
Dependency
'com.google.android.gms:play-services-location:15.0.0'
Kotlin Code
val client = FusedLocationProviderClient(this)val location = client.lastLocationlocation.addOnCompleteListener { // this is a lambda expression and we get an 'it' iterator to access the 'result' // it.result.latitude gives the latitude // it.result.longitude gives the longitude val geocoder = Geocoder(applicationContext, Locale.getDefault()) val address = geocoder.getFromLocation(it.result.latitude, it.result.longitude, 1) if (address != null && address.size > 0) { // Get the current city city = address[0].locality }}location.addOnFailureListener { // Some error in getting the location, let's log it Log.d("xtraces", it.message)}
#21
Simple and easy way,
简单方便,
Get location using https://github.com/sachinvarma/EasyLocation.
使用https://github.com/sachinvarma/EasyLocation获取位置。
Step 1: Just call
第1步:打电话
new EasyLocationInit(MainActivity.this, timeInterval, fastestTimeInterval, runAsBackgroundService);
timeInterval -> setInterval(long)(inMilliSeconds) means - set the interval in which you want to get locations.
timeInterval - > setInterval(long)(inMilliSeconds)表示 - 设置要获取位置的时间间隔。
fastestTimeInterval -> setFastestInterval(long)(inMilliSeconds) means - if a location is available sooner you can get it. (i.e. another app is using the location services).
fasterTimeInterval - > setFastestInterval(long)(inMilliSeconds)表示 - 如果某个位置可以尽快获得它。 (即另一个应用程序正在使用位置服务)。
runAsBackgroundService = True -> (Service will run in Background and updates Frequently(according to the timeInterval and fastestTimeInterval)) runAsBackgroundService = False -> (Service will getDestroyed after a successful location update )
runAsBackgroundService = True - >(服务将在后台运行并经常更新(根据timeInterval和fasterTimeInterval))runAsBackgroundService = False - >(成功更新位置后服务将被getDestroyed)
Step 2: Prepare EventBus subscribers: Declare and annotate your subscribing method, optionally specify a thread mode:
步骤2:准备EventBus订阅者:声明并注释您的订阅方法,可选择指定一个线程模式:
eg:
@Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { super.onStop(); EventBus.getDefault().unregister(this); } @SuppressLint("SetTextI18n") @Subscribe public void getEvent(final Event event) { if (event instanceof LocationEvent) { if (((LocationEvent) event).location != null) { ((TextView) findViewById(R.id.tvLocation)).setText("The Latitude is " + ((LocationEvent) event).location.getLatitude() + " and the Longitude is " + ((LocationEvent) event).location.getLongitude()); } } }
That's all.
Hope it will help someone in future.
希望它将来有助于某人。
#22
Best way to fetch location is below
获取位置的最佳方式如下
// put dependancy implementation 'com.google.android.gms:play-services-location:11.0.4'// PUT permissions in Menifest<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> // create a Java file as belowpublic 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); if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } 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; } }}// FILE FINISHED// FETCH LOCATION FROM ACTIVITY AS BELOWpublic void getLocation(Context context) { MyApplication.log(LOG_TAG, "getLocation() "); SingleShotLocationProvider.requestSingleUpdate(context, new SingleShotLocationProvider.LocationCallback() { @Override public void onNewLocationAvailable(SingleShotLocationProvider.GPSCoordinates loc) { location = loc; MyApplication.log(LOG_TAG, "getLocation() LAT: " + location.latitude + ", LON: " + location.longitude); } });}
#1
I have created a small application with step by step description to get current location's GPS coordinates.
我创建了一个小型应用程序,逐步描述获取当前位置的GPS坐标。
Complete example source code is in Get Current Location coordinates , City name - in Android.
完整的示例源代码位于获取当前位置坐标,城市名称 - 在Android中。
See how it works:
看看它怎么运作:
-
All we need to do is add this permission in the manifest file:
我们需要做的就是在清单文件中添加此权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-
And create a LocationManager instance like this:
并创建一个这样的LocationManager实例:
LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
-
Check if GPS is enabled or not.
检查GPS是否启用。
-
And then implement LocationListener and get coordinates:
然后实现LocationListener并获取坐标:
LocationListener locationListener = new MyLocationListener();locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
-
Here is the sample code to do so
以下是执行此操作的示例代码
/*---------- Listener class to get coordinates ------------- */private class MyLocationListener implements LocationListener { @Override public void onLocationChanged(Location loc) { editLocation.setText(""); pb.setVisibility(View.INVISIBLE); Toast.makeText( getBaseContext(), "Location changed: Lat: " + loc.getLatitude() + " Lng: " + loc.getLongitude(), Toast.LENGTH_SHORT).show(); String longitude = "Longitude: " + loc.getLongitude(); Log.v(TAG, longitude); String latitude = "Latitude: " + loc.getLatitude(); Log.v(TAG, latitude); /*------- To get city name from coordinates -------- */ String cityName = null; Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault()); List<Address> addresses; try { addresses = gcd.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1); if (addresses.size() > 0) { System.out.println(addresses.get(0).getLocality()); cityName = addresses.get(0).getLocality(); } } catch (IOException e) { e.printStackTrace(); } String s = longitude + "\n" + latitude + "\n\nMy Current City is: " + cityName; editLocation.setText(s); } @Override public void onProviderDisabled(String provider) {} @Override public void onProviderEnabled(String provider) {} @Override public void onStatusChanged(String provider, int status, Bundle extras) {}}
#2
Here is additional information for other answers.
以下是其他答案的其他信息。
Since Android has
自Android以来
GPS_PROVIDER and NETWORK_PROVIDER
you can register to both and start fetch events from onLocationChanged(Location location)
from two at the same time. So far so good. Now the question do we need two results or we should take the best. As I know GPS_PROVIDER
results have better accuracy than NETWORK_PROVIDER
.
您可以注册两者并同时从两个开始从onLocationChanged(位置位置)获取事件。到现在为止还挺好。现在问题是我们需要两个结果,还是我们应该采取最好的结果。据我所知,GPS_PROVIDER结果的准确度要高于NETWORK_PROVIDER。
Let's define Location
field:
让我们定义位置字段:
private Location currentBestLocation = null;
Before we start listen on Location change we will implement the following method. This method returns the last known location, between the GPS and the network one. For this method newer is best.
在我们开始听取位置更改之前,我们将实现以下方法。该方法返回GPS和网络之间的最后已知位置。对于这种方法,新方法最好。
/** * @return the last know best location */private Location getLastBestLocation() { Location locationGPS = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); Location locationNet = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); long GPSLocationTime = 0; if (null != locationGPS) { GPSLocationTime = locationGPS.getTime(); } long NetLocationTime = 0; if (null != locationNet) { NetLocationTime = locationNet.getTime(); } if ( 0 < GPSLocationTime - NetLocationTime ) { return locationGPS; } else { return locationNet; }}
Each time when we retrieve a new location we will compare it with our previous result.
每当我们检索新位置时,我们都会将其与之前的结果进行比较。
...static final int TWO_MINUTES = 1000 * 60 * 2;...
I add a new method to onLocationChanged
:
我在onLocationChanged中添加了一个新方法:
@Overridepublic void onLocationChanged(Location location) { makeUseOfNewLocation(location); if(currentBestLocation == null){ currentBestLocation = location; } ....}/** * This method modify the last know good location according to the arguments. * * @param location The possible new location. */void makeUseOfNewLocation(Location location) { if ( isBetterLocation(location, currentBestLocation) ) { currentBestLocation = location; }}..../** Determines whether one location reading is better than the current location fix * @param location The new location that you want to evaluate * @param currentBestLocation The current location fix, to which you want to compare the new one. */protected boolean isBetterLocation(Location location, Location currentBestLocation) { if (currentBestLocation == null) { // A new location is always better than no location return true; } // Check whether the new location fix is newer or older long timeDelta = location.getTime() - currentBestLocation.getTime(); boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; boolean isNewer = timeDelta > 0; // If it's been more than two minutes since the current location, use the new location, // because the user has likely moved. if (isSignificantlyNewer) { return true; // If the new location is more than two minutes older, it must be worse. } else if (isSignificantlyOlder) { return false; } // Check whether the new location fix is more or less accurate int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); boolean isLessAccurate = accuracyDelta > 0; boolean isMoreAccurate = accuracyDelta < 0; boolean isSignificantlyLessAccurate = accuracyDelta > 200; // Check if the old and new location are from the same provider boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider()); // Determine location quality using a combination of timeliness and accuracy if (isMoreAccurate) { return true; } else if (isNewer && !isLessAccurate) { return true; } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { return true; } return false;}// Checks whether two providers are the sameprivate boolean isSameProvider(String provider1, String provider2) { if (provider1 == null) { return provider2 == null; } return provider1.equals(provider2);}....
#3
You can find the location either by GPS_PROVIDER or NETWORK_PROVIDER
.
您可以通过GPS_PROVIDER或NETWORK_PROVIDER找到该位置。
Overview of location services in Android.
Android中的位置服务概述。
Here is one example which try to find the location using GPS. If your GPS is not available then try to use network for find the location.
以下是尝试使用GPS查找位置的一个示例。如果您的GPS不可用,请尝试使用网络查找位置。
GPSTracker.java
public class GPSTracker extends Service implements LocationListener { private final Context mContext; // Flag for GPS status boolean isGPSEnabled = false; // Flag for network status boolean isNetworkEnabled = false; // Flag for GPS status boolean canGetLocation = false; Location location; // Location double latitude; // Latitude double longitude; // Longitude // The minimum distance to change Updates in meters private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters // The minimum time between updates in milliseconds private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute // Declaring a Location Manager protected LocationManager locationManager; public GPSTracker(Context context) { this.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 isNetworkEnabled = locationManager .isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (!isGPSEnabled && !isNetworkEnabled) { // No network provider is enabled } else { this.canGetLocation = true; if (isNetworkEnabled) { locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("Network", "Network"); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } // If GPS enabled, get latitude/longitude using GPS Services if (isGPSEnabled) { if (location == null) { locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); Log.d("GPS Enabled", "GPS Enabled"); if (locationManager != null) { location = locationManager .getLastKnownLocation(LocationManager.GPS_PROVIDER); if (location != null) { latitude = location.getLatitude(); longitude = location.getLongitude(); } } } } } } catch (Exception e) { e.printStackTrace(); } return location; } /** * Stop using GPS listener * Calling this function will stop using GPS in your app. * */ public void stopUsingGPS(){ if(locationManager != null){ locationManager.removeUpdates(GPSTracker.this); } } /** * Function to get latitude * */ public double getLatitude(){ if(location != null){ latitude = location.getLatitude(); } // return latitude return latitude; } /** * Function to get longitude * */ public double getLongitude(){ if(location != null){ longitude = location.getLongitude(); } // return longitude return longitude; } /** * Function to check GPS/Wi-Fi enabled * @return boolean * */ public boolean canGetLocation() { return this.canGetLocation; } /** * Function to show settings alert dialog. * On pressing the Settings button it will launch Settings Options. * */ public void showSettingsAlert(){ AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext); // Setting Dialog Title alertDialog.setTitle("GPS is settings"); // Setting Dialog Message alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?"); // On pressing the Settings button. alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog,int which) { Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); mContext.startActivity(intent); } }); // On pressing the cancel button alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); // Showing Alert Message alertDialog.show(); } @Override public void onLocationChanged(Location location) { } @Override public void onProviderDisabled(String provider) { } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public IBinder onBind(Intent arg0) { return null; }}
Activity -AndroidGPSTrackingActivity.java
public class AndroidGPSTrackingActivity extends Activity { Button btnShowLocation; // GPSTracker class GPSTracker gps; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnShowLocation = (Button) findViewById(R.id.btnShowLocation); // Show location button click event btnShowLocation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // Create class object gps = new GPSTracker(AndroidGPSTrackingActivity.this); // Check if GPS enabled if(gps.canGetLocation()) { double latitude = gps.getLatitude(); double longitude = gps.getLongitude(); // \n is for new line Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show(); } else { // Can't get location. // GPS or network is not enabled. // Ask user to enable GPS/network in settings. gps.showSettingsAlert(); } } }); }}
Layout- main.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/btnShowLocation" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Show Location" android:layout_centerVertical="true" android:layout_centerHorizontal="true"/></RelativeLayout>
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.INTERNET" />
#4
There are already many answers there but I want to show latest way to get location using Google API, so new programmers can use new method:
那里已经有很多答案,但我想展示使用Google API获取位置的最新方式,因此新程序员可以使用新方法:
I have written detailed tutorial on current location in android at my blog demonuts.com You can also find full source code developed with android studio.
我在我的博客demonuts.com上写了关于android当前位置的详细教程。你也可以找到用android studio开发的完整源代码。
First of all, put this in gradle file
首先,将它放在gradle文件中
compile 'com.google.android.gms:play-services:9.0.2'
then implement necessary interfaces
然后实现必要的接口
public class MainActivity extends BaseActivitiy implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener
declare instances
private GoogleApiClient mGoogleApiClient; private Location mLocation; private LocationManager locationManager; private LocationRequest mLocationRequest;
put this in onCreate()
把它放在onCreate()
mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
At last, override necessary methods
最后,重写必要的方法
@Override public void onConnected(Bundle bundle) { 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; } startLocationUpdates(); mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); if(mLocation == null){ startLocationUpdates(); } if (mLocation != null) { double latitude = mLocation.getLatitude(); double longitude = mLocation.getLongitude(); } else { // Toast.makeText(this, "Location not Detected", Toast.LENGTH_SHORT).show(); } } protected void startLocationUpdates() { // Create the location request mLocationRequest = LocationRequest.create() .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) .setInterval(UPDATE_INTERVAL) .setFastestInterval(FASTEST_INTERVAL); // Request location updates 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; } LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); Log.d("reque", "--->>>>"); } @Override public void onConnectionSuspended(int i) { Log.i(TAG, "Connection Suspended"); mGoogleApiClient.connect(); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.i(TAG, "Connection failed. Error: " + connectionResult.getErrorCode()); } @Override public void onStart() { super.onStart(); mGoogleApiClient.connect(); } @Override public void onStop() { super.onStop(); if (mGoogleApiClient.isConnected()) { mGoogleApiClient.disconnect(); } } @Override public void onLocationChanged(Location location) { }
Don't forget to start GPS in your device before running app.
在运行应用程序之前,请不要忘记在设备中启动GPS。
#5
Since I didn't like some of the code in the other answers, here's my simple solution. This solution is meant to be usable in an Activity or Service to track the location. It makes sure that it never returns data that's too stale unless you explicitly request stale data. It can be run in either a callback mode to get updates as we receive them, or in poll mode to poll for the most recent info.
由于我不喜欢其他答案中的一些代码,这是我的简单解决方案。此解决方案旨在可用于活动或服务以跟踪位置。除非您明确请求陈旧数据,否则它确保它永远不会返回太陈旧的数据。它可以在回调模式下运行以在我们收到更新时获得更新,也可以在轮询模式下轮询以查询最新信息。
Generic LocationTracker interface. Allows us to have multiple types of location trackers and plug the appropriate one in easily:
通用LocationTracker接口。允许我们拥有多种类型的位置跟踪器并轻松插入相应的位置跟踪器:
package com.gabesechan.android.reusable.location;import android.location.Location;public interface LocationTracker { public interface LocationUpdateListener{ public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime); } public void start(); public void start(LocationUpdateListener update); public void stop(); public boolean hasLocation(); public boolean hasPossiblyStaleLocation(); public Location getLocation(); public Location getPossiblyStaleLocation();}
ProviderLocationTracker- this class will track the location for either GPS or NETWORK.
ProviderLocationTracker-此类将跟踪GPS或NETWORK的位置。
package com.gabesechan.android.reusable.location;import android.content.Context;import android.location.Location;import android.location.LocationListener;import android.location.LocationManager;import android.os.Bundle;public class ProviderLocationTracker implements LocationListener, LocationTracker { // The minimum distance to change Updates in meters private static final long MIN_UPDATE_DISTANCE = 10; // The minimum time between updates in milliseconds private static final long MIN_UPDATE_TIME = 1000 * 60; private LocationManager lm; public enum ProviderType{ NETWORK, GPS }; private String provider; private Location lastLocation; private long lastTime; private boolean isRunning; private LocationUpdateListener listener; public ProviderLocationTracker(Context context, ProviderType type) { lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); if(type == ProviderType.NETWORK){ provider = LocationManager.NETWORK_PROVIDER; } else{ provider = LocationManager.GPS_PROVIDER; } } public void start(){ if(isRunning){ //Already running, do nothing return; } //The provider is on, so start getting updates. Update current location isRunning = true; lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE, this); lastLocation = null; lastTime = 0; return; } public void start(LocationUpdateListener update) { start(); listener = update; } public void stop(){ if(isRunning){ lm.removeUpdates(this); isRunning = false; listener = null; } } public boolean hasLocation(){ if(lastLocation == null){ return false; } if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){ return false; //stale } return true; } public boolean hasPossiblyStaleLocation(){ if(lastLocation != null){ return true; } return lm.getLastKnownLocation(provider)!= null; } public Location getLocation(){ if(lastLocation == null){ return null; } if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){ return null; //stale } return lastLocation; } public Location getPossiblyStaleLocation(){ if(lastLocation != null){ return lastLocation; } return lm.getLastKnownLocation(provider); } public void onLocationChanged(Location newLoc) { long now = System.currentTimeMillis(); if(listener != null){ listener.onUpdate(lastLocation, lastTime, newLoc, now); } lastLocation = newLoc; lastTime = now; } public void onProviderDisabled(String arg0) { } public void onProviderEnabled(String arg0) { } public void onStatusChanged(String arg0, int arg1, Bundle arg2) { }}
The is the FallbackLocationTracker, which will track by both GPS and NETWORK, and use whatever location is more accurate.
这是FallbackLocationTracker,它将通过GPS和NETWORK进行跟踪,并使用任何更准确的位置。
package com.gabesechan.android.reusable.location;import android.content.Context;import android.location.Location;import android.location.LocationManager;public class FallbackLocationTracker implements LocationTracker, LocationTracker.LocationUpdateListener { private boolean isRunning; private ProviderLocationTracker gps; private ProviderLocationTracker net; private LocationUpdateListener listener; Location lastLoc; long lastTime; public FallbackLocationTracker(Context context) { gps = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.GPS); net = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.NETWORK); } public void start(){ if(isRunning){ //Already running, do nothing return; } //Start both gps.start(this); net.start(this); isRunning = true; } public void start(LocationUpdateListener update) { start(); listener = update; } public void stop(){ if(isRunning){ gps.stop(); net.stop(); isRunning = false; listener = null; } } public boolean hasLocation(){ //If either has a location, use it return gps.hasLocation() || net.hasLocation(); } public boolean hasPossiblyStaleLocation(){ //If either has a location, use it return gps.hasPossiblyStaleLocation() || net.hasPossiblyStaleLocation(); } public Location getLocation(){ Location ret = gps.getLocation(); if(ret == null){ ret = net.getLocation(); } return ret; } public Location getPossiblyStaleLocation(){ Location ret = gps.getPossiblyStaleLocation(); if(ret == null){ ret = net.getPossiblyStaleLocation(); } return ret; } public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime) { boolean update = false; //We should update only if there is no last location, the provider is the same, or the provider is more accurate, or the old location is stale if(lastLoc == null){ update = true; } else if(lastLoc != null && lastLoc.getProvider().equals(newLoc.getProvider())){ update = true; } else if(newLoc.getProvider().equals(LocationManager.GPS_PROVIDER)){ update = true; } else if (newTime - lastTime > 5 * 60 * 1000){ update = true; } if(update){ if(listener != null){ listener.onUpdate(lastLoc, lastTime, newLoc, newTime); } lastLoc = newLoc; lastTime = newTime; } }}
Since both implement the LocationTracker interface, you can easily change your mind about which one to use. To run the class in poll mode, just call start(). To run it in update mode, call start(Listener).
由于两者都实现了LocationTracker接口,因此您可以轻松改变您对使用哪个接口的想法。要在轮询模式下运行类,只需调用start()。要在更新模式下运行它,请调用start(Listener)。
Also take a look at my blog post on the code
另请查看关于代码的博客文章
#6
Get location of gps by -
获取gps的位置 -
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);LocationListener locationListener = new LocationListener() { @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onLocationChanged(Location location) { // TODO Auto-generated method stub double latitude = location.getLatitude(); double longitude = location.getLongitude(); double speed = location.getSpeed(); //spedd in meter/minute speed = (speed*3600)/1000; // speed in km/minute Toast.makeText(GraphViews.this, "Current speed:" + location.getSpeed(),Toast.LENGTH_SHORT).show(); } }; locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);}
#7
You need to use latest/newest
你需要使用最新/最新
GoogleApiClient Api
Basically what you need to do is:
基本上你需要做的是:
private GoogleApiClient mGoogleApiClient;mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build();
Then
@Override public void onConnected(Bundle connectionHint) { mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mLastLocation != null) { mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude())); mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude())); } }
for the most accurate and reliable location. See my post here:
为了最准确和可靠的位置。在这里看我的帖子:
https://*.com/a/33599228/2644905
Do not use LocationListener which is not accurate and has delayed response. To be honest this is easier to implement.Also read documentation: https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient
不要使用不准确且响应延迟的LocationListener。说实话,这更容易实现。另外阅读文档:https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient
#8
class MyLocation { Timer timer1; LocationManager lm; LocationResult locationResult; boolean gps_enabled = false; boolean network_enabled = false; 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 the 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(), 5000); 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 { @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); }}
I hope this will help you...
我希望这能帮到您...
#9
Now that Google Play locations services are here, I recommend that developers start using the new fused location provider. You will find it easier to use and more accurate. Please watch the Google I/O video Beyond the Blue Dot: New Features in Android Location by the two guys who created the new Google Play location services API.
既然Google Play位置服务已经存在,我建议开发人员开始使用新的融合位置提供商。您会发现它更容易使用且更准确。请观看创建新Google Play位置服务API的两个人观看Google I / O视频超越蓝点:Android位置的新功能。
I've been working with location APIs on a number of mobile platforms, and I think what these two guys have done is really revolutionary. It's gotten rid of a huge amount of the complexities of using the various providers. Stack Overflow is littered with questions about which provider to use, whether to use last known location, how to set other properties on the LocationManager, etc. This new API that they have built removes most of those uncertainties and makes the location services a pleasure to use.
我一直在许多移动平台上使用位置API,我认为这两个人所做的真的是革命性的。它摆脱了使用各种提供商的大量复杂性。 Stack Overflow充斥着关于使用哪个提供商,是否使用最后已知位置,如何在LocationManager上设置其他属性等问题。他们构建的这个新API消除了大部分不确定性并使位置服务成为愉快的选择。使用。
I've written an Android app that periodically gets the location using Google Play location services and sends the location to a web server where it is stored in a database and can be viewed on Google Maps. I've written both the client software (for Android, iOS, Windows Phone and Java ME) and the server software (for ASP.NET and SQL Server or PHP and MySQL). The software is written in the native language on each platform and works properly in the background on each. Lastly, the software has the MIT License. You can find the Android client here:
我编写了一个Android应用程序,定期使用Google Play位置服务获取该位置,并将该位置发送到Web服务器,并将其存储在数据库中,并可在Google地图上查看。我已经编写了客户端软件(适用于Android,iOS,Windows Phone和Java ME)和服务器软件(适用于ASP.NET和SQL Server或PHP和MySQL)。该软件在每个平台上都以母语编写,并在每个平台的后台正常工作。最后,该软件具有MIT许可证。您可以在此处找到Android客户端:
https://github.com/nickfox/GpsTracker/tree/master/phoneClients/android
#10
LocationManager is a class that provides in-build methods to get last know location
LocationManager是一个提供构建方法以获取最后知道位置的类
STEP 1 :Create a LocationManager Object as below
第1步:创建一个LocationManager对象,如下所示
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
LocationManager locationManager =(LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
STEP 2 : Add Criteria
第2步:添加标准
*Criteria is use for setting accuracy*Criteria criteria = new Criteria();int currentapiVersion = android.os.Build.VERSION.SDK_INT;if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) { criteria.setSpeedAccuracy(Criteria.ACCURACY_HIGH); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(true); criteria.setBearingRequired(true); criteria.setSpeedRequired(true);}
STEP 3 :GET Avaliable Provider
第3步:获得Avaliable Provider
Threre are two types of provider GPS and network
Threre是提供商GPS和网络的两种类型
String provider = locationManager.getBestProvider(criteria, true);
STEP 4: Get Last Know Location
第4步:获取最后知道的位置
Location location = locationManager.getLastKnownLocation(provider);
STEP 5: Get Latitude and Longitude
第5步:获取纬度和经度
If location object is null then dont try to call below methods
如果location对象为null,则不要尝试调用以下方法
getLatitude and getLongitude is methods which returns double values
getLatitude和getLongitude是返回double值的方法
#11
Simplest you can find
最简单的你可以找到
package com.javapapers.android.geolocationfinder; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.widget.TextView; import android.util.Log; public class MainActivity extends Activity implements LocationListener{ protected LocationManager locationManager; protected LocationListener locationListener; protected Context context; TextView txtLat; String lat; String provider; protected String latitude,longitude; protected boolean gps_enabled,network_enabled; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); txtLat = (TextView) findViewById(R.id.textview1); locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); } @Override public void onLocationChanged(Location location) { txtLat = (TextView) findViewById(R.id.textview1); txtLat.setText("Latitude:" + location.getLatitude() + ", Longitude:" + location.getLongitude()); } @Override public void onProviderDisabled(String provider) { Log.d("Latitude","disable"); } @Override public void onProviderEnabled(String provider) { Log.d("Latitude","enable"); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { Log.d("Latitude","status"); } }
#12
Getting location updates requires lots of bolierplate code in Android, You need to take care of
获取位置更新需要在Android中使用大量的bolierplate代码,您需要注意
- Google Play services availablity Check,
- Update Google play Service if it is old or not available
- Dialog Creation of GoogleApiClient and its callbacks connected,disconnected etc.
- Stopping and releasing resources for location updates
- Handling Location permission scenarios
- Checking Location services are On or Off
- Getting lastknown location is not so easy either
- Fallback to last known location if not getting location after certain duration
Google Play服务可用性检查,
如果旧版或不可用,请更新Google Play服务
对话创建GoogleApiClient及其回调连接,断开连接等。
停止和释放资源以进行位置更新
处理位置权限方案
检查位置服务是开还是关
获取最后的位置也不是那么容易
如果在一定时间后没有获得位置,则回退到最后已知位置
To ease out all these steps i have created Android-EasyLocation (small android library) which will take care all this stuff and you can focus on business logic.
为了简化所有这些步骤,我创建了Android-EasyLocation(小型android库),它将关注所有这些内容,您可以专注于业务逻辑。
All you need is extend EasyLocationActivity and this
您只需要扩展EasyLocationActivity和它
requestSingleLocationFix(easyLocationRequest);
or
requestLocationUpdates(easyLocationRequest);
Checkout sample app and steps needed here at https://github.com/akhgupta/Android-EasyLocation
通过https://github.com/akhgupta/Android-EasyLocation查看示例应用程序和步骤
#13
I have made a project from which we can get the accurate location using Google Play Services, GPS and Network providers. This project can be found here.
我制作了一个项目,通过Google Play服务,GPS和网络提供商,我们可以从中获得准确的位置。这个项目可以在这里找到。
Strategy in finding the best location is that first get the location from google play services if location is found then check weather it is better or not, if location found is null restart google play services and try to fetch the location from Android Location API. Register the location on change listeners and when ever the better location is found the call back returns it to the main activity.
找到最佳位置的策略是首先从谷歌播放服务获取位置,如果找到位置然后检查天气是否更好,如果找到的位置是null重新启动谷歌播放服务并尝试从Android位置API获取位置。在更改侦听器上注册位置,当找到更好的位置时,回叫将其返回到主活动。
It is very simple to use and implement in code only two classes we need to embed i.e. LocationManagerInterface
and SmartLocationManager
, LocationActivity
is implementing the interface and using SmartLocationManager to fetch location.
在代码中使用和实现非常简单,我们需要嵌入两个类,即LocationManagerInterface和SmartLocationManager,LocationActivity正在实现接口并使用SmartLocationManager来获取位置。
/** * Created by Syed Raza Mehdi Naqvi on 8/10/2016. */public interface LocationManagerInterface { String TAG = LocationManagerInterface.class.getSimpleName(); void locationFetched(Location mLocation, Location oldLocation, String time, String locationProvider);}
here is the location manager class
这是位置管理器类
import android.Manifest;import android.app.Activity;import android.content.Context;import android.content.DialogInterface;import android.content.Intent;import android.content.IntentSender;import android.content.pm.PackageManager;import android.location.Location;import android.location.LocationManager;import android.os.Build;import android.os.Bundle;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v7.app.AlertDialog;import android.util.Log;import android.widget.Toast;import com.google.android.gms.common.ConnectionResult;import com.google.android.gms.common.GooglePlayServicesUtil;import com.google.android.gms.common.api.GoogleApiClient;import com.google.android.gms.location.LocationListener;import com.google.android.gms.location.LocationRequest;import com.google.android.gms.location.LocationServices;import java.text.DateFormat;import java.util.Date;/** * Created by Syed Raza Mehdi Naqvi on 8/9/2016. */public class SmartLocationManager implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { private static final String TAG = SmartLocationManager.class.getSimpleName(); private static final int TWO_MINUTES = 1000 * 60 * 2; private static final int PERMISSION_REQUEST_CODE = 1000; private static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000; // default value is false but user can change it private String mLastLocationUpdateTime; // fetched location time private String locationProvider; // source of fetched location private Location mLastLocationFetched; // location fetched private Location mLocationFetched; // location fetched private Location networkLocation; private Location gpsLocation; private int mLocationPiority; private long mLocationFetchInterval; private long mFastestLocationFetchInterval; private Context mContext; // application context private Activity mActivity; // activity context private LocationRequest mLocationRequest; private GoogleApiClient mGoogleApiClient; private LocationManagerInterface mLocationManagerInterface; private android.location.LocationManager locationManager; private android.location.LocationListener locationListener; boolean isGPSEnabled; boolean isNetworkEnabled; private int mProviderType; public static final int NETWORK_PROVIDER = 1; public static final int ALL_PROVIDERS = 0; public static final int GPS_PROVIDER = 2;// private final double STANDARD_LOCATION_ACCURACY = 100.0;// private final double STANDARD_LOCATION_SEED_LIMIT = 6.95; public static final int LOCATION_PROVIDER_ALL_RESTICTION = 1; public static final int LOCATION_PROVIDER_RESTRICTION_NONE = 0; public static final int LOCATION_PROVIDER_GPS_ONLY_RESTICTION = 2; public static final int LOCATION_PROVIDER_NETWORK_ONLY_RESTICTION = 3; private int mForceNetworkProviders = 0; public SmartLocationManager(Context context, Activity activity, LocationManagerInterface locationInterface, int providerType, int locationPiority, long locationFetchInterval, long fastestLocationFetchInterval, int forceNetworkProviders) { mContext = context; mActivity = activity; mProviderType = providerType; mLocationPiority = locationPiority; mForceNetworkProviders = forceNetworkProviders; mLocationFetchInterval = locationFetchInterval; mFastestLocationFetchInterval = fastestLocationFetchInterval; mLocationManagerInterface = locationInterface; initSmartLocationManager(); } public void initSmartLocationManager() { // 1) ask for permission for Android 6 above to avoid crash // 2) check if gps is available // 3) get location using awesome strategy askLocationPermission(); // for android version 6 above checkNetworkProviderEnable(mForceNetworkProviders); // if (isGooglePlayServicesAvailable()) // if googleplay services available initLocationObjts(); // init obj for google play service and start fetching location else getLocationUsingAndroidAPI(); // otherwise get location using Android API } private void initLocationObjts() { // Create the LocationRequest object mLocationRequest = LocationRequest.create() .setPriority(mLocationPiority) .setInterval(mLocationFetchInterval) // 10 seconds, in milliseconds .setFastestInterval(mFastestLocationFetchInterval); // 1 second, in milliseconds if (mGoogleApiClient == null) { mGoogleApiClient = new GoogleApiClient.Builder(mActivity) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } startLocationFetching(); // connect google play services to fetch location } @Override public void onConnected(Bundle connectionHint) { Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); startLocationUpdates(); if (location == null) { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); getLocationUsingAndroidAPI(); } else { setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); } } @Override public void onLocationChanged(Location location) { if (location == null) { getLastKnownLocation(); } else { setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched); } } @Override public void onConnectionSuspended(int i) { Log.i(TAG, "Connection suspended"); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { if (connectionResult.hasResolution()) { try { connectionResult.startResolutionForResult(mActivity, CONNECTION_FAILURE_RESOLUTION_REQUEST); // Start an Activity that tries to resolve the error getLocationUsingAndroidAPI(); // try to get location using Android API locationManager } catch (IntentSender.SendIntentException e) { e.printStackTrace(); } } else { Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode()); } } private void setNewLocation(Location location, Location oldLocation) { if (location != null) { mLastLocationFetched = oldLocation; mLocationFetched = location; mLastLocationUpdateTime = DateFormat.getTimeInstance().format(new Date()); locationProvider = location.getProvider(); mLocationManagerInterface.locationFetched(location, mLastLocationFetched, mLastLocationUpdateTime, location.getProvider()); } } private void getLocationUsingAndroidAPI() { // Acquire a reference to the system Location Manager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); setLocationListner(); captureLocation(); } public void captureLocation() { if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } try { if (mProviderType == SmartLocationManager.GPS_PROVIDER) { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); } else if (mProviderType == SmartLocationManager.NETWORK_PROVIDER) { locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); } else { locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener); } } catch (Exception e) { Log.e(TAG, e.getMessage()); } } private void setLocationListner() { // Define a listener that responds to location updates locationListener = new android.location.LocationListener() { public void onLocationChanged(Location location) { // Called when a new location is found by the network location provider. if (location == null) { getLastKnownLocation(); } else { setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);// if (isLocationAccurate(location) && location.getAccuracy() < STANDARD_LOCATION_ACCURACY && location.getSpeed() < STANDARD_LOCATION_SEED_LIMIT) {// no use of this if// setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);// } else {// setNewLocation(getBetterLocation(location, mLocationFetched), mLocationFetched);// } } } public void onStatusChanged(String provider, int status, Bundle extras) { } public void onProviderEnabled(String provider) { } public void onProviderDisabled(String provider) { } }; } public Location getAccurateLocation() { if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return null; } try { gpsLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); networkLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); Location newLocalGPS, newLocalNetwork; if (gpsLocation != null || networkLocation != null) { newLocalGPS = getBetterLocation(mLocationFetched, gpsLocation); newLocalNetwork = getBetterLocation(mLocationFetched, networkLocation); setNewLocation(getBetterLocation(newLocalGPS, newLocalNetwork), mLocationFetched); } } catch (Exception ex) { Log.e(TAG, ex.getMessage()); } return mLocationFetched; } protected void startLocationUpdates() { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } public void startLocationFetching() { mGoogleApiClient.connect(); if (mGoogleApiClient.isConnected()) { startLocationUpdates(); } } public void pauseLocationFetching() { if (mGoogleApiClient.isConnected()) { LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); mGoogleApiClient.disconnect(); } } public void abortLocationFetching() { mGoogleApiClient.disconnect(); // Remove the listener you previously added if (locationManager != null && locationListener != null) { if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } try { locationManager.removeUpdates(locationListener); locationManager = null; } catch (Exception ex) { Log.e(TAG, ex.getMessage()); } } } public void resetLocation() { mLocationFetched = null; mLastLocationFetched = null; networkLocation = null; gpsLocation = null; } // Android M Permission check public void askLocationPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) { if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(mActivity, Manifest.permission.ACCESS_FINE_LOCATION)) { final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); builder.setMessage("Please allow all permissions in App Settings for additional functionality.") .setCancelable(false) .setPositiveButton("Allow", new DialogInterface.OnClickListener() { public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) { Toast.makeText(mContext, "Welcome", Toast.LENGTH_SHORT).show(); } }) .setNegativeButton("Deny", new DialogInterface.OnClickListener() { public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) { mActivity.finish(); } }); final AlertDialog alert = builder.create(); alert.show(); } else ActivityCompat.requestPermissions(mActivity, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION , Manifest.permission.ACCESS_FINE_LOCATION }, PERMISSION_REQUEST_CODE); } } } public void checkNetworkProviderEnable(int enforceActive) { locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (!isGPSEnabled && !isNetworkEnabled) { buildAlertMessageTurnOnLocationProviders("Your location providers seems to be disabled, please enable it", "OK", "Cancel"); } else if (!isGPSEnabled && mForceNetworkProviders == LOCATION_PROVIDER_GPS_ONLY_RESTICTION) { buildAlertMessageTurnOnLocationProviders("Your GPS seems to be disabled, please enable it", "OK", "Cancel"); } else if (!isNetworkEnabled && mForceNetworkProviders == LOCATION_PROVIDER_NETWORK_ONLY_RESTICTION) { buildAlertMessageTurnOnLocationProviders("Your Network location provider seems to be disabled, please enable it", "OK", "Cancel"); } // getting network status if (!isGPSEnabled && !isNetworkEnabled) { Toast.makeText(mContext, "Location can't be fetched!", Toast.LENGTH_SHORT).show(); // show alert mActivity.finish(); } } private void buildAlertMessageTurnOnLocationProviders(String message, String positiveButtonText, String negativeButtonText) { final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); builder.setMessage(message) .setCancelable(false) .setPositiveButton(positiveButtonText, new DialogInterface.OnClickListener() { public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) { Intent mIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(mIntent); } }) .setNegativeButton(negativeButtonText, new DialogInterface.OnClickListener() { public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) { mActivity.finish(); } }); final AlertDialog alert = builder.create(); alert.show(); } public Location getLastKnownLocation() { locationProvider = LocationManager.NETWORK_PROVIDER; Location lastKnownLocation = null; // Or use LocationManager.GPS_PROVIDER if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return lastKnownLocation; } try { lastKnownLocation = locationManager.getLastKnownLocation(locationProvider); return lastKnownLocation; } catch (Exception e) { Log.e(TAG, e.getMessage()); } return lastKnownLocation; } public boolean isGooglePlayServicesAvailable() { int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext); if (status == ConnectionResult.SUCCESS) { return true; } else { return false; } } /** * Determines whether one Location reading is better than the current Location fix * * @param location The new Location that you want to evaluate * @param currentBestLocation The current Location fix, to which you want to compare the new one */ protected Location getBetterLocation(Location location, Location currentBestLocation) { if (currentBestLocation == null) { // A new location is always better than no location return location; } // Check whether the new location fix is newer or older long timeDelta = location.getTime() - currentBestLocation.getTime(); boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; boolean isNewer = timeDelta > 0; // If it's been more than two minutes since the current location, use the new location // because the user has likely moved if (isSignificantlyNewer) { return location; // If the new location is more than two minutes older, it must be worse } else if (isSignificantlyOlder) { return currentBestLocation; } // Check whether the new location fix is more or less accurate int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); boolean isLessAccurate = accuracyDelta > 0; boolean isMoreAccurate = accuracyDelta < 0; boolean isSignificantlyLessAccurate = accuracyDelta > 200; // Check if the old and new location are from the same provider boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider()); // Determine location quality using a combination of timeliness and accuracy if (isMoreAccurate) { return location; } else if (isNewer && !isLessAccurate) { return location; } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { return location; } return currentBestLocation; } /** * Checks whether two providers are the same */ private boolean isSameProvider(String provider1, String provider2) { if (provider1 == null) { return provider2 == null; } return provider1.equals(provider2); } public boolean isLocationAccurate(Location location) { if (location.hasAccuracy()) { return true; } else { return false; } } public Location getStaleLocation() { if (mLastLocationFetched != null) { return mLastLocationFetched; } if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return null; } if (mProviderType == SmartLocationManager.GPS_PROVIDER) { return locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); } else if (mProviderType == SmartLocationManager.NETWORK_PROVIDER) { return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } else { return getBetterLocation(locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER), locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)); } }}
we can use it with activity or a fragment, here i am using it with activity
我们可以将它与活动或片段一起使用,我在这里使用它与活动
import android.location.Location;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.widget.TextView;import android.widget.Toast;import com.example.raza.locationaware.location.LocationManagerInterface;import com.example.raza.locationaware.location.SmartLocationManager;import com.google.android.gms.location.LocationRequest;public class LocationActivity extends AppCompatActivity implements LocationManagerInterface { public static final String TAG = LocationActivity.class.getSimpleName(); SmartLocationManager mLocationManager; TextView mLocalTV, mLocationProviderTV, mlocationTimeTV; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_location); mLocationManager = new SmartLocationManager(getApplicationContext(), this, this, SmartLocationManager.ALL_PROVIDERS, LocationRequest.PRIORITY_HIGH_ACCURACY, 10 * 1000, 1 * 1000, SmartLocationManager.LOCATION_PROVIDER_RESTRICTION_NONE); // init location manager mLocalTV = (TextView) findViewById(R.id.locationDisplayTV); mLocationProviderTV = (TextView) findViewById(R.id.locationProviderTV); mlocationTimeTV = (TextView) findViewById(R.id.locationTimeFetchedTV); } protected void onStart() { super.onStart(); mLocationManager.startLocationFetching(); } protected void onStop() { super.onStop(); mLocationManager.abortLocationFetching(); } @Override protected void onPause() { super.onPause(); mLocationManager.pauseLocationFetching(); } @Override public void locationFetched(Location mLocal, Location oldLocation, String time, String locationProvider) { Toast.makeText(getApplication(), "Lat : " + mLocal.getLatitude() + " Lng : " + mLocal.getLongitude(), Toast.LENGTH_LONG).show(); mLocalTV.setText("Lat : " + mLocal.getLatitude() + " Lng : " + mLocal.getLongitude()); mLocationProviderTV.setText(locationProvider); mlocationTimeTV.setText(time); }}
Hope it helps, if you can suggest any improvement kindly post it on git. Thanks.
希望它有所帮助,如果你可以建议任何改进,请将它发布在git上。谢谢。
#14
GoogleSamples has verbose example using latest FusedLocationProviderApi.Unfortunately the most upvoted answers are out of date.
GoogleSamples使用最新的FusedLocationProviderApi进行了详细示例。遗憾的是,最受欢迎的答案已过时。
Follow the below examples to implement Location Services using FusedLocationProviderApi
按照以下示例使用FusedLocationProviderApi实现位置服务
https://github.com/googlesamples/android-play-location/tree/master/LocationUpdates
#15
If you are creating new location projects for Android you should use the new Google Play location services. It is much more accurate and much simpler to use.
如果您要为Android创建新的位置项目,则应使用新的Google Play位置服务。它使用起来更准确,更简单。
I have been working on an open source GPS tracker project, GpsTracker, for several years. I recently updated it to handle periodic updates from Android, iOS, Windows Phone and Java ME cell phones. It is fully functional and does what you need and has the MIT License.
多年来,我一直致力于开源GPS跟踪器项目GpsTracker。我最近对其进行了更新,以处理来自Android,iOS,Windows Phone和Java ME手机的定期更新。它功能齐全,可满足您的需求并拥有MIT许可证。
The Android project within GpsTracker uses the new Google Play services and there are also two server stacks (ASP.NET and PHP) to allow you to track those phones.
GpsTracker中的Android项目使用新的Google Play服务,还有两个服务器堆栈(ASP.NET和PHP),可让您跟踪这些手机。
#16
For just location checking you can use following code. You can put it in your onStart() of main activity and display alert dialog if return is false.
对于只是位置检查,您可以使用以下代码。您可以将它放在主活动的onStart()中,如果return为false,则显示警告对话框。
private boolean isLocationAccurate() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { String provider = Settings.Secure .getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); if (provider != null && !provider.contains("gps")) { return false; } } else { try { int status = Settings.Secure .getInt(this.getContentResolver(), Settings.Secure.LOCATION_MODE); if (status != Settings.Secure.LOCATION_MODE_HIGH_ACCURACY) { return false; } } catch (Settings.SettingNotFoundException e) { Log.e(TAG, e.getMessage()); } } return true; }
#17
I have published a small library that can make it easy to get location data in Android, it even takes care of Android M runtime permissions.
我已经发布了一个小型库,可以很容易地在Android中获取位置数据,它甚至可以处理Android M运行时权限。
You might check it out here: https://github.com/julioromano/RxLocation and use it or its source code as examples for your implementation.
您可以在这里查看:https://github.com/julioromano/RxLocation并使用它或其源代码作为您的实现示例。
#18
Simple Find Write Code in On Location Method
在定位方法中简单查找写代码
public void onLocationChanged(Location location) { if (mCurrLocationMarker != null) { mCurrLocationMarker.remove(); } //Place current location marker LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng); markerOptions.title("Current Position"); markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)); mCurrLocationMarker = mMap.addMarker(markerOptions); //move map camera mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); mMap.animateCamera(CameraUpdateFactory.zoomTo(18)); PolylineOptions pOptions = new PolylineOptions() .width(5) .color(Color.GREEN) .geodesic(true); for (int z = 0; z < routePoints.size(); z++) { LatLng point = routePoints.get(z); pOptions.add(point); } line = mMap.addPolyline(pOptions); routePoints.add(latLng);}
#19
I will recommend using Smart Location Library
Very simple to use and it wraps the location logic nicely.
我将建议使用智能位置库非常简单易用,它很好地包装了位置逻辑。
For starting the location service:
要启动位置服务:
SmartLocation.with(context).location() .start(new OnLocationUpdatedListener() { ... });
If you just want to get a single location (not periodic) you can just use the oneFix modifier. Example:
如果您只想获得一个位置(非周期性),您可以使用oneFix修改器。例:
SmartLocation.with(context).location() .oneFix() .start(new OnLocationUpdatedListener() { ... });
#20
I have got very accurate location using FusedLocationProviderClient
(Google Play services required)
我使用FusedLocationProviderClient获得了非常准确的位置(需要Google Play服务)
Permissions Required
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_COARSE_LOCATION
Dependency
'com.google.android.gms:play-services-location:15.0.0'
Kotlin Code
val client = FusedLocationProviderClient(this)val location = client.lastLocationlocation.addOnCompleteListener { // this is a lambda expression and we get an 'it' iterator to access the 'result' // it.result.latitude gives the latitude // it.result.longitude gives the longitude val geocoder = Geocoder(applicationContext, Locale.getDefault()) val address = geocoder.getFromLocation(it.result.latitude, it.result.longitude, 1) if (address != null && address.size > 0) { // Get the current city city = address[0].locality }}location.addOnFailureListener { // Some error in getting the location, let's log it Log.d("xtraces", it.message)}
#21
Simple and easy way,
简单方便,
Get location using https://github.com/sachinvarma/EasyLocation.
使用https://github.com/sachinvarma/EasyLocation获取位置。
Step 1: Just call
第1步:打电话
new EasyLocationInit(MainActivity.this, timeInterval, fastestTimeInterval, runAsBackgroundService);
timeInterval -> setInterval(long)(inMilliSeconds) means - set the interval in which you want to get locations.
timeInterval - > setInterval(long)(inMilliSeconds)表示 - 设置要获取位置的时间间隔。
fastestTimeInterval -> setFastestInterval(long)(inMilliSeconds) means - if a location is available sooner you can get it. (i.e. another app is using the location services).
fasterTimeInterval - > setFastestInterval(long)(inMilliSeconds)表示 - 如果某个位置可以尽快获得它。 (即另一个应用程序正在使用位置服务)。
runAsBackgroundService = True -> (Service will run in Background and updates Frequently(according to the timeInterval and fastestTimeInterval)) runAsBackgroundService = False -> (Service will getDestroyed after a successful location update )
runAsBackgroundService = True - >(服务将在后台运行并经常更新(根据timeInterval和fasterTimeInterval))runAsBackgroundService = False - >(成功更新位置后服务将被getDestroyed)
Step 2: Prepare EventBus subscribers: Declare and annotate your subscribing method, optionally specify a thread mode:
步骤2:准备EventBus订阅者:声明并注释您的订阅方法,可选择指定一个线程模式:
eg:
@Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { super.onStop(); EventBus.getDefault().unregister(this); } @SuppressLint("SetTextI18n") @Subscribe public void getEvent(final Event event) { if (event instanceof LocationEvent) { if (((LocationEvent) event).location != null) { ((TextView) findViewById(R.id.tvLocation)).setText("The Latitude is " + ((LocationEvent) event).location.getLatitude() + " and the Longitude is " + ((LocationEvent) event).location.getLongitude()); } } }
That's all.
Hope it will help someone in future.
希望它将来有助于某人。
#22
Best way to fetch location is below
获取位置的最佳方式如下
// put dependancy implementation 'com.google.android.gms:play-services-location:11.0.4'// PUT permissions in Menifest<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> // create a Java file as belowpublic 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); if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } 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; } }}// FILE FINISHED// FETCH LOCATION FROM ACTIVITY AS BELOWpublic void getLocation(Context context) { MyApplication.log(LOG_TAG, "getLocation() "); SingleShotLocationProvider.requestSingleUpdate(context, new SingleShotLocationProvider.LocationCallback() { @Override public void onNewLocationAvailable(SingleShotLocationProvider.GPSCoordinates loc) { location = loc; MyApplication.log(LOG_TAG, "getLocation() LAT: " + location.latitude + ", LON: " + location.longitude); } });}