问题
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