10.14 An Introduction to Android GPS
Category Android Basic Tutorial
Introduction to This Section:
When it comes to the term GPS, everyone should be familiar with it, right? GPS stands for Global Positioning System technology. In Android, there are generally four ways to locate:
- GPS positioning
- WIFI positioning
- Cell tower positioning
- AGPS positioning (Cell tower + GPS)
This series of tutorials only covers the basic usage of GPS positioning! GPS acquires the current latitude and longitude of the device by interacting with satellites, which is quite accurate, but it also has some drawbacks. The biggest drawback is that it is almost unusable indoors ... It requires signals from at least four satellites to ensure accurate positioning with GPS! However, if you are outdoors and without a network, GPS can still be used!
In this section, we will explore the basic usage of GPS in Android~
1. Some APIs Related to Location
1) LocationManager
Official API documentation: LocationManager
This is a system service and cannot be directly instantiated with new. It requires:
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Also, don't forget to add permissions for GPS positioning:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Once you have obtained the LocationManager object, you 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 proximity alert
getAllProviders (): Get a list of all LocationProvider
getBestProvider (Criteria criteria, boolean enabledOnly): Return the best LocationProvider based on specified criteria
getGpsStatus (GpsStatus status): Get GPS status
getLastKnownLocation (String provider): Get the last known location based on LocationProvider
getProvider (String name): Get LocationProvider based on the name
getProviders (boolean enabledOnly): Get all available LocationProvider
getProviders (Criteria criteria, boolean enabledOnly): Get all LocationProviders that meet the specified criteria
isProviderEnabled (String provider): Determine if the specified LocationProvider is available
removeGpsStatusListener (GpsStatus.Listener listener): Remove a GPS status listener
removeProximityAlert (PendingIntent intent): Remove a proximity alert
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 location information through the specified LocationProvider and trigger the listener's corresponding trigger
2) LocationProvider (Location Provider)
Official API documentation: LocationProvider
This is an abstract representation of the GPS positioning component. You can call the following methods to obtain information about the positioning component!
Common methods are as follows:
getAccuracy (): Return the accuracy of LocationProvider
getName (): Return the name of LocationProvider
getPowerRequirement (): Get the power requirement of LocationProvider
hasMonetaryCost (): Return whether the LocationProvider is paid or free
meetsCriteria (Criteria criteria): Determine if LocationProvider meets the Criteria conditions
requiresCell (): Determine if LocationProvider needs to access network cell towers
requiresNetwork (): Determine if LocationProvider needs to access network data
requiresSatellite (): Determine if LocationProvider needs to access satellite-based positioning systems
supportsAltitude (): Determine if LocationProvider supports altitude information
supportsBearing (): Determine if LocationProvider supports direction information
supportsSpeed (): Determine if LocationProvider supports speed information
3) Location (Location Information)
Official API documentation: Location
An abstract class for location information, you can call the following methods to obtain relevant location information!
Common methods are as follows:
float getAccuracy (): Get the accuracy of location information
double getAltitude (): Get the altitude of location information
float getBearing (): Get the direction of location information
double getLatitude (): Get the latitude of 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>(); // Collection to store the names of 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 altitude 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 the name tv_result.setText(getProvider()); break; } }
// Method to traverse the array and return a string private String getProvider(){ StringBuilder sb = new StringBuilder(); for (String s : pNames) { sb.append(s + "\n"); } return sb.toString(); } }
3. Determine if GPS is turned on and two ways to turn on GPS
The first thing we should do before using GPS positioning is to determine whether the GPS is already turned on or available. If it's not turned on, we need to turn on the GPS to complete the positioning! AGPS is not considered here~
1) Determine if GPS is available
private boolean isGpsAble(LocationManager lm){
return lm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER) ? true : false;
}
2) If GPS is not turned on, turn on GPS
Method one: Force to turn on GPS, useless after Android 5.0...
// Force to turn on GPS for users before 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 two: Open the GPS location information settings page and let the user turn it on themselves
// Open the location settings page for the user to set it up 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 a LocationListener to periodically detect the location!
Example 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 (
updateShow(lm.getLastKnownLocation(provider));
}
@Override
public void onProviderDisabled(String provider) {
updateShow(null);
}
});
}
//Define a method to update the display
private void updateShow(Location location) {
if (location != null) {
StringBuilder sb = new StringBuilder();
sb.append("Current location information:\n");
sb.append("Longitude: " + location.getLongitude() + "\n");
sb.append("Latitude: " + location.getLatitude() + "\n");
sb.append("Altitude: " + location.getAltitude() + "\n");
sb.append("Speed: " + location.getSpeed() + "\n");
sb.append("Bearing: " + location.getBearing() + "\n");
sb.append("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 to set up themselves
private void openGPS2() {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivityForResult(intent, 0);
}
}
Well, it's very simple. Since GPS needs to be used outdoors, I took the opportunity to run out to the convenience store and buy a cup of milk tea, and took a screenshot on the way~
requestLocationUpdates (String provider, long minTime, float minDistance, LocationListener listener)
When the time exceeds minTime (unit: milliseconds), or the position moves more than minDistance (unit: meters), the method in the listener will be called to update the GPS information. It is recommended that this minTime is not less than 60000, that is, 1 minute, which will be more efficient and power-saving. If you need to update the GPS as close to real-time 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 Alert (Geo-fencing)
Well, it's about fixing a point, and when the distance between the phone and that point is less than the specified range, the corresponding processing can be triggered! It's a bit like a geo-fence... 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)
Property description:
-latitude : The longitude of the specified fixed point
-longitude : The latitude of the specified fixed point
-radius : The specified radius length
-expiration : The specified proximity alert will expire after this many milliseconds, -1 means never expire
-intent : This parameter specifies the component corresponding to the intent that is triggered when approaching the fixed point
Example 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);
//Define the fixed point's longitude and latitude
double longitude = 113.56843;
double latitude = 22.374937;
float radius = 10; //Define the radius in meters
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 the South Soft B1 building", Toast.LENGTH_LONG).show();
else Toast.makeText(context, "You have left the vicinity of the South Soft B1 building", Toast.LENGTH_LONG).show();
}
}
Don't forget to register:
<receiver android:name=".ProximityReceiver"/>
Running effect picture :
PS: Well, I set
2.5.4 Basic Usage of AutoCompleteTextView (Auto-Complete Text Field)
2.5.8 Detailed Explanation of Notification (Status Bar Notification)
2.6.4 Simple Usage of DrawerLayout (Official Side-Slide Menu)
3.6 Responding to System Setting Events (Configuration Class)
[4.2.3 Mastering Service]
8.3.4 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part One)
8.3.5 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part Two)
8.3.6 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part Three)
8.3.7 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part Four)
8.3.8 Paint API - Detailed Explanation of Xfermode and PorterDuff (Part Five)
8.3.14 Paint Several Enum/Constant Values and ShadowLayer Shadow Effect
8.3.17 Detailed Explanation of Canvas API (Part 2) - Collection of Clipping Methods
8.3.18 Detailed Explanation of Canvas API (Part 3) - Matrix and drawBitmapMesh
8.4.3 Android Animation Collection - Property Animation - First Encounter
8.4.4 Android Animation Collection - Property Animation - Revisit
[10.4