How do I get the current GPS location programmatically in Android?
我需要以编程方式使用GPS获取当前位置。我怎样才能做到?
我已经创建了一个小应用程序,并逐步描述以获取当前位置的GPS坐标。
完整的示例源代码位于get current location coordinates,city name-android中。
看看它是如何工作的:
我们只需要在清单文件中添加此权限:
1<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />并创建这样的locationManager实例:
1
2LocationManager locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);检查GPS是否启用。
然后实现locationListener并获取坐标:
1
2
3LocationListener locationListener = new MyLocationListener();
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 5000, 10, locationListener);这是这样做的示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | /*---------- 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 +" " + latitude +" My 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) {} } |
以下是其他答案的附加信息。
因为Android已经
1 | GPS_PROVIDER and NETWORK_PROVIDER |
您可以同时向两者注册并从两个
让我们定义
1 | private Location currentBestLocation = null; |
在开始监听位置更改之前,我们将实现以下方法。此方法返回GPS和网络GPS之间的最后一个已知位置。对于这种方法,更新是最好的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | /** * @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; } } |
每次我们检索新位置时,都会将其与以前的结果进行比较。
1 2 3 | ... static final int TWO_MINUTES = 1000 * 60 * 2; ... |
我在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | @Override public 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 same private boolean isSameProvider(String provider1, String provider2) { if (provider1 == null) { return provider2 == null; } return provider1.equals(provider2); } .... |
您可以通过
安卓定位服务概述。
下面是一个使用GPS查找位置的示例。如果GPS不可用,请尝试使用网络查找位置。
Java语言
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | 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; } } |
活动-androidgpstrackingActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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(); // is for new line Toast.makeText(getApplicationContext(),"Your Location is - Lat:" + latitude +" Long:" + 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(); } } }); } } |
布局-main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?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文件
1 2 | <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> |
已经有很多答案了,但我想展示使用谷歌API获取位置的最新方法,这样新的程序员可以使用新方法:
我在我的博客demonuts.com上写了一篇关于Android当前位置的详细教程,您还可以找到使用Android Studio开发的完整源代码。
首先,把这个放进梯度文件
1 | compile 'com.google.android.gms:play-services:9.0.2' |
然后实现必要的接口
1 | public class MainActivity extends BaseActivitiy implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener |
声明实例
1 2 3 4 | private GoogleApiClient mGoogleApiClient; private Location mLocation; private LocationManager locationManager; private LocationRequest mLocationRequest; |
把这个放在
1 2 3 4 5 6 | mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); |
最后,重写必要的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | @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) { } |
在运行应用程序之前,不要忘记在设备中启动GPS。
由于我不喜欢其他答案中的一些代码,下面是我的简单解决方案。此解决方案旨在在活动或服务中可用以跟踪位置。它确保它不会返回太陈旧的数据,除非您显式地请求陈旧的数据。它可以在收到更新时以回调模式运行,也可以以轮询模式运行,以轮询最新信息。
通用locationTracker接口。允许我们拥有多种类型的位置追踪器,并轻松插入相应的追踪器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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-此类将跟踪GPS或网络的位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | 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) { } } |
是FallbackLocationTracker,它将通过GPS和网络进行跟踪,并使用任何更精确的位置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | 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; } } } |
由于两者都实现了locationTracker接口,所以您可以轻松地改变主意使用哪个接口。要在轮询模式下运行类,只需调用start()。要在更新模式下运行它,请调用Start(Listener)。
也可以看看我的博客上的代码
GPS定位-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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); } |
您需要使用最新的
GoogleApiClient Api
基本上你需要做的是:
1 2 3 4 5 6 | private GoogleApiClient mGoogleApiClient; mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); |
然后
1 2 3 4 5 6 7 8 9 | @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())); } } |
为最准确和可靠的位置。在这里查看我的帖子:
https://stackoverflow.com/a/33599228/2644905
不要使用不准确且响应延迟的locationListener。老实说,这更容易实现。另请阅读文档:https://developers.google.com/android/reference/com/google/android/gms/common/api/googleapiclient
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | 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); } } |
我希望这能帮助你…
既然google play locations服务已经在这里了,我建议开发人员开始使用新的融合位置提供者。你会发现它更容易使用,更准确。请观看超越蓝点的谷歌I/O视频:两个创建了新的谷歌Play定位服务API的人在Android定位中的新功能。
我一直在许多移动平台上使用位置API,我认为这两个人所做的事情确实是革命性的。它已经摆脱了使用各种提供者的巨大复杂性。堆栈溢出充满了关于使用哪个提供者、是否使用上一个已知位置、如何在locationmanager上设置其他属性等问题。他们构建的这个新API消除了大部分不确定性,使location服务成为一种使用的乐趣。
我已经编写了一个Android应用程序,它使用Google Play定位服务定期获取位置,并将位置发送到一个Web服务器,该服务器存储在数据库中,可以在Google地图上查看。我已经编写了客户端软件(对于Android、iOS、Windows Phone和JavaME)和服务器软件(对于ASP.NET和SQL & Nbsp;服务器或PHP和MySQL)。软件在每个平台上都是用本机语言编写的,并且在每个平台的后台都能正常工作。最后,该软件具有MIT许可证。您可以在这里找到Android客户端:
https://github.com/nickfox/gpstracker/tree/master/phoneclients/android
你能找到的最简单的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | 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"); } } |
获取位置更新需要很多Android中的boilerplate代码,您需要注意
- Google Play服务可用性检查,
- 如果google play服务旧或不可用,请更新该服务
- 对话创建googleapiclient及其回调连接、断开连接等。
- 停止和释放用于位置更新的资源
- 处理位置权限方案
- 检查位置服务是否打开或关闭
- 获取最新的已知位置也不是那么容易
- 如果在某段时间后未获取位置,则返回到最后一个已知位置
为了简化所有这些步骤,我创建了android easylocation(小型android库),它将处理所有这些东西,您可以专注于业务逻辑。
你所需要的只是延长易感活动和这个
1 | requestSingleLocationFix(easyLocationRequest); |
或
1 | requestLocationUpdates(easyLocationRequest); |
请访问https://github.com/akhgupta/android-easylocation查看所需的示例应用程序和步骤。
locationManager是一个类,它提供内部生成方法以获取最后一个已知位置
STEP 1 :Create a LocationManager Object as below
locationManager locationManager=(locationManager)context.getSystemService(context.locationu service);
STEP 2 : Add Criteria
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | *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
三种是GPS和网络提供商的两种类型
1 | String provider = locationManager.getBestProvider(criteria, true); |
STEP 4: Get Last Know Location
1 | Location location = locationManager.getLastKnownLocation(provider); |
STEP 5: Get Latitude and Longitude
如果location对象为空,则不要尝试调用以下方法
我做了一个项目,从中我们可以使用谷歌播放服务、GPS和网络提供商获得准确的位置。这个项目可以在这里找到。
找到最佳位置的策略是,首先从Google Play Services获取位置如果找到位置,然后检查是否更好,如果找到位置为空,重新启动Google Play Services并尝试从Android位置API获取位置。在变更监听器上注册位置,当找到更好的位置时,回调会将其返回到主活动。
在代码中使用和实现非常简单,只需要嵌入两个类,即
1 2 3 4 5 6 7 8 9 | /** * 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); } |
这是地点经理班
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | 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)); } } } |
我们可以将它与活动或片段一起使用,这里我将它与活动一起使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 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); } } |
希望有帮助,如果你能提出任何改进,请把它贴在Git上。谢谢。
GoogleSamples有使用最新fusedLocationProviderAPI的详细示例。不幸的是,最乐观的答案已经过时了。
按照以下示例使用fusedLocationProviderAPI实现位置服务
https://github.com/googlesamples/android-play-location/tree/master/locationupdates网站
https://github.com/googlesamples/android-play-location/blob/master/locationupdates/app/src/main/java/com/google/android/gms/location/sample/locationupdates/mainactivity.java
对于只是位置检查,您可以使用以下代码。您可以将其放入主活动的onStart()中,如果返回值为false,则显示警报对话框。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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; } |
如果你正在为Android创建新的定位项目,你应该使用新的Google Play定位服务。它更准确,使用更简单。
我已经在一个开源的GPS跟踪器项目gpstracker上工作了几年。我最近更新它来处理定期更新从Android,iOS,Windows手机和Java ME手机。它功能齐全,可以满足您的需要,并拥有麻省理工学院的许可证。
gpstracker中的android项目使用了新的Google Play服务,还有两个服务器堆栈(asp.net和php)允许您跟踪这些电话。
我已经发布了一个小型的库,它可以使在Android中轻松获取位置数据,甚至可以处理Android M运行时权限。
您可以在这里查看它:https://github.com/julioromano/rxlocation,并使用它或它的源代码作为实现的示例。
我用FusedLocationProviderClient得到了非常准确的位置(需要Google Play服务)
Permissions Required
android.permission.access_fine_位置
android.permission.access粗糙位置
Dependency
'com.google.android.gms:play服务位置:15.0.0'
Kotlin Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | val client = FusedLocationProviderClient(this) val location = client.lastLocation location.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) } |
在location方法中简单地查找和写入代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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); } |
我建议使用智能位置库
使用非常简单,它很好地包装了位置逻辑。
启动定位服务:
1 2 | SmartLocation.with(context).location() .start(new OnLocationUpdatedListener() { ... }); |
如果你只想得到一个单一的位置(不是周期性的),你可以使用onfix修饰符。例子:
1 2 3 | SmartLocation.with(context).location() .oneFix() .start(new OnLocationUpdatedListener() { ... }); |
简单而简单的方法,
使用https://github.com/sachinvarma/easylocation获取位置。
第一步:打电话
1 | new EasyLocationInit(MainActivity.this, timeInterval, fastestTimeInterval, runAsBackgroundService); |
timeinterval->set interval(long)(以毫秒为单位)表示-设置要获取位置的间隔。
fastestTimeInterval->setfastestInterval(long)(以毫秒为单位)意味着-如果一个位置可以更快地得到它。(即另一个应用程序正在使用定位服务)。
runasBackgroundService=true->(服务将在后台运行并频繁更新(根据时间间隔和fastestTimeInterval))runasBackgroundService=false->(成功更新位置后服务将被销毁)
步骤2:准备EventBus订阅服务器:声明和注释订阅方法,或者指定线程模式:
如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | @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()); } } } |
这就是全部。
希望将来能帮助别人。