Lesson 138. Positioning. GPS coordinates.

Lesson 138. Positioning. GPS coordinates.


In this lesson:

– we receive location data

Android devices can provide us with data on our current location. It is, of course, very convenient and is strongly used for, for example, using a card, getting relevant information for your locality (weather forecast), all kinds of Chekin and more.

The implementation of this is quite simple. We hang the listener on the provider and receive the data. There are currently two providers: GPS and Network.

GPS – everything is clear here, it’s data from GPS satellites.

Networks are coordinates that can be obtained via cellular or WiFi. This provider requires an Internet connection.

Let’s write a simple application that will query and display coordinates.

Let’s create a project:

Project name: P1381_Location
Build Target: Android 2.3.3
Application name: Location
Package name: en.startandroid.develop.p1381location
Create Activity: MainActivity

IN strings.xml add rows:

GPS
Network
Location settings

screen main.xml:



    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

A few TextViews that we’ll output data to and a button to open the location settings.

MainActivity.java:

package ru.startandroid.develop.p1381location;

import java.util.Date;

import android.app.Activity;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {

  TextView tvEnabledGPS;
  TextView tvStatusGPS;
  TextView tvLocationGPS;
  TextView tvEnabledNet;
  TextView tvStatusNet;
  TextView tvLocationNet;

  private LocationManager locationManager;
  StringBuilder sbGPS = new StringBuilder();
  StringBuilder sbNet = new StringBuilder();

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    tvEnabledGPS = (TextView) findViewById(R.id.tvEnabledGPS);
    tvStatusGPS = (TextView) findViewById(R.id.tvStatusGPS);
    tvLocationGPS = (TextView) findViewById(R.id.tvLocationGPS);
    tvEnabledNet = (TextView) findViewById(R.id.tvEnabledNet);
    tvStatusNet = (TextView) findViewById(R.id.tvStatusNet);
    tvLocationNet = (TextView) findViewById(R.id.tvLocationNet);

    locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
  }

  @Override
  protected void onResume() {
    super.onResume();
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
        1000 * 10, 10, locationListener);
    locationManager.requestLocationUpdates(
        LocationManager.NETWORK_PROVIDER, 1000 * 10, 10,
        locationListener);
    checkEnabled();
  }

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

  private LocationListener locationListener = new LocationListener() {

    @Override
    public void onLocationChanged(Location location) {
      showLocation(location);
    }

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

    @Override
    public void onProviderEnabled(String provider) {
      checkEnabled();
      showLocation(locationManager.getLastKnownLocation(provider));
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
      if (provider.equals(LocationManager.GPS_PROVIDER)) {
        tvStatusGPS.setText("Status: " + String.valueOf(status));
      } else if (provider.equals(LocationManager.NETWORK_PROVIDER)) {
        tvStatusNet.setText("Status: " + String.valueOf(status));
      }
    }
  };

  private void showLocation(Location location) {
    if (location == null)
      return;
    if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) {
      tvLocationGPS.setText(formatLocation(location));
    } else if (location.getProvider().equals(
        LocationManager.NETWORK_PROVIDER)) {
      tvLocationNet.setText(formatLocation(location));
    }
  }

  private String formatLocation(Location location) {
    if (location == null)
      return "";
    return String.format(
        "Coordinates: lat = %1$.4f, lon = %2$.4f, time = %3$tF %3$tT",
        location.getLatitude(), location.getLongitude(), new Date(
            location.getTime()));
  }

  private void checkEnabled() {
    tvEnabledGPS.setText("Enabled: "
        + locationManager
            .isProviderEnabled(LocationManager.GPS_PROVIDER));
    tvEnabledNet.setText("Enabled: "
        + locationManager
            .isProviderEnabled(LocationManager.NETWORK_PROVIDER));
  }

  public void onClickLocationSettings(View view) {
    startActivity(new Intent(
        android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
  };

}

IN onCreate we define TextView components and get LocationManager, through which we will work.

IN onResume we hang the listener using requestLocationUpdates. At the entrance we pass:

– Provider type: GPS_PROVIDER or NETWORK_PROVIDER
– minimum time (in milliseconds) between data acquisition. I will point here 10 seconds, I will be enough. If you want to get coordinates without delay, send 0. But keep in mind that this is only a minimum time. The real wait may be longer.
– minimum distance (in meters). That is, if your location has changed by the specified number of meters, you will receive new coordinates.
– listener, the locationListener object, which we will consider below

Also here we update on-screen information about provider involvement.

IN onPause disconnect the listener using the removeUpdates method.

locationListener – The listener implements the LocationListener interface with the following methods:

onLocationChanged – New location data, Location object. This is where we call our showLocation method, which will display location information on the screen.

onProviderDisabled – The specified provider has been disabled by the user. In this method, we call our checkEnabled method, which updates the current ISP statuses on the screen.

onProviderEnabled – The specified provider was enabled by the user. We also call checkEnabled here. Then, using the getLastKnownLocation method (it can return null), we request the last available placement from the included provider and display it. It may be quite relevant if you have previously used any location-based application.

onStatusChanged – The status of the specified provider has changed. The status field can be OUT_OF_SERVICE (data will be unavailable for a long time), TEMPORARILY_UNAVAILABLE (data is temporarily unavailable), AVAILABLE (all ok, data are available). In this method, we simply display the new status on the screen.

Providers switch on and off in system settings. Thus, it is simply determined by the presence of a certain provider to obtain coordinates from him. Later we will see how you can send the user to these settings. Software on / off providers through standard methods are not available.

The following are their methods.

showLocation it takes Location, identifies its provider with the getProvider method, and displays the coordinates in the corresponding text box.

formatLocation takes Location, reads data from it, and formats a string. What data does it take: getLatitude – latitude, getLongitude – longitude, getTime – determination time.

checkEnabled identifies providers on or off by the isProviderEnabled method and displays this info on the screen.

method onClickLocationSettings triggers when you click the Location settings button and opens the settings so that the user can turn on or off the provider. To do this, use Intent with action = ACTION_LOCATION_SOURCE_SETTINGS.

It remains to declare ACCESS_FINE_LOCATION coordinate permission to allow us to use both Network and GPS. ACCESS_COARSE_LOCATION permission is also available, but it only gives access to the network provider.

With the code everything, let’s see what happened. We all save and launch the application.

My tablet now has GPS turned off, WiFi turned off, seven inserted, and mobile internet turned off.

I launch the application and see the following picture:

GPS off, Network on. But the internet is gone, so Network gives me nothing. You need to turn on either mobile internet or WiFi.

I turn on WiFi. It takes 15-20 seconds and the info from Network is gone

We see latitude, longitude and time.

Recall that we set a minimum recovery rate of 10 seconds. But my Network Provider gives out data no more than once a minute.

Now let’s turn on GPS. To do this, we specifically hung the Location settings button, which the user will have to click to go to the settings. Click the button.

We see that GPS is off and Network is on. Our app showed everything right.

Of course, GPS can be switched on and off via the quick system setup (top right). But not all users are aware of this. And here we will send them exactly.

We turn on GPS and press Back to return to the application.

GPS now shows that it is on, waiting for coordinates. It makes sense to go to the window, more likely to catch the signal.

As a result, the signal is caught and the result obtained.

Status 2 (AVAILABLE) switched on to GPS after a while.

And in Network silence with status. I don’t know if it’s okay or not.

If everything is ok with the GPS signal, you will receive location information every 10 seconds. If you remove the tablet from the window, we get a bad signal: the data may come less often and my status sometimes changes to 1 (TEMPORARILY_UNAVAILABLE).

the rest

There is another type of provider – PASSIVE_PROVIDER. By itself, this provider will not return any data. But by hanging a listener on it, you will be able to get location data when someone else on the system is trying to determine a location through regular providers. The system will duplicate the results for you as well.

The getAllProviders method will return you a list of all available providers. The getProviders (boolean enabledOnly) method returns either all or only included ones.

In addition to coordinates, time, and provider, the Location object has several other attributes that may come up empty:

getAccuracy – accuracy of reading in meters

getAltitude – height above sea level in meters

getSpeed ​​- speed in m / s

getBearing – as far as I understand, this is the angle at which the current trajectory deviates from the trajectory to the north. It is azimuth.

You can also test your location using the AVD emulator. To do this, open Eclipse in DDMS (Window> Open Perspective> DDMS) and select the Emulator Control tab. Below is the Manual tab, which has fields for entering coordinates and a submit button.

In the next lesson:

– create a map application
– customize the map and process its events
– programmatically change the position of the camera




Discuss in the forum [165 replies]

Leave a Comment