The realization of android positioning

http://developer.android.com/guide/topics/location/strategies.html

 

There are only two kinds of positioning based on android: network and gps. Both have their pros and cons.

Network: Fast positioning, low accuracy, and little environmental impact.

GPS: The positioning is slow, the accuracy is high, and it is greatly affected by the environment.

 

The problem to be solved in this article:

1. The locationManager.getLastKnownLocation method returns null.

2. How to achieve fast and precise positioning.

 

If the E text is good, just look at the official website http://developer.android.com/guide/topics/location/strategies.html

 

If you have such code in your program, you should pay attention (it seems that these are redundant now)

[java] view plaincopy

Criteria criteria = new Criteria();  

        criteria.setAccuracy(Criteria.ACCURACY_FINE);//高精度  

        criteria.setAltitudeRequired(false);//No altitude requirement  

        criteria.setBearingRequired(false);//No bearing requirement  

        criteria.setCostAllowed(true);//Allow charges to be generated  

        criteria.setPowerRequirement(Criteria.POWER_LOW);//Low power consumption  

        

        // Get the best service object  

        String provider = locationManager.getBestProvider(criteria,true);  

locationManager.getLastKnownLocation(provider);  

 

The locationManager.getBestProvider(criteria,true); method looks perfect, but in fact the return value is either network or gps. And if you require high accuracy, it will check GPS first, if the phone has GPS turned on, it will return to GPS, otherwise it will return to network. Returns null if none are enabled.

Combining the advantages and disadvantages of the two positioning methods of Network and GPS, it is not difficult to see why the getLastKnownLocation method returns null (this is only for the first positioning).

 

When you turn on GPS, the value of provider is GPS. The positioning method at this time is GPS. Because GPS positioning is slow (the time I tested is about 50 seconds), it is impossible to return you a Location object immediately, so it returns null. Others have solved this problem with:

[java] view plaincopy

while (location ==null) {  

       location = locationManager.getLastKnownLocation(provider);  

   }  

 

This is absolutely stupid! For example: if you are indoors and the GPS cannot locate it, your program will be stuck in an infinite loop. Of course, using requestLocationUpdates can achieve positioning without letting the program fall into an infinite loop, but the positioning takes a long time, and even the positioning is not obtained.

If you use network positioning, it must be said that this is also a good choice. locationManager.requestLocationUpdates(

              LocationManager.NETWORK_PROVIDER, 0, 0,networkListener);

The network positioning time is generally about 2 seconds (the network is poor, the time will be longer), as long as you connect to the network, you can basically get the positioning. The only downside is that the accuracy is not high.

 

Whether it can combine the two is also the focus of this article. Since combining the two, it is necessary to add monitoring for both at the same time

[java] view plaincopy

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000 * 2,50,gpsListener);  

locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0,networkListener);  

 

In this way, we can get the location from the network in about 2 seconds, and get the location from the GPS in a minute. At this time, it is good to replace the network positioning with GPS positioning. Of course this is only an ideal situation, the reality is much more complicated.

for example:

Your first location successfully returns location, and the second time returns null due to network problems. At this time, it will be found that the updated location is not as accurate as the last time, or even null, and cannot be used. At this time, we need to judge the current location and the newly obtained location which is better. Maybe after you obtain the GPS location, the GPS server is lost due to weather, entering a tunnel, etc., and the location cannot be updated (a good practice at this time is to switch to the network location). It is also possible that the user does not turn on GPS and network, and there is no positioning at all (in fact, every time the positioning is successful, there will be a positioning cache, which can be obtained using getLastKnownLocation).

 

In conclusion, all we have to do is:

1. Try to get the last location information through getLastKnownLocation

2. Enable network and gps monitoring

3. Obtain network location information location

4. Compare the current location and the newly acquired location which is better (from network)

5. Get GPS location information

6. Stop network monitoring

7. Compare the current location and the newly acquired location which is better (from gps)

8. If the gps server is lost, restart the network monitoring

 

Take GPS monitoring as an example

[java] view plaincopy

// Callback function for GPS monitoring  

 private class GPSLocationListener implements LocationListener {  

  

    private boolean isRemove = false;//Determine whether network monitoring is removed  

  

    @Override  

    public void onLocationChanged(Location location) {  

        // TODO Auto-generatedmethod stub  

        boolean flag =betterLocation.isBetterLocation(location,  

               currentBestLocation);  

  

        if (flag) {  

           currentBestLocation = location;  

           updateLocation(currentBestLocation);  

        }  

        // After getting the GPS service, remove the network monitor  

        if (location !=null && !isRemove) {  

           locationManager.removeUpdates(networkListener);  

           isRemove = true;  

        }  

    }  

  

    @Override  

    public void onProviderDisabled(String provider) {  

        // TODO Auto-generatedmethod stub  

    }  

  

    @Override  

    public void onProviderEnabled(String provider) {  

        // TODO Auto-generatedmethod stub  

    }  

  

    @Override  

    public void onStatusChanged(String provider, int status, Bundleextras) {  

        // TODO Auto-generatedmethod stub  

        if (LocationProvider.OUT_OF_SERVICE == status) {  

           Toast.makeText(MainActivity.this, "GPS service lost, switch to network positioning",  

                  Toast.LENGTH_SHORT).show();  

           locationManager  

                  .requestLocationUpdates(  

                         LocationManager.NETWORK_PROVIDER, 0, 0,  

                         networkListener);  

        }  

    }  

 }  

 

Where isBetterLocation is used to determine which location is better. This method comes from the android official website, and is judged by the time, accuracy and other information obtained by the location.

Because the demo uploaded before, everyone thinks it is of little significance, so it is no longer provided.

The unit of 'microseconds' in the picture below is wrong, it should be milliseconds

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326688814&siteId=291194637