使用GoogleMap和FusedLocationProviderClient进行MyLocation并实现MyLocationButton功能

时间:2018-06-09 21:17:53

标签: android

我是Android的新手,并使用FusedLocationProviderClient获取MyLocation并放大它。

当我的位置关闭并打开并调用getDeviceLocation()函数时,它会在我的logcat上抛出此错误并强行关闭应用程序:

    java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
        at myProjectPackageName.MainActivity$2.onComplete(MainActivity.java:108)
        at com.google.android.gms.tasks.zzj.run(Unknown Source:23)
        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)

我的整个代码:

public class MainActivity extends AppCompatActivity
        implements
        OnMapReadyCallback,
        GoogleMap.OnMapClickListener {

    private GoogleMap mMap;
    private FusedLocationProviderClient mFusedLocationProviderClient;
    // The geographical location where the device is currently located. That is, the last-known
    // location retrieved by the Fused Location Provider.
    private Location mLastKnownLocation;

    // A default location and zoom to use when location permission is not granted.
    private final LatLng defaultLocation = new LatLng(36.2896307,59.6011211);
    private static final int DEFAULT_ZOOM_GRANTED = 17;
    private static final int DEFAULT_ZOOM_DENIED = 10;

    // Permission Check
    private static final int ACCESS_FINE_LOCATION_REQUEST_CODE = 1;
    private boolean locationPermissionGranted = false;

    // Location Service Status
    private LocationManager locationManager;

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

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

        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

        ImageView myLocationImageView = findViewById(R.id.iv_main_myLocation);
        myLocationImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(locationPermissionGranted) {
                    if (checkGpsStatus()) {
                        getDeviceLocation();
                    } else {
                        //TODO : Alert Dialog For Enabling Location Service
                        Toast.makeText(MainActivity.this, "Please Enable GPS", Toast.LENGTH_SHORT).show();
                    }
                }else{
                    getLocationPermission();
                }
            }
        });
    }

    private boolean checkGpsStatus() {
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setOnMapClickListener(this);
        //mMap.getUiSettings().setZoomControlsEnabled(true);

        getLocationPermission();
        getDeviceLocation();
    }

    private void getDeviceLocation() {
        try {
            if (locationPermissionGranted) {
                if (checkGpsStatus()) {
                    Task<Location> locationResult = mFusedLocationProviderClient.getLastLocation();
                    locationResult.addOnCompleteListener(this, new OnCompleteListener<Location>() {
                        @Override
                        public void onComplete(@NonNull Task<Location> task) {
                            if (task.isSuccessful()) {
                                // Set the map's camera position to the current location of the device.
                                mLastKnownLocation = task.getResult();
                                CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
                                        new LatLng(mLastKnownLocation.getLatitude(),
                                                mLastKnownLocation.getLongitude()), DEFAULT_ZOOM_GRANTED);
                                mMap.animateCamera(cameraUpdate);
                            }
                        }
                    });
                }else{
                    //TODO : Alert Dialog For Enabling Location Service
                    Toast.makeText(MainActivity.this, "Please Enable GPS", Toast.LENGTH_SHORT).show();
                    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(defaultLocation, DEFAULT_ZOOM_DENIED);
                    mMap.animateCamera(cameraUpdate);
                }
            }else{
                CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(defaultLocation, DEFAULT_ZOOM_DENIED);
                mMap.animateCamera(cameraUpdate);
            }
        } catch (SecurityException e) {
            Log.e("Exception: %s", e.getMessage());
        }
    }

    private void getLocationPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            setMyLocationEnabled();
        } else {
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {
                //TODO : Add Alert Dialog For Getting Request Again & Remove Below Codes
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        ACCESS_FINE_LOCATION_REQUEST_CODE);            } else {
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        ACCESS_FINE_LOCATION_REQUEST_CODE);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case ACCESS_FINE_LOCATION_REQUEST_CODE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    setMyLocationEnabled();
                } else {
                    Toast.makeText(this,"Denied",Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    private void setMyLocationEnabled() {
        locationPermissionGranted = true;
        try{
            mMap.setMyLocationEnabled(true);
            mMap.getUiSettings().setMyLocationButtonEnabled(false);
        }catch (SecurityException e){
            Log.e("setMyLocationEnabled : ",e.toString());
        }
        getDeviceLocation();
    }

    @Override
    public void onMapClick(LatLng latLng) {
        Toast.makeText(this, "Lat :" + latLng.latitude + "Lng : " + latLng.longitude, Toast.LENGTH_LONG).show();
    }
}

我不想使用谷歌地图MyLocationButton,如何在我的应用程序中实现该功能?

我使用了一些编辑: https://github.com/googlemaps/android-samples/blob/master/ApiDemos/java/app/src/main/java/com/example/mapdemo/MyLocationDemoActivity.java

0 个答案:

没有答案