我需要以编程方式使用GPS获取当前位置.我怎样才能实现它?
我创建了一个小型应用程序,逐步描述获取当前位置的GPS坐标.
完整的示例源代码位于获取当前位置坐标,城市名称 - 在Android中.
看看它怎么运作:
我们需要做的就是在清单文件中添加此权限:
并创建一个这样的LocationManager实例:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
检查GPS是否启用.
然后实现LocationListener并获取坐标:
LocationListener locationListener = new MyLocationListener(); locationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
以下是执行此操作的示例代码
/*---------- 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 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) {} }
以下是其他答案的其他信息.
自Android以来
GPS_PROVIDER and NETWORK_PROVIDER
您可以注册到两者并同时onLocationChanged(Location location)
从两个开始获取事件.到现在为止还挺好.现在问题是我们需要两个结果,还是我们应该采取最好的结果.据我所知,GPS_PROVIDER
结果的准确性要高于NETWORK_PROVIDER
.
我们来定义Location
字段:
private Location currentBestLocation = null;
在我们开始听取位置更改之前,我们将实现以下方法.该方法返回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; } }
每当我们检索新位置时,我们都会将其与之前的结果进行比较.
... static final int TWO_MINUTES = 1000 * 60 * 2; ...
我添加一个新方法onLocationChanged
:
@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_PROVIDER or NETWORK_PROVIDER
.
Android中的位置服务概述.
以下是尝试使用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; } }
活动-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
AndroidManifest.xml中
那里已经有很多答案,但我想展示使用Google API获取位置的最新方法,因此新程序员可以使用新方法:
我在我的博客demonuts.com上写了关于android当前位置的详细教程.你也可以找到用android studio开发的完整源代码.
首先,将它放在gradle文件中
compile 'com.google.android.gms:play-services:9.0.2'
然后实现必要的接口
public class MainActivity extends BaseActivitiy implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener
声明实例
private GoogleApiClient mGoogleApiClient; private Location mLocation; private LocationManager locationManager; private LocationRequest mLocationRequest;
把它放进去 onCreate()
mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
最后,重写必要的方法
@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接口.允许我们拥有多种类型的位置跟踪器并轻松插入相应的位置跟踪器:
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或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) { } }
这是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; } } }
由于两者都实现了LocationTracker接口,因此您可以轻松改变您对使用哪个接口的想法.要在轮询模式下运行类,只需调用start().要在更新模式下运行它,请调用start(Listener).
另请查看关于代码的博客文章
获取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); }
你需要使用最新/最新
GoogleApiClient Api
基本上你需要做的是:
private GoogleApiClient mGoogleApiClient; mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build();
然后
@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())); } }
为了最准确和可靠的位置.在这里看我的帖子:
/sf/ask/17360801/
不要使用不准确且响应延迟的LocationListener.说实话,这更容易实现.另请阅读文档:https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient
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位置服务已经存在,我建议开发人员开始使用新的融合位置提供商.您会发现它更容易使用且更准确.请观看两位创建新Google Play位置服务API的人员观看Google I/O视频Beyond the Blue Dot:Android中的新功能.
我一直在许多移动平台上使用位置API,我认为这两个人所做的真的是革命性的.它摆脱了使用各种提供商的大量复杂性.Stack Overflow充斥着关于使用哪个提供商,是否使用最后已知位置,如何在LocationManager上设置其他属性等的问题.他们构建的这个新API消除了大部分不确定性并使位置服务成为愉快的选择.使用.
我编写了一个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
最简单的你可以找到
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"); } }
LocationManager是一个提供构建方法以获取最后知道位置的类
第1步:创建一个LocationManager对象,如下所示
LocationManager locationManager =(LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
第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); }
第3步:获得Avaliable Provider
Threre是两种类型的提供商GPS和网络
String provider = locationManager.getBestProvider(criteria, true);
第4步:获取最后知道的位置
Location location = locationManager.getLastKnownLocation(provider);
第5步:获取纬度和经度
如果定位对象为null,则不要尝试以下方法调用小号
getLatitude and getLongitude is methods which returns double values
获取位置更新需要在Android中使用大量的bolierplate代码,您需要注意
Google Play服务可用性检查,
如果旧版或不可用,请更新Google Play服务
对话创建GoogleApiClient及其回调连接,断开连接等.
停止和释放资源以进行位置更新
处理位置权限方案
检查位置服务是开还是关
获取最后的位置也不是那么容易
如果在一定时间后没有获得位置,则回退到最后已知位置
为了简化所有这些步骤,我创建了Android-EasyLocation(小型android库),它将关注所有这些内容,您可以专注于业务逻辑.
您只需要扩展EasyLocationActivity和它
requestSingleLocationFix(easyLocationRequest);
要么
requestLocationUpdates(easyLocationRequest);
通过https://github.com/akhgupta/Android-EasyLocation查看示例应用程序和步骤
我做了一个项目,我们可以使用Google Play服务,GPS和网络提供商从中获得准确的位置。这个项目可以在这里找到。
寻找最佳位置的策略是:如果找到位置,则首先从Google Play服务获取位置,然后检查天气情况是否好;如果找到的位置为null,则重新启动Google Play服务,并尝试从Android Location API获取位置。在更改侦听器上注册该位置,一旦找到更好的位置,则回调将其返回到主要活动。
仅使用我们需要嵌入的两个类即可在代码中使用和实现,这非常简单,即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); }
这是位置管理器类
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 t
14> karthikdivi..: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