我想要进行GPS定位,如何借助编程,完成这个操作?
原问题:How do I get the current GPS location programmatically in Android?
解决方案
答:CommonsWare
(最佳答案)
网上很多的教程都已经过时了,你可以在我的书中下载相关源码,找到Internet/Weather和Service/WeatherPlus的demo,然后使用LocationManager。或者你可以在我的另一本书中,根据23-Location的教程指引,使用LocationManager。
不过,因为GPS需要花费一段时间才能成功安装,所以目前,你也只能通过Android系统进行定位。否则,你只有通过位置升级,或者利用类似的pattern才能完成这个操作。
答:RDC
我创建了一个简易的应用,来完成GPS的相关定位。
以下是全部源码的URL地址
Get Current Location coordinates , City name - in Android
首先,我们需要在manifest文件中添加许可,
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
然后创建如下LocationManager的实例:
1
2
LocationManager locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
检查GPS能否正常工作
然后执行LocationListener和Get Coordinates
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<Address> addresses; try { addresses = gcd.getFromLocation(loc.getLatitude(), loc.getLongitude(), 1); if (addresses.size() > 0) System.out.println(addresses.get(0).getLocality()); cityName = addresses.get(0).getLocality(); } catch (IOException e) { e.printStackTrace(); } String s = longitude + "\n" + latitude + "\n\nMy Current City is: " + cityName; editLocation.setText(s); } @Override public void onProviderDisabled(String provider) {} @Override public void onProviderEnabled(String provider) {} @Override public void onStatusChanged(String provider, int status, Bundle extras) {}}
答:Maxim Shoustin
我的方法与以上几位的回答不同,因为Android自带:
GPS_PROVIDER 和 NETWORK_PROVIDER
你可以两个都注册,然后同时启动GPS_PROVIDER和NETWORK_PROVIDER中的onLocationChanged(Location location)。
然后我们可以从两个结果中择优处理,不难发现,NETWORK PROVIDER的定位结果要比GPS更加精确。
下面来定义Location field:
private Location currentBestLocation = null;
下述的方法可以说是介于GPS和Network中,但还是推荐一试,
/** * @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中添加了一种新的method。
@overridepublic void onLocationChanged(Location location) { makeUseOfNewLocation(location); if(currentBestLocation == null){ currentBestLocation = location; } .... }/** * This method modify the last know good location according to the arguments. * * @param location the possible new location */void makeUseOfNewLocation(Location location) { if ( isBetterLocation(location, currentBestLocation) ) { currentBestLocation = location; }}.... /** Determines whether one Location reading is better than the current Location fix * @param location The new Location that you want to evaluate * @param currentBestLocation The current Location fix, to which you want to compare the new one */protected boolean isBetterLocation(Location location, Location currentBestLocation) { if (currentBestLocation == null) { // A new location is always better than no location return true; } // Check whether the new location fix is newer or older long timeDelta = location.getTime() - currentBestLocation.getTime(); boolean isSignificantlyNewer = timeDelta > TWO_MINUTES; boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; boolean isNewer = timeDelta > 0; // If it's been more than two minutes since the current location, use the new location // because the user has likely moved if (isSignificantlyNewer) { return true; // If the new location is more than two minutes older, it must be worse } else if (isSignificantlyOlder) { return false; } // Check whether the new location fix is more or less accurate int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy()); boolean isLessAccurate = accuracyDelta > 0; boolean isMoreAccurate = accuracyDelta < 0; boolean isSignificantlyLessAccurate = accuracyDelta > 200; // Check if the old and new location are from the same provider boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider()); // Determine location quality using a combination of timeliness and accuracy if (isMoreAccurate) { return true; } else if (isNewer && !isLessAccurate) { return true; } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { return true; } return false;}/** Checks whether two providers are the same */private boolean isSameProvider(String provider1, String provider2) { if (provider1 == null) { return provider2 == null; } return provider1.equals(provider2);}....