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

一世执手 提交于 2019-12-11 14:51:51

问题


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);
}

 }

回答1:


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);



回答2:


Implementation of fused location service has changed, you can do that without the GoogleApiClient. You can try like this,

Add required location library to build.grade

implementation 'com.google.android.gms:play-services-location:15.0.0'

Add required permissions to manifest

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Inside Welcome activity

public class Welcome extends AppCompatActivity implements OnMapReadyCallback {

    ...
    ...

    private FusedLocationProviderClient mFusedLocationClient;

    private LocationRequest mLocationRequest = LocationRequest.create()
            .setInterval(1000)
            .setFastestInterval(500)
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    private LocationCallback mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult result) {
            super.onLocationResult(result);
            for (Location location : result.getLocations())
                if (location != null) {
                    displayLocation(result.getLastLocation());
                    break;
                }
        }
    };

    ...
    ...

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome);

        ...
        ...

        // Get fussed location instance
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);

        ...
        ...
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        ...
        ...

        // Check if location permission is granted
        if (!hasLocationPermission()) {
            // Request location permission
        } else {
            // Get the last known location
            startLocationUpdate();
        }
    }

    private void startLocationUpdate() {
        try {
            mFusedLocationClient.getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    if (location != null) {
                        displayLocation(location);
                    } else {
                    mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, null);
                    }
                }
            });
        } catch (SecurityException ex) {
            ex.printStackTrace();
        }
    }

    private boolean hasLocationPermission() {
        return ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED;
    }

    private void stopLocationUpdate() {
        mFusedLocationClient.removeLocationUpdates(mLocationCallback);
    }

    private void displayLocation(Location location) {
        // do something
        ...
        ...
    }
}


来源:https://stackoverflow.com/questions/49987265/app-crashes-while-requesting-location-updates-with-the-help-of-fused-location

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!