1

I am trying to make an app that can track the GPS location of my bike. To start off, I've been trying to read the GPS location of my own phone. My app keeps crashing whenever I try to launch the fragment below. I have put in a Google API key for the App and placed the line " " in my manifest file. What are some good ways to debug this issue? I am new to Android Studio so I would love to hear any sort of feedback.

//FindBikeFragment.java

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;


/**
 * A simple {@link Fragment} subclass.
 */
public class FindBikeFragment extends Fragment implements OnMapReadyCallback {

    /**
     * GoogleMaps object
     */
    private GoogleMap mMap;
    /**
     * Provides the entry point to the Fused Location Provider API.
     */
    private FusedLocationProviderClient mFusedLocationClient;
    /**
     * Represents a geographical location.
     */
    protected Location mLastLocation;


    public FindBikeFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.fragment_find_bike, container, false);
        return v;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map1);
        mapFragment.getMapAsync(this);
    }


    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());

        if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            mLastLocation = mFusedLocationClient.getLastLocation().getResult();
            LatLng pp = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
            MarkerOptions option = new MarkerOptions();
            option.position(pp).title("Some City");
            mMap.addMarker(option);
            mMap.moveCamera(CameraUpdateFactory.newLatLng(pp));
            return;
        }
    }
}
user230913
  • 11
  • 1

2 Answers2

0

You need to use GoogleApiClient for FusedLocationApi.Here is a working code

    protected synchronized void buildGoogleApiClient() {
         mGoogleApiClient = new GoogleApiClient.Builder(this)
        .addConnectionCallbacks(this)
        .addOnConnectionFailedListener(this)
        .addApi(LocationServices.API)
        .build();}

    return;
}

Call buildGoogleApiClient method on onCreate().And implement required interfaces. GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener

 @Override
public void onConnected(@Nullable Bundle bundle) {
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.


        return;
    }
    Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);
    if (mLastLocation != null) {
        //place marker at current position
        // Log.e("x", mLastLocation.getLongitude() + "");
        //Log.e("y", mLastLocation.getLatitude() + "");
        currentLocation = mLastLocation;


    }

    LocationRequest mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(5000); //5 seconds
    mLocationRequest.setFastestInterval(5000); //3 seconds
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    mLocationRequest.setSmallestDisplacement(50F); //1/10 meter

    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

@Override
public void onLocationChanged(Location location) {

    currentLocation = location;

}

And define this parameters

private GoogleApiClient mGoogleApiClient;
private Location currentLocation;

Btw if you are using Android 6.x or 7.x version. You need to grant permission at runtime.Check here

FnR
  • 75
  • 1
  • 5
0

@FnR you're talking about the old version of the fusedlocationapi, a new one came out with the version 11 of the playservices, it's supposed to be much simpler, look here : https://android-developers.googleblog.com/2017/06/reduce-friction-with-new-location-apis.html

I got the same issue there seems to be a conflict between the new fusedlocationapi and the map activities. I'm able to get my current location with this new technique in an empty activity with no map but the exact same code used in a map activity returns a null result.

Google didn't even provide any example of this with a map, which is crazy since getting the location is 99% of the time coupled with a map

Waylan
  • 91
  • 1
  • 2
  • 9