Search code examples
androidfusedlocationproviderapiandroid-fusedlocationlocation-updates

App Crashes While Requesting Location Updates With The Help Of Fused Location


I was requesting the location updates with the help of

LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, 
locationRequest, locationListener);

But As I tried to mention this on a swtich onClickListener , it crashed. However there was no error thrown Android Studio itself.

I already have added permission to request Fused Location, coarse Location and Internet as part of this function. I even tried to connect the google Api client before requesting the Updated Like.,

if(googleApiClient.isConnected){
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, 
locationRequest, locationListener);
}else{
buildGoogleApiClient();
}

But I could not get the error resolved. removing the location request with Fused Location Provider Api is also causing the app to crash.

My Manifest file have codes as given below. As you can see i already have requested the permissions requred

My XML File is as

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >


    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        tools:context="com.matt.dumate.Welcome" />

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar3"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:background="#0064a2"
        android:weightSum="2">

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="start">

            <com.github.glomadrian.materialanimatedswitch.MaterialAnimatedSwitch
                android:id="@+id/locationSwitch"
                android:layout_width="20dp"
                android:layout_height="wrap_content"
                android:layout_alignParentStart="true"
                android:layout_centerInParent="true"
                android:layout_marginStart="0dp"
                android:layout_marginTop="0dp"
                app:ball_press_color="@android:color/white"
                app:ball_release_color="@color/ballReleaseColor"
                app:base_press_color="@color/basePressColor"
                app:base_release_color="@color/baseReleaseColor"
                app:icon_press="@drawable/ic_location_on"
                app:icon_release="@drawable/ic_location_off" />

        </RelativeLayout>

    </android.support.v7.widget.Toolbar>

    <Button
        android:id="@+id/bookingButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/toolbar3"
        android:layout_alignParentStart="true"
        android:layout_marginBottom="5dp"
        android:layout_marginStart="90dp"
        android:layout_marginTop="5dp"
        android:background="@drawable/bookingbutton"
        android:gravity="center"
        android:text="@string/booking"
        android:textColor="@android:color/white" />


</RelativeLayout>

This is my java File. I was learning too create an app like Uber.

package com.matt.dumate;

import com.firebase.geofire.GeoFire;
import com.firebase.geofire.GeoLocation;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.github.glomadrian.materialanimatedswitch.MaterialAnimatedSwitch;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
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.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

public class Welcome extends FragmentActivity implements OnMapReadyCallback,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    LocationListener {

MaterialAnimatedSwitch location_switch;
SupportMapFragment mapFragment;

private Button btnBooking;
private Location lastLocation;
private GoogleApiClient.OnConnectionFailedListener onConnectionFailedListener;
private LocationRequest locationRequest;
private LocationListener locationListener;
private LocationManager locationManager;
private Marker marker;
private GoogleMap mMap;
private GoogleApiClient googleApiClient;
private final int RequestCode = 10;
private final int ResourceCode = 11;

private DatabaseReference databaseReference;
GeoFire geoFire;


@Override
protected void onCreate(Bundle savedInstanceState) {

    checkLocationPermission();
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_welcome);
    mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

    /***/
    databaseReference = FirebaseDatabase.getInstance().getReference("Drivers");
    geoFire = new GeoFire(databaseReference);
    setupLocation();
}

@Override
public void onMapReady(GoogleMap googleMap) {
    setupUiViews();
    mMap = googleMap;
    location_switch.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(location_switch.isChecked()){
                displayLocation();
                Snackbar.make(mapFragment.getView(), "You Are Online", Snackbar.LENGTH_SHORT).show();
            }else {
                stopLocationUpdates();
                Snackbar.make(mapFragment.getView(), "You Are Offline", Snackbar.LENGTH_SHORT).show();
                if (marker != null) {
                    marker.remove();
                }
            }
        }
    });

}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case RequestCode:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                if (checkPlayServices()){
                    buildGoogleApiClient();
                    createLocationRequest();
                    if (location_switch.isChecked()){
                        displayLocation();
                    }
                }
            }

    }
}

public void checkLocationPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
    {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION))
        {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, RequestCode);
        } else {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, RequestCode);
        }
    } else {
        Toast.makeText(this, "Location Permissions Granted", Toast.LENGTH_SHORT).show();
    }
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    locationRequest = LocationRequest.create()
            .setInterval(1000)
            .setFastestInterval(500)
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    startLocationUpdates();
    displayLocation();
}

@Override
public void onConnectionSuspended(int i) {
    googleApiClient.connect();
}

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

@Override
public void onLocationChanged(Location location) {
    lastLocation = location;
    displayLocation();

}

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

private void setupUiViews() {
    btnBooking = findViewById(R.id.bookingButton);
    location_switch = findViewById(R.id.locationSwitch);
}

private void displayLocation() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
    if (lastLocation != null ){
        if(location_switch.isChecked()){
            final Double lat = lastLocation.getLatitude();
            final Double lng = lastLocation.getLongitude();

            geoFire.setLocation(FirebaseAuth.getInstance().getCurrentUser().getUid(), new GeoLocation(lat, lng), new GeoFire.CompletionListener() {
                @Override
                public void onComplete(String key, DatabaseError error) {
                    if (marker != null) {
                        marker.remove();
                        marker = mMap.addMarker(new MarkerOptions().position(new LatLng(lat, lng)).icon(BitmapDescriptorFactory.fromResource(R.drawable.carmarker)).title("You"));

                        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 15.0f));
                    }else{
                        marker = mMap.addMarker(new MarkerOptions().position(new LatLng(lat, lng)).icon(BitmapDescriptorFactory.fromResource(R.drawable.carmarker)).title("You"));

                        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 15.0f));
                }
                }
            });
        }else{
            Toast.makeText(this, "Cannot Get Location Updates", Toast.LENGTH_SHORT).show();
        }
    }else{
        Log.d("Error", "Cannot Get Your Location");
    }
}

private void setupLocation() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
    {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION))
        {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, RequestCode);
        } else {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, RequestCode);
        }
    }else{
        if (checkPlayServices()){
            buildGoogleApiClient();
            createLocationRequest();

        }
    }
}

private void createLocationRequest() {
    locationRequest = LocationRequest.create()
            .setInterval(1500)
            .setFastestInterval(500)
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setSmallestDisplacement(0);
}

private boolean checkPlayServices(){
    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    if (resultCode != ConnectionResult.SUCCESS){
        if (GooglePlayServicesUtil.isUserRecoverableError(resultCode))
            GooglePlayServicesUtil.getErrorDialog(resultCode, this, ResourceCode).show();
        else {
            Toast.makeText(this, "This Device Is Not Supported", Toast.LENGTH_SHORT).show();
            finish();
        }return false;
    }
    return true;
}

private void stopLocationUpdates() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    //LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, locationListener);
}

private void startLocationUpdates() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }
    //LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, locationListener);
}

 }

Solution

  • You have requested location updates with the help of locationListener which you have not initialized. You can solve the problem either by initializing a location listener or by changing locationListener to this in the given statement of your code.

    LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, locationListener);
    

    to:

    LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);