First experience with Android GPS


Introduction to this section:

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

This series of tutorials only explains the basic use of GPS positioning! GPS obtains the device's current longitude and latitude accurately by interacting with satellites. The degree is relatively high, but there are also some disadvantages. The biggest disadvantage is: It is almost impossible to use indoors...needs to receive 4 satellites or more The signal can ensure the accurate positioning of GPS! 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 document:

LocationManager

This thing comes from the system service and cannot be directly new. It requires:

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"/>

Okay, after obtaining 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 the list of all LocationProviders
  • getBestProvider(Criteria criteria, boolean enabledOnly): Return according to the specified conditions Optimal LocationProvider
  • getGpsStatus(GpsStatus status): Get the GPS status
  • getLastKnownLocation(String provider): Get the last known location based on LocationProvider Location
  • getProvider(String name): Get LocationProvider
  • getProviders(boolean enabledOnly): Get all available LocationProvider
  • getProviders(Criteria criteria, boolean enabledOnly): Get all LocationProviders that meet the conditions based on the specified conditions
  • isProviderEnabled(String provider): Determine the LocationProvider with the specified name Is it available
  • removeGpsStatusListener(GpsStatus.Listener listener): Remove the GPS status listener
  • removeProximityAlert(PendingIntent intent): Remove a proximity warning
  • requestLocationUpdates(long minTime, float minDistance, Criteria criteria, PendingIntent intent): Periodically obtain location information through the specified LocationProvider, and start the corresponding component through Intent
  • requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener): Periodically obtain positioning information through the specified LocationProvider and trigger the trigger corresponding to the listener

2) LocationProvider (location provider)

Official API document: LocationProvider

This is an abstract representation of the GPS positioning component. Call the following method to obtain relevant information about the positioning component!

Commonly used methods are as follows:

  • getAccuracy(): Returns the LocationProvider accuracy
  • getName(): Returns the LocationProvider name
  • getPowerRequirement(): Get the power requirements of the LocationProvider
  • hasMonetaryCost(): Return whether the LocationProvider is paid 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 the satellite-based positioning system
  • supportsAltitude(): Determine whether the LocationProvider supports altitude Information
  • supportsBearing(): Determine whether the LocationProvider supports direction information
  • supportsSpeed(): Determine whether the LocationProvider supports speed information

3) Location (location information)

Official API document: Location

Abstract class of location information, We can call the following method to obtain relevant positioning information!

Commonly used methods are as follows:

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

4) Criteria (filter conditions)

Official API documentation: Criteria

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

Common methods are as follows:

  • setAccuracy(int accuracy): Set the accuracy requirement
  • setAltitudeRequired(boolean altitudeRequired): Set whether the LocationProvider is required to provide altitude information
  • setBearingRequired(boolean bearingRequired): Set whether the LocationProvider is required to provide direction information
  • setCostAllowed(boolean costAllowed): Set whether the LocationProvider is required to be able to provide direction information Provide direction information
  • setPowerRequirement(int level): Set the required power consumption of LocationProvider
  • setSpeedRequired(boolean speedRequired): Set whether to require LocationProvider Can provide speed information

2. Get LocationProvider example

Running renderings:

1.gif

As you can see from the picture, there are three currently available LocationProviders, which are:

  • passive: passively provided, provided by other programs
  • gps: Obtain positioning information through GPS
  • network: Obtain positioning 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="根据条件获取LocationProvider" />

    <Button
        android:id="@+id/btn_three"
        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 pNames = new ArrayList(); // 存放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);   //免费
                criteria.setAltitudeRequired(true);  //能够提供高度信息
                criteria.setBearingRequired(true);   //能够提供方向信息
                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()); //指定名称
                tv_result.setText(getProvider());
                break;
        }
    }

    //遍历数组返回字符串的方法
    private String getProvider(){
        StringBuilder sb = new StringBuilder();
        for (String s : pNames) {
            sb.append(s + "\n");
        }
        return sb.toString();
    }
}

3. Determine whether GPS is turned on and the two conditions for turning on GPS This method

The first thing before we use GPS positioning should be to determine whether the GPS has been turned on or available. If it is not turned on, we need to Turn on GPS to complete positioning! 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 GPS is not turned on, turn it on GPS

Method 1: Force open GPS, 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 GPS location The information setting page allows users to open it by themselves

//打开位置信息设置页面让用户自己设置
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 detect the location regularly!

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);
        //设置间隔两秒获得一次GPS定位信息
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 8, new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                // 当GPS定位信息发生改变时,更新定位
                updateShow(location);
            }

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

            }

            @Override
            public void onProviderEnabled(String provider) {
                // 当GPS LocationProvider可用时,更新定位
                updateShow(lm.getLastKnownLocation(provider));
            }

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


    //定义一个更新显示的方法
    private void updateShow(Location location) {
        if (location != null) {
            StringBuilder sb = new StringBuilder();
            sb.append("当前的位置信息:\n");
            sb.append("精度:" + location.getLongitude() + "\n");
            sb.append("纬度:" + location.getLatitude() + "\n");
            sb.append("高度:" + location.getAltitude() + "\n");
            sb.append("速度:" + location.getSpeed() + "\n");
            sb.append("方向:" + location.getBearing() + "\n");
            sb.append("定位精度:" + 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;
    }


    //打开设置页面让用户自己设置
    private void openGPS2() {
        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        startActivityForResult(intent, 0);
    }

}

Okay, very Simple, because GPS needs to be used outdoors, so I took this opportunity to run out to the convenience store and buy a cup of milk tea. Take the screenshot below~

2.png3..png

4.png

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

When the time exceeds minTime (unit: milliseconds), or the position moves exceeds minDistance (unit: meters), the method in the listener will be called to update the GPS information. It is recommended that the minTime be not less than 60000, which is 1 minute, which will be more efficient. And save power, add as much as you need To update the GPS in real time, 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 (geofence) )

Well, it means fixing a point. 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 geofencing... we can call the LocationManager's addProximityAlert method to add a proximity alert! The complete method is as follows:

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

Attribute description:

  • latitude: Specify the longitude of the fixed point
  • longitude: Specify the latitude of the fixed point
  • radius: Specify the radius length
  • expiration: Specifies the number of milliseconds after which the approaching warning will expire. -1 means it will never expire.
  • intent: This parameter specifies Trigger the component corresponding to 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, "你已到达南软B1栋附近", Toast.LENGTH_LONG).show();
        else Toast.makeText(context, "你已离开南软B1栋附近", Toast.LENGTH_LONG).show();
    }
}

Don’t forget to register:

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

Running renderings:

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

6.png 6.png


6. Download the sample code of this section

GPSDemo.zip


Summary of this section:

Okay, this section introduces you to some basic usage of GPS positioning in Android. It is very simple. Please refer to the content part. Teacher Li Gang's "Android Crazy Lecture Notes" just made some modifications to the examples and conducted usability tests! That’s it for this section, thank you~6.jpg