Getting a Location Fix

Now that you have everything set up, you are ready to get a location fix. Your window to the Fused Location Provider API is a class named, appropriately enough, FusedLocationProviderApi. There is one instance of this class. It is a singleton object that lives on LocationServices called FusedLocationApi.

To get a location fix from this API, you need to build a location request. Fused location requests are represented by LocationRequest objects. Create one and configure it in a new method called findImage(). (There are two LocationRequest classes. Use the one with the complete name of com.google.android.gms.location.LocationRequest.)

Listing 33.14  Building a location request (LocatrFragment.java)

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        ...
    }

    private void findImage() {
        LocationRequest request = LocationRequest.create();
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        request.setNumUpdates(1);
        request.setInterval(0);
    }
}

LocationRequest objects configure a variety of parameters for your request:

  • interval – how frequently the location should be updated

  • number of updates – how many times the location should be updated

  • priority – how Android should prioritize battery life against accuracy to satisfy your request

  • expiration – whether the request should expire and, if so, when

  • smallest displacement – the smallest amount the device must move (in meters) to trigger a location update

When you first create a LocationRequest, it will be configured for accuracy within a city block, with repeated slow updates until the end of time. In your code, you change this to get a single, high-accuracy location fix by changing the priority and the number of updates. You also set the interval to 0 to signify that you would like a location fix as soon as possible.

The next step is to send off this request and listen for the Locations that come back. You do this by adding a LocationListener. There are two versions of LocationListener you can import. Choose com.google.android.gms.location.LocationListener. Add another method call to findImage().

Listing 33.15  Sending LocationRequest (LocatrFragment.java)

public class LocatrFragment extends Fragment {
    private static final String TAG = "LocatrFragment";
    ...
    private void findImage() {
        LocationRequest request = LocationRequest.create();
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        request.setNumUpdates(1);
        request.setInterval(0);
        LocationServices.FusedLocationApi
                .requestLocationUpdates(mClient, request, new LocationListener() {
                    @Override
                    public void onLocationChanged(Location location) {
                        Log.i(TAG, "Got a fix: " + location);
                    }
                });
    }

If this were a longer-lived request, you would need to hold on to your listener and call removeLocationUpdates(…) later to cancel the request. However, since you called setNumUpdates(1), all you need to do is send this off and forget about it.

(Your call to requestLocationUpdates(…) will receive a dramatic red error indicator. Will this cause problems? Yes, it will – but leave it as is for now; you will address those issues in a moment.)

Finally, to send this off you need to hook up your search button. Override onOptionsItemSelected(…) to call findImage().

Listing 33.16  Hooking up search button (LocatrFragment.java)

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    ...
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_locate:
            findImage();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Run your app and press the search button. Sadly, your dramatic red error indicator will come due when your app runs: You will see a message indicating that Locatr has stopped (Figure 33.8).

Figure 33.8  Permission: denied

Screenshot shows a permission error in Android phone. The error reads, locatr has stopped. Open app again.

If you check Logcat, you will see that a SecurityException was thrown:

FATAL EXCEPTION: main
Process: com.bignerdranch.android.locatr, PID: 7892
java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION permission to
request PRIORITY_HIGH_ACCURACY locations.
    at android.os.Parcel.readException(Parcel.java:1684)
    at android.os.Parcel.readException(Parcel.java:1637)
    ...
    at com.google.android.gms.location.internal.zzd
        .requestLocationUpdates(Unknown Source)
    at com.bignerdranch.android.locatr.LocatrFragment
        .findImage(LocatrFragment.java:102)
    at com.bignerdranch.android.locatr.LocatrFragment
        .onOptionsItemSelected(LocatrFragment.java:89)
    at android.support.v4.app.Fragment.performOptionsItemSelected(Fragment.java:2212)
    ...
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller
        .run(ZygoteInit.java:886)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

For your call to requestLocationUpdates(…) to work, you must first ask permission.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.247.196