无法转换为com.google.android.gms.location.LocationListener

时间:2018-05-16 13:45:40

标签: java android location

这是我的MapsActivity.class代码

package com.plusequalsto.ride;

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import com.google.android.gms.location.LocationListener;
import android.os.Handler;
import android.os.SystemClock;
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.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.Toast;

import com.firebase.geofire.GeoFire;
import com.firebase.geofire.GeoLocation;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
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.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MapStyleOptions;
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.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

public class MapsActivity extends Fragment implements OnMapReadyCallback,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    LocationListener{

private GoogleMap mMap;

private static final int MY_PERMISSION_REQUEST_CODE = 7000;
private static final int PLAY_SERVICE_RES_REQUEST = 7001;

private LocationRequest myLocationRequest;
private GoogleApiClient myGoogleApiClient;
private Location myLastLoaction;

private static int UPDATE_INTERVAL = 5000;
private static int FASTEST_INTERVAL = 3000;
private static int DISPLACEMENT = 10;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;

DatabaseReference drivers;
GeoFire geoFire;

Marker mCurrent;
Switch availableSwitch;

SupportMapFragment mapFragment;


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.activity_maps, container, false);
}

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

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

    availableSwitch = (Switch) getActivity().findViewById(R.id.availableSwitch);
    availableSwitch.setOnCheckedChangeListener(new Switch.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isOnline) {
            if (isOnline){
                startLocationUpdates();
                displayLocation();
                Snackbar.make(mapFragment.getView(), "You are Online", Snackbar.LENGTH_SHORT)
                        .show();
            }
            else {
                stopLocationUpdate();
                mCurrent.remove();
                Snackbar.make(mapFragment.getView(), "You are Offline", Snackbar.LENGTH_SHORT)
                        .show();
            }
        }
    });

    drivers = FirebaseDatabase.getInstance().getReference("Drivers");
    geoFire = new GeoFire(drivers);

    setUpLocation();

}

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

private void setUpLocation(){
    if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){

        ActivityCompat.requestPermissions(getActivity(),new String[]{
                android.Manifest.permission.ACCESS_COARSE_LOCATION,
                android.Manifest.permission.ACCESS_FINE_LOCATION
        },MY_PERMISSION_REQUEST_CODE);
    }
    else {
        if (checkPlayServices()){
            buildGoogleApiClient();
            createLocationRequest();
            if (availableSwitch.isChecked())
                displayLocation();
        }
    }
}

private void createLocationRequest() {
    myLocationRequest = new LocationRequest();
    myLocationRequest.setInterval(UPDATE_INTERVAL);
    myLocationRequest.setFastestInterval(FASTEST_INTERVAL);
    myLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    myLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}

private void buildGoogleApiClient() {
    myGoogleApiClient = new GoogleApiClient.Builder(getActivity())
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    myGoogleApiClient.connect();
}

private boolean checkPlayServices() {
    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
    if (resultCode != ConnectionResult.SUCCESS){
        if (GooglePlayServicesUtil.isUserRecoverableError(resultCode))
            GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(), PLAY_SERVICES_RESOLUTION_REQUEST).show();
        else {
            Toast.makeText(getActivity(), "This device is not supported", Toast.LENGTH_SHORT).show();
        }
    }
    return true;
}

private void stopLocationUpdate() {
    if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
        return;
    }
    LocationServices.FusedLocationApi.removeLocationUpdates(myGoogleApiClient, (LocationListener) getActivity());
}

private void displayLocation() {
    if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
        return;
    }
    myLastLoaction = LocationServices.FusedLocationApi.getLastLocation(myGoogleApiClient);
    if (myLastLoaction != null){
        if (availableSwitch.isChecked()){
            final double latitude = myLastLoaction.getLatitude();
            final double longitude = myLastLoaction.getLongitude();

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

                    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 15.0f));
                    rotateMarker(mCurrent, -360, mMap);
                }
            });
        }
    }
    else {
        Log.d("ERROR", "displayLocation: ");
    }

}

private void rotateMarker(final Marker myCurent, final float i, GoogleMap mMap) {
    final Handler handler = new Handler();
    final long start = SystemClock.uptimeMillis();
    final float startRotation = myCurent.getRotation();
    final long duration = 1000;

    final Interpolator interpolator = new LinearInterpolator();
    handler.post(new Runnable() {
        @Override
        public void run() {
            long elapsed = SystemClock.uptimeMillis()-start;
            float t = interpolator.getInterpolation((float)elapsed/duration);
            float rot = t+i+(1-t)*startRotation;
            myCurent.setRotation(-rot > 180?rot/2:rot);
            if (t<1.0){
                handler.postDelayed(this, 16);
            }

        }
    });
}

private void startLocationUpdates() {
    if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
        return;
    }
    LocationServices.FusedLocationApi.requestLocationUpdates(myGoogleApiClient, myLocationRequest, (LocationListener) getActivity());
}

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

@Override
public void onLocationChanged(Location location) {

}

@Override
public void onConnected(@Nullable Bundle bundle) {

}

@Override
public void onConnectionSuspended(int i) {

}

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

}

}

及以下是我的错误消息

05-16 17:22:12.849 17072-17072/com.plusequalsto.ride E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.plusequalsto.ride, PID: 17072
java.lang.ClassCastException: com.plusequalsto.ride.MainActivity cannot be cast to com.google.android.gms.location.LocationListener
    at com.plusequalsto.ride.MapsActivity.startLocationUpdates(MapsActivity.java:246)
    at com.plusequalsto.ride.MapsActivity.access$000(MapsActivity.java:46)
    at com.plusequalsto.ride.MapsActivity$1.onCheckedChanged(MapsActivity.java:93)
    at android.widget.CompoundButton.setChecked(CompoundButton.java:171)
    at android.widget.Switch.setChecked(Switch.java:1075)
    at android.widget.Switch.toggle(Switch.java:1070)
    at android.widget.CompoundButton.performClick(CompoundButton.java:132)
    at android.view.View$PerformClick.run(View.java:24770)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

现在我已尝试过在Google上找到的各种解决方案。而且他们没有工作!

我有Switch,当检查时会加载我当前的位置并保持更新。但是一旦我将开关转到托架,我的应用程序就会崩溃。

如果有助于理解问题,我的MainActivity.class如下所示

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    fragmentTransaction.replace(R.id.contentFrame, new MapsActivity()).commit();

    mAuth = FirebaseAuth.getInstance();

}

有人可以建议一个有效的解决方案吗?

1 个答案:

答案 0 :(得分:1)

问题在这里

LocationServices.FusedLocationApi.removeLocationUpdates(myGoogleApiClient,
               (LocationListener) getActivity());
//.            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

您的活动尚未实施任何位置监听器,因此将您的活动转移到位置监听器会产生问题 使用getActivity或仅MapsActivity.this

删除this
LocationServices.FusedLocationApi.removeLocationUpdates(myGoogleApiClient,
               this);

注意:使用正确的命名约定,因此我建议您将片段重命名为MapsFragment