我希望在用户的当前位置准确设置标记。我使用的是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
已解决:获取启动时的运行时权限可修复此问题。
答案 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;
}
}
}