Android Marshmallow的Google Maps API中的getMyLocation()出错

时间:2016-07-21 09:06:23

标签: android google-maps

我希望在用户的当前位置准确设置标记。我使用的是Google Maps API V2.0。这是我的代码:

package com.acousfit.www.acousfit.Fragments;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.BitmapFactory;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
vimport android.view.View;
import android.widget.Toast;

import com.acousfit.www.acousfit.R;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
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.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.io.IOException;


/**

* Created by Vaze on 7/21/2016.

*/



public class MapFragment extends SupportMapFragment implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    GoogleMap.OnInfoWindowClickListener,
    GoogleMap.OnMapLongClickListener,
    GoogleMap.OnMapClickListener,
    GoogleMap.OnMarkerClickListener, LocationListener {

private GoogleApiClient mGoogleApiClient;
private Location mCurrentLocation;


private final int[] MAP_TYPES = {GoogleMap.MAP_TYPE_SATELLITE,
        GoogleMap.MAP_TYPE_NORMAL,
        GoogleMap.MAP_TYPE_HYBRID,
        GoogleMap.MAP_TYPE_TERRAIN,
        GoogleMap.MAP_TYPE_NONE};
private int curMapTypeIndex = 0;

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

    setHasOptionsMenu(true);

    //googleMap.setMyLocationEnabled(true);

    mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

    initListeners();
}


@Override
public void onInfoWindowClick(Marker marker) {

}

@Override
public void onMapLongClick(LatLng latLng) {
    MarkerOptions options = new MarkerOptions().position(latLng);
    options.title(getAddressFromLatLng(latLng));

    options.icon(BitmapDescriptorFactory.fromBitmap(
            BitmapFactory.decodeResource(getResources(),
                    R.mipmap.ic_launcher)));

    getMap().addMarker(options);
}


@Override
public boolean onMarkerClick(Marker marker) {
    return false;
}

@Override
public void onMapClick(LatLng latLng) {

    MarkerOptions options = new MarkerOptions().position(latLng);
    options.title(getAddressFromLatLng(latLng));

    options.icon(BitmapDescriptorFactory.defaultMarker());
    getMap().addMarker(options);
}


@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}

private void initListeners() {
    getMap().setOnMarkerClickListener(this);
    getMap().setOnMapLongClickListener(this);
    getMap().setOnInfoWindowClickListener(this);
    getMap().setOnMapClickListener(this);
}

@Override
public void onStart() {
    super.onStart();
    mGoogleApiClient.connect();
}

@Override
public void onStop() {
    super.onStop();
    if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
        mGoogleApiClient.disconnect();
    }
}

@Override
public void onConnected(Bundle bundle) {
    mCurrentLocation = LocationServices
            .FusedLocationApi.getLastLocation(mGoogleApiClient);
    //LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
    //Criteria criteria = new Criteria();
    //String bestProvider = String.valueOf(locationManager.getBestProvider(criteria, true));
    //mCurrentLocation = locationManager.getLastKnownLocation(bestProvider);
    initCamera(getMyLocation());


}

private void initCamera(Location location) {
    CameraPosition position = CameraPosition.builder()
            .target(new LatLng(location.getLatitude(),
                    location.getLongitude()))
            .zoom(16f)
            .bearing(0.0f)
            .tilt(0.0f)
            .build();

    getMap().animateCamera(CameraUpdateFactory
            .newCameraPosition(position), null);

    getMap().setMapType(MAP_TYPES[curMapTypeIndex]);
    getMap().setTrafficEnabled(true);
    getMap().setMyLocationEnabled(true);
    getMap().getUiSettings().setZoomControlsEnabled(true);
}

private String getAddressFromLatLng(LatLng latLng) {
    Geocoder geocoder = new Geocoder(getActivity());

    String address = "";
    try {
        address = geocoder
                .getFromLocation(latLng.latitude, latLng.longitude, 1)
                .get(0).getAddressLine(0);
    } catch (IOException e) {
    }

    return address;
}


@Override
public void onLocationChanged(Location location) {

}

private Location getMyLocation() {
    // Get location from GPS if it's available
    LocationManager lm = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
    if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return null;
    }
    Location myLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);

    // Location wasn't found, check the next most accurate place for the current location
    if (myLocation == null) {
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_COARSE);
        // Finds a provider that matches the criteria
        String provider = lm.getBestProvider(criteria, true);
        // Use the provider to get the last known location
        myLocation = lm.getLastKnownLocation(provider);
    }

    return myLocation;
 }
}

每当我尝试打开此片段时,它会将当前位置返回为NULL。 注意:我使用Android Marshmallow(仅供您参考),指定的最低SDK是Android 5.0.2

已解决:获取启动时的运行时权限可修复此问题。

1 个答案:

答案 0 :(得分:1)

下面的行给你null,因为你的设备是android-M,它会进入你的下面if条件,所以你的android-M运行时权限的正确代码在你的下面if条件。

 if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    // TODO: Consider calling
    //    ActivityCompat#requestPermissions
    // here to request the missing permissions, and then overriding
    //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
    //                                          int[] grantResults)
    // to handle the case where the user grants the permission. See the documentation
    // for ActivityCompat#requestPermissions for more details.
    return null;
}

尝试执行以下操作:

Location myLocation =null;

if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    // TODO: Consider calling
                    //    ActivityCompat#requestPermissions
                    // here to request the missing permissions, and then overriding
                    //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                    //                                          int[] grantResults)
                    // to handle the case where the user grants the permission. See the documentation
                    // for ActivityCompat#requestPermissions for more details.
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, ACCESS_COARSE_LOCATION);
                    }
                    return;
                }else{
                     myLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);

// Location wasn't found, check the next most accurate place for the current location
                     if (myLocation == null) {
                         Criteria criteria = new Criteria();
                         criteria.setAccuracy(Criteria.ACCURACY_COARSE);
                         // Finds a provider that matches the criteria
                         String provider = lm.getBestProvider(criteria, true);
                         // Use the provider to get the last known location
                         myLocation = lm.getLastKnownLocation(provider);
                      }

                }

并添加以下覆盖方法:

    @Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // location-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }
    }

}