An introduction to GPS in Android

Introduction to this section:

Speaking of the term GPS, I believe everyone is familiar with it. GPS global positioning technology, well, there are generally four positioning methods in Android: GPS positioning, WIFI positioning, base station positioning, and AGPS positioning (base station + GPS);

This series of tutorials only explains the basic use of GPS positioning! GPS obtains the current latitude and longitude of the device by interacting with satellites. The accuracy is high, but there are also some disadvantages. The biggest disadvantage is that it is almost impossible to use indoors ... Need to receive 4 or more satellite signals to ensure accurate GPS positioning ! But if you are outdoors and there is no network, GPS can still be used!

In this section, we will discuss the basic usage of GPS in Android~


1. Some APIs related to positioning


1)LocationManager

Official API documentation: LocationManager

This thing comes from a system service and cannot be directly new. It needs:

LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

In addition, don't forget to add permissions when using GPS positioning:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Ok, after getting the LocationManager object, we can call the following common methods:

  • addGpsStatusListener (GpsStatus.Listener listener): Add a GPS status listener
  • addProximityAlert (double latitude, double longitude, float radius, long expiration, PendingIntent intent): Add a critical warning
  • getAllProviders (): Get a list of all LocationProviders
  • getBestProvider (Criteria criteria, boolean enabledOnly): returns the best LocationProvider according to the specified conditions
  • getGpsStatus (GpsStatus status): Get GPS status
  • getLastKnownLocation (String provider): Get the last known Location according to LocationProvider
  • getProvider (String name): Get the LocationProvider according to the name
  • getProviders (boolean enabledOnly): Get all available LocationProviders
  • getProviders (Criteria criteria, boolean enabledOnly): Get all LocationProviders that meet the conditions according to the specified conditions
  • isProviderEnabled (String provider): Determine whether the LocationProvider with the specified name is available
  • removeGpsStatusListener (GpsStatus.Listener listener): remove the GPS status listener
  • removeProximityAlert (PendingIntent intent): removes a proximity alert
  • requestLocationUpdates (long minTime, float minDistance, Criteria criteria, PendingIntent intent): periodically obtain location information through the specified LocationProvider, and start the corresponding components through Intent
  • requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener): Obtain location information periodically through the specified LocationProvider, and trigger the trigger corresponding to the listener

2) LocationProvider (location provider)

Official API documentation: LocationProvider

This is an abstract representation of the GPS positioning component, and the relevant information of the positioning component can be obtained by calling the following method!

Commonly used methods are as follows:

  • getAccuracy (): returns LocationProvider accuracy
  • getName (): Returns the LocationProvider name
  • getPowerRequirement (): Get the power requirements of LocationProvider
  • hasMonetaryCost (): Returns whether the LocationProvider is charged or free
  • meetsCriteria (Criteria criteria): Determine whether the LocationProvider meets the Criteria conditions
  • requiresCell (): Determine whether the LocationProvider needs to access the network base station
  • requiresNetwork (): Determine whether the LocationProvider needs to access network data
  • requiresSatellite (): Determine whether the LocationProvider needs to access a satellite-based positioning system
  • supportsAltitude (): Determine whether the LocationProvider supports height information
  • supportsBearing (): Determine whether the LocationProvider supports direction information
  • supportsSpeed ​​(): Determine whether the LocationProvider supports speed information

3) Location (location information)

Official API documentation: Location

The abstract class of location information, we can call the following methods to obtain related location information!

Common methods are as follows:

  • float  getAccuracy (): Get the accuracy of positioning information
  • double  getAltitude (): Get the height of the positioning information
  • float  getBearing (): Obtain the direction of positioning information
  • double  getLatitude (): Get the latitude of the positioning information
  • double  getLongitude (): Get the accuracy of positioning information
  • String  getProvider (): Get the LocationProvider that provides the location information
  • float  getSpeed ​​(): Get the speed of positioning information
  • boolean  hasAccuracy (): Determine whether the positioning information contains accuracy information

4) Criteria (filter conditions)

Official API documentation: Criteria

When obtaining the LocationProvider, you can set the filter conditions, which is to set the relevant conditions through this class~

Common methods are as follows:

  • setAccuracy (int accuracy): Set the accuracy requirement for the pair
  • setAltitudeRequired (boolean altitudeRequired): Set whether to require LocationProvider to provide altitude information
  • setBearingRequired (boolean bearingRequired): Set whether to ask LocationProvider to provide direction information
  • setCostAllowed (boolean costAllowed): Set whether to require LocationProvider to provide direction information
  • setPowerRequirement (int level): Set the power consumption required by LocationProvider
  • setSpeedRequired (boolean speedRequired): Set whether to require LocationProvider to provide speed information

2. Get an example of LocationProvider

Running effect diagram :

As can be seen from the figure, there are three currently available LocationProviders, namely:

  • passive : Passively provided, provided by other programs
  • gps : Obtain location information through GPS
  • network : Obtain location information through the network

Implementation code :

Layout file: activity_main.xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获得系统所有的LocationProvider" />

    <Button
        android:id="@+id/btn_two"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Get LocationProvider according to conditions" /> 
        android:id="@+id/btn_three"

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取指定的LocationProvider" />

    <TextView
        android:id="@+id/tv_result"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:background="#81BB4D"
        android:padding="5dp"
        android:textColor="#FFFFFF"
        android:textSize="20sp"
        android:textStyle="bold" />

</LinearLayout>

MainActivity.java:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btn_one;
    private Button btn_two;
    private Button btn_three;
    private TextView tv_result;
    private LocationManager lm;
    private List<String> pNames = new ArrayList<String>(); // 存放LocationProvider名称的集合

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        bindViews();
    }

    private void bindViews() {
        btn_one = (Button) findViewById(R.id.btn_one);
        btn_two = (Button) findViewById(R.id.btn_two);
        btn_three = (Button) findViewById(R.id.btn_three);
        tv_result = (TextView) findViewById(R.id.tv_result);

        btn_one.setOnClickListener(this);
        btn_two.setOnClickListener(this);
        btn_three.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_one:
                pNames.clear();
                pNames = lm.getAllProviders();
                tv_result.setText(getProvider());
                break;
            case R.id.btn_two:
                pNames.clear();
                Criteria criteria = new Criteria(); 
                criteria.setCostAllowed(false); //free 
                criteria.setAltitudeRequired(true); //can provide height information 
                criteria.setBearingRequired(true); //can provide direction information 
                pNames = lm.getProviders( criteria, true); 
                tv_result.setText(getProvider()); 
                break; 
            case R.id.btn_three: 
                pNames.clear(); 
                pNames.add(lm.getProvider(LocationManager.GPS_PROVIDER).getName()); //Specify Name 
                tv_result.setText(getProvider()); 
                break; 
        } 
    }

    //The method of traversing the array and returning the string 
    private String getProvider(){ 
        StringBuilder sb = new StringBuilder(); 
        for (String s : pNames) { 
            sb.append(s + "\n"); 
        } 
        return sb.toString() ; 
    } 
}

3. Two ways to judge whether GPS is turned on and to turn it on

The first thing before we use GPS positioning should be to determine whether the GPS has been turned on or available, otherwise we need to turn on the GPS to complete the positioning! The case of AGPS is not considered here~


1) Determine whether GPS is available

private boolean isGpsAble(LocationManager lm){
    return lm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)?true:false;
}

2) Detect that the GPS is not turned on, turn on the GPS

Method 1 : Force GPS to be turned on, it is useless after Android 5.0....

//强制帮用户打开GPS 5.0以前可用
private void openGPS(Context context){
    Intent gpsIntent = new Intent();
    gpsIntent.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
    gpsIntent.addCategory("android.intent.category.ALTERNATIVE");
    gpsIntent.setData(Uri.parse("custom:3"));
    try {
        PendingIntent.getBroadcast(LocationActivity.this, 0, gpsIntent, 0).send();
    } catch (PendingIntent.CanceledException e) {
        e.printStackTrace();
    }
}

Method 2 : Open the GPS location information setting page and let the user open it by himself

//Open the location information setting page and let the user set up 
private void openGPS2(){ 
    Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
    startActivityForResult(intent,0); 
}

4. Dynamically obtain location information

This is very simple, just call the requestLocationUpdates method to set up a LocationListener to regularly detect the location!

The sample code is as follows:

Layout: activity_location.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_show"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dp"
        android:textSize="20sp"
        android:textStyle="bold" />

</LinearLayout>

LocationActivity.java:

/**
 * Created by Jay on 2015/11/20 0020.
 */
public class LocationActivity extends AppCompatActivity {

    private LocationManager lm;
    private TextView tv_show;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_location);
        tv_show = (TextView) findViewById(R.id.tv_show);
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (!isGpsAble(lm)) {
            Toast.makeText(LocationActivity.this, "请打开GPS~", Toast.LENGTH_SHORT).show();
            openGPS2();
        }
        //从GPS获取最近的定位信息
        Location lc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
        updateShow(lc); 
        //Set an interval of two seconds to obtain GPS location information 
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 8, new LocationListener() { 
            @Override 
            public void onLocationChanged (Location location) { 
                // When the GPS location information changes, update the location 
                updateShow(location); 
            } 

            @Override 
            public void onStatusChanged(String provider, int status, Bundle extras) { 

            } 

            @Override 
            public void onProviderEnabled(String provider) { 
                // When GPS LocationProvider is available, update the location
                updateShow(lm.getLastKnownLocation(provider)); 
            } 

            @Override 
            public void onProviderDisabled(String provider) { 
                updateShow(null); 
            } 
        }); 
    } 


    //Define a method for updating display 
    private void updateShow(Location location) { 
        if (location != null) { 
            StringBuilder sb = new StringBuilder(); 
            sb.append("Current location information:\n"); 
            sb.append("Accuracy: " + location.getLongitude() + "\n"); 
            sb .append("Latitude: " + location.getLatitude() + "\n"); 
            sb.append("Height: " + location.getAltitude() + "\n");
            sb.append("Speed: " + location.getSpeed() + "\n");
            sb.append("Direction: " + location.getBearing() + "\n"); 
            sb.append("Positioning Accuracy: " + location.getAccuracy() + "\n"); 
            tv_show.setText(sb.toString ()); 
        } else tv_show.setText(""); 
    } 


    private boolean isGpsAble(LocationManager lm) { 
        return lm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER) ? true : false; 
    } 


    //Open the settings page for the user Settings 
    private void openGPS2() { 
        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
        startActivityForResult(intent, 0); 
    } 

}

Okay, it’s very simple, because the GPS needs to be used outdoors, so I took this opportunity to trot out to the convenience store to buy a cup of milk tea, and screenshot the picture below~

requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener)

When the time exceeds minTime (unit: milliseconds), or the position moves beyond minDistance (unit: meters), the method in the listener will be called to update the GPS information. It is recommended that the minTime be no less than 60000, that is, 1 minute, which will be more efficient and save power , adding that you need to update the GPS in real time as much as possible, you can set minTime and minDistance to 0

By the way, don't forget, you also need a permission:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

5. Proximity warning (geofencing)

Well, it is to fix a point, and when the distance between the mobile phone and the point is less than the specified range, the corresponding processing can be triggered! Kind of like a geofence...we can call the LocationManager's addProximityAlert method to add proximity alerts! The complete method is as follows:

addProximityAlert(double latitude,double longitude,float radius,long expiration,PendingIntent intent)

Property description:

  • latitude : specifies the longitude of the fixed point
  • longitude : specifies the latitude of the fixed point
  • radius : Specifies the radius length
  • expiration : Specifies how many milliseconds after which the approach warning will expire, -1 means it will never expire
  • intent : This parameter specifies the component that triggers the intent when approaching the fixed point

The sample code is as follows :

ProximityActivity.java

/**
 * Created by Jay on 2015/11/21 0021.
 */
public class ProximityActivity extends AppCompatActivity {
    private LocationManager lm;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_proximity);
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        //定义固定点的经纬度
        double longitude = 113.56843;
        double latitude = 22.374937;
        float radius = 10;     //定义半径,米
        Intent intent = new Intent(this, ProximityReceiver.class);
        PendingIntent pi = PendingIntent.getBroadcast(this, -1, intent, 0);
        lm.addProximityAlert(latitude, longitude, radius, -1, pi);
    }
}

You also need to register a broadcast receiver: ProximityReceiver.java :

/** 
 * Created by Jay on 2015/11/21 0021. 
 */ 
public class ProximityReceiver extends BroadcastReceiver{ 
    @Override 
    public void onReceive(Context context, Intent intent) { 
        boolean isEnter = intent.getBooleanExtra( LocationManager.KEY_PROXIMITY_ ENTERING, false); 
        if(isEnter) Toast.makeText(context, "You have arrived near Building B1 of Nanruan", Toast.LENGTH_LONG).show(); 
        else Toast.makeText(context, "You have left near Building B1 of Nanruan", Toast. LENGTH_LONG). show(); 
    } 
}

Don't forget to register:

<receiver android:name=".ProximityReceiver"/>

Running effect diagram :

PS: Well, I set 10m, but I walked from B1 to D1, it was more than 10m... and it happened to be raining

Guess you like

Origin blog.csdn.net/leyang0910/article/details/132590863