如何从 Gps 切换到网络提供商?

How to switch from Gps to network provider?

需要一些帮助。我正在制作一个应用程序,我可以从 gps 或网络提供商那里获取位置更新。如果没有启用 gps,那么我给出了启用 gps 的按钮。现在我需要做的是从 gps 获取更新,如果 gps 无法获得信号,那么我切换到网络提供商并进行位置更新,一旦 gps 可用,再次切换到 gps 并计算距离用户已经旅行。我有多个问题。

What does the getProvider and getBestProvider methods do? I think it provides the best provider that is available to the phone (correct me if i am wrong) and how can i use it to get location updates.

I need to know what providers are enabled when the user launches the app. How can i do that? I used isProviderEnabled but got confused when enabling or disabling the wifi it gives me nothing.

I tried some conditions if gps not enabled then switch to network provider but this doesn't do anything. I read many posts regarding this but couldn't figure out how to use it in my code. Any help would be greatly appreciated. Thanks. Here is my code.

public class MainActivity extends Activity {
public boolean getLocation() {

    try {
        isGps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch (Exception ex) {
    }
    try {
        isNetwork_enabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch (Exception ex) {
    }

    //don't start listeners if no provider is enabled
    if (!isGps_enabled && !isNetwork_enabled)
        return false;

    if (isGps_enabled)
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
    if (isNetwork_enabled)
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
    return true;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    accu = (TextView) findViewById(R.id.accu);
    speed1 = (TextView)findViewById(R.id.speed);
    t = (TextView)findViewById(R.id.t);
    prevLatLon = (TextView) findViewById(R.id.prevLatLon);
    distance = (TextView)findViewById(R.id.distance);
    listView = (ListView)findViewById(R.id.listView);
    listText = (TextView)findViewById(R.id.listText);
    settings = (Button)findViewById(R.id.settings_button);
    settings.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
        }
    });

    locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    List<String> providers = locationManager.getProviders(criteria, true);
    for (String provider: providers){
        distance.setText("Providers: " + provider);
    }
    provider = locationManager.getBestProvider(criteria, false);

    /*isGps_enabled = locationManager.isProviderEnabled(provider);
    Toast.makeText(this, isGps_enabled + "", Toast.LENGTH_SHORT).show();

    isNetwork_enabled = locationManager.isProviderEnabled(provider);
    Toast.makeText(this, isNetwork_enabled + "", Toast.LENGTH_SHORT).show();*/

    locationListener = new LocationListener() {

        @Override
        public void onLocationChanged(Location loc) {
            //locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

            getLocation();
            int accuracy = (int) loc.getAccuracy();
            speed = (int) loc.getSpeed();

            accu.setText("Accuracy: " + accuracy);
            speed1.setText("Speed: " + speed);
            t.setText("Time: " + loc.getTime());

            listView.setAdapter(new ArrayAdapter<String>(MainActivity.this, R.layout.activity_simplelist, R.id.listText, list));

            DateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
            Date date = new Date(loc.getTime());
            String formatted = format.format(date);

            if (flag == 0) {
                latitude = loc.getLatitude();
                longitude = loc.getLongitude();
                speed = (int) loc.getSpeed();
                time = formatted;
                distanceInMeters = 0;
                distanceTo = 0;
                distanceBetween = 0;
                timestamp = loc.getTime();
                timestampmsec = 0;
                hours = 0;
                minutes = 0;
                seconds = 0;
                startTime = loc.getTime();

                flag = 1;
                list.add("latitude: " + latitude + " longitude: " + longitude +
                        " \nspeed: " + speed + " Time: " + time + "\nDistance: " + distanceInMeters + " meters"
                        + "\ntimestamp: " + timestamp);
            }

            else {
                prevLatitude = latitude;
                prevLongitude = longitude;
                prevSpeed = speed;
                prevTime = time;
                prevDistanceInMeters = distanceInMeters;
                prevDistanceTo = distanceTo;
                prevDistanceBetween = distanceBetween;
                //prevTimestamp = timestamp;
                prevTimestampmsec = timestampmsec;
                prevHours = hours;
                prevMinutes = minutes;
                prevSeconds = seconds;

                prevLatLon.setText("Previous Latitude: " + prevLatitude + "\nPrevious Longitude: " + prevLongitude +
                        " \nPrevious speed: " + prevSpeed + " \nTime: " + prevTime + "\nPrevious Timestamp: " + prevTimestamp);

                latitude = loc.getLatitude();
                longitude = loc.getLongitude();
                speed = (int) loc.getSpeed();
                time = formatted;
                timestamp = loc.getTime();

                if (loc.hasSpeed()) {
                    Toast.makeText(MainActivity.this, "true", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "false", Toast.LENGTH_SHORT).show();
                }

                getDistance();
                distanceTo = androidDistanceTo(prevLatitude, prevLongitude, latitude, longitude);
                Location.distanceBetween(prevLatitude, prevLongitude, latitude, longitude, results);
                distanceBetween = results[0];

                list.add("latitude: " + latitude + " longitude: " + longitude +
                        " \nspeed: " + speed + " Time: " + time + "\nDistance: " + distanceInMeters + " meters"
                        + "\nTimestamp: " + timestamp);

                speed = prevSpeed + speed;
                distanceInMeters = prevDistanceInMeters + distanceInMeters;
                distanceTo = prevDistanceTo + distanceTo;
                distanceBetween = prevDistanceBetween + distanceBetween;

                timestampmsec = (long) (timestamp - startTime);
                seconds = TimeUnit.MILLISECONDS.toSeconds(timestampmsec);

                if(seconds >= 60) {
                    minutes = (int) seconds / 60;
                    seconds = seconds % 60;
                }

                if(minutes >= 60){
                    hours = (int) minutes / 60;
                    minutes = minutes % 60;
                }

            }

            distance.setText("Distance: " + distanceInMeters + " meters" + "\nDistanceTo: " + distanceTo + " meters" +
                    "\nDistanceBetween: " + distanceBetween + " meters" + "\nTime: " + hours + " hours " +
                    minutes + " minutes " + seconds + " seconds");

            Toast.makeText(MainActivity.this, "Location Changed", Toast.LENGTH_SHORT).show();

        }

        @Override
        public void onProviderDisabled(String arg0) {
            //TODO auto generated method stub
            Toast.makeText(MainActivity.this, provider + " disabled", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onProviderEnabled(String arg0) {
            //TODO auto generated method stub
            Toast.makeText(MainActivity.this, provider + " enabled", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
            //TODO auto generated method stub
        }
    };
}

public void getDistance(){
    double dLat = Math.toRadians(latitude - prevLatitude);
    double dLon = Math.toRadians(longitude - prevLongitude);
    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
            + Math.cos(Math.toRadians(prevLatitude))
            * Math.cos(Math.toRadians(latitude)) * Math.sin(dLon / 2)
            * Math.sin(dLon / 2);
    double c = 2 * Math.asin(Math.sqrt(a));
    distanceInMeters = (6372800 * c);
}

public static double androidDistanceTo(double lat_a, double lng_a, double lat_b, double lng_b) {
    Location locationA = new Location("Point A");
    locationA.setLatitude(lat_a);
    locationA.setLongitude(lng_a);

    Location locationB = new Location("Point B");
    locationB.setLatitude(lat_b);
    locationB.setLongitude(lng_b);

    return (locationA.distanceTo(locationB));
}

public void resetButton(View view) {
    list.clear();
    listView.setAdapter(new ArrayAdapter<String>(MainActivity.this, R.layout.activity_simplelist, R.id.listText, list));
}

@Override
protected void onResume() {
    super.onResume();
    locationManager.requestLocationUpdates(provider, 30000, 0, locationListener);
}

@Override
protected void onPause() {
    super.onPause();
    //locationManager.removeUpdates(locationListener);
} 

getBestProvider 执行以下操作:

Returns the name of the provider that best meets the given criteria. Only providers that are permitted to be accessed by the calling activity will be returned. If several providers meet the criteria, the one with the best accuracy is returned. If no provider meets the criteria, the criteria are loosened in the following sequence: power requirement, accuracy, bearing, speed, altitude

getProvider 执行以下操作:

Returns the information associated with the location provider of the given name, or null if no provider exists by that name.

通俗地说,您选择 getProvider 的提供商,系统选择 getBestProvider

的提供商

您可以通过查看 isProviderEnabled

了解启用了哪些提供商

您启动侦听器的代码看起来不错。但是你实际上并没有在 onResume()onLocationChanged() 以外的任何地方调用 getLocation() 你需要将该调用移出 onLocationChanged() 并将其放在 [=16= 的末尾]