如何借助编程进行GPS定位?

阅读 5k
1 个回答

答: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。

@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);
}

....
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题