我目前正在制作一个带有谷歌地图的片段.一旦用户访问该片段,他的地图应该缩放并关注他的位置.但是,它显示的是世界地图而不是附近的位置(靠近用户):
@SuppressWarnings("unused") public class DeferredMapFragment extends MapFragment implements GoogleMap.OnCameraChangeListener, OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { private static final String TAG = "DeferredMapFragment"; private DequependingActions; private AbstractMap tags; private GoogleMap map; private LocationRequest mLocationRequest; private GoogleApiClient mGoogleApiClient; private Location mLastLocation; private Marker marker; private GoogleMap.OnCameraChangeListener cameraChangeListener = null; private boolean isMapReady = false; /* * INTERNALS */ @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (getMap() != null) { map = getMap(); getMap().setOnCameraChangeListener(this); } } @Override public void onCameraChange(CameraPosition cameraPosition) { isMapReady = true; if (pendingActions != null) { int i = pendingActions.size(); while (i > 0) { pendingActions.pop().run(); --i; } } if (cameraChangeListener != null) { cameraChangeListener.onCameraChange(cameraPosition); } if (getMap() != null) { getMap().setOnCameraChangeListener(cameraChangeListener); } } private void execute(Runnable action) { if (action == null) { return; } if (isMapReady) { action.run(); } else { if (pendingActions == null) { pendingActions = new LinkedList<>(); } pendingActions.add(action); } } /* * TAGGING */ private void addTag(Marker key, Object value) { if (tags == null) { tags = new HashMap<>(); } tags.put(key, value); } public Object getTag(Marker key) { return tags != null ? tags.get(key) : null; } /* * LISTENERS */ public void setOnInfoWindowClickListener(final GoogleMap.OnInfoWindowClickListener listener) { execute(new Runnable() { @Override public void run() { getMap().setOnInfoWindowClickListener(listener); } }); } public void setOnCameraChangeListener(final GoogleMap.OnCameraChangeListener listener) { cameraChangeListener = listener; } public void setOnMarkerClickListener(final GoogleMap.OnMarkerClickListener listener) { execute(new Runnable() { @Override public void run() { getMap().setOnMarkerClickListener(listener); } }); } public void setOnMapClickListener(final GoogleMap.OnMapClickListener listener) { execute(new Runnable() { @Override public void run() { getMap().setOnMapClickListener(listener); } }); } /* * MAP OVERLAYS */ public void addPolyline(final PolylineOptions options) { execute(new Runnable() { @Override public void run() { getMap().addPolyline(options); } }); } public void addPolygon(final PolygonOptions options) { execute(new Runnable() { @Override public void run() { getMap().addPolygon(options); } }); } public void addCircle(final CircleOptions options) { execute(new Runnable() { @Override public void run() { getMap().addCircle(options); } }); } public void addMarker(final MarkerOptions options) { addMarker(options, null); } public void addMarker(final MarkerOptions options, final Object tag) { execute(new Runnable() { @Override public void run() { Marker marker = getMap().addMarker(options); if (tag != null) { addTag(marker, tag); } } }); } public void addGroundOverlay(final GroundOverlayOptions options) { execute(new Runnable() { @Override public void run() { getMap().addGroundOverlay(options); } }); } public void addTileOverlay(final TileOverlayOptions options) { execute(new Runnable() { @Override public void run() { getMap().addTileOverlay(options); } }); } /* * UI SETTINGS */ public void setMapToolbarEnabled(final boolean enabled) { execute(new Runnable() { @Override public void run() { getMap().getUiSettings().setMapToolbarEnabled(enabled); } }); } public void setPadding(final int left, final int top, final int right, final int bottom) { execute(new Runnable() { @Override public void run() { getMap().setPadding(left, top, right, bottom); } }); } public void setZoomControlsEnabled(final boolean enabled) { execute(new Runnable() { @Override public void run() { getMap().getUiSettings().setZoomControlsEnabled(enabled); } }); } public void setCompassEnabled(final boolean enabled) { execute(new Runnable() { @Override public void run() { getMap().getUiSettings().setCompassEnabled(enabled); } }); } public void setMyLocationButtonEnabled(final boolean enabled) { execute(new Runnable() { @Override public void run() { getMap().getUiSettings().setMyLocationButtonEnabled(enabled); } }); } public void setIndoorLevelPickerEnabled(final boolean enabled) { execute(new Runnable() { @Override public void run() { getMap().getUiSettings().setIndoorLevelPickerEnabled(enabled); } }); } public void setScrollGesturesEnabled(final boolean enabled) { execute(new Runnable() { @Override public void run() { getMap().getUiSettings().setScrollGesturesEnabled(enabled); } }); } public void setZoomGesturesEnabled(final boolean enabled) { execute(new Runnable() { @Override public void run() { getMap().getUiSettings().setZoomGesturesEnabled(enabled); } }); } public void setTiltGesturesEnabled(final boolean enabled) { execute(new Runnable() { @Override public void run() { getMap().getUiSettings().setTiltGesturesEnabled(enabled); } }); } public void setRotateGesturesEnabled(final boolean enabled) { execute(new Runnable() { @Override public void run() { getMap().getUiSettings().setRotateGesturesEnabled(enabled); } }); } public void setAllGesturesEnabled(final boolean enabled) { execute(new Runnable() { @Override public void run() { getMap().getUiSettings().setAllGesturesEnabled(enabled); } }); } public void setInfoWindowAdapter(final GoogleMap.InfoWindowAdapter adapter) { execute(new Runnable() { @Override public void run() { getMap().setInfoWindowAdapter(adapter); } }); } @Override public void onMapReady(GoogleMap googleMap) { map = googleMap; setUpMap(); } public void setUpMap() { map.setMapType(GoogleMap.MAP_TYPE_HYBRID); if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), 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; } map.setMyLocationEnabled(true); } @Override public void onConnected(Bundle bundle) { mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(1000); mLocationRequest.setFastestInterval(1000); mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); //mLocationRequest.setSmallestDisplacement(0.1F); if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), 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; } LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } @Override public void onConnectionSuspended(int i) { } @Override public void onLocationChanged(Location location) { mLastLocation = location; //remove previous current location Marker if (marker != null){ marker.remove(); } double dLatitude = mLastLocation.getLatitude(); double dLongitude = mLastLocation.getLongitude(); marker = map.addMarker(new MarkerOptions().position(new LatLng(dLatitude, dLongitude)) .title("My Location").icon(BitmapDescriptorFactory .defaultMarker(BitmapDescriptorFactory.HUE_RED))); map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(dLatitude, dLongitude), 8)); } @Override public void onPause() { super.onPause(); if (mGoogleApiClient != null) { LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); } } protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(getContext()) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { } }
有缩放功能吗?另外我的api允许我访问用户的邮政编码.我可以用它吗?我要求用户显示他附近的位置.
这与我在这里的其他答案类似,但是,由于您正在扩展MapFragment并在Fragment中实现自定义行为,因此这是不同的.
下面是一个扩展SupportMapFragment的示例片段,在启动时它将获取用户的当前位置,放置标记并放大:
public class MapFragment extends SupportMapFragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { GoogleMap mGoogleMap; SupportMapFragment mapFrag; LocationRequest mLocationRequest; GoogleApiClient mGoogleApiClient; Location mLastLocation; Marker mCurrLocationMarker; @Override public void onResume() { super.onResume(); setUpMapIfNeeded(); } private void setUpMapIfNeeded() { if (mGoogleMap == null) { getMapAsync(this); } } @Override public void onPause() { super.onPause(); //stop location updates when Activity is no longer active if (mGoogleApiClient != null) { LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); } } @Override public void onMapReady(GoogleMap googleMap) { mGoogleMap=googleMap; mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); //Initialize Google Play Services if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { //Location Permission already granted buildGoogleApiClient(); mGoogleMap.setMyLocationEnabled(true); } else { //Request Location Permission checkLocationPermission(); } } else { buildGoogleApiClient(); mGoogleMap.setMyLocationEnabled(true); } } protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); mGoogleApiClient.connect(); } @Override public void onConnected(Bundle bundle) { mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(1000); mLocationRequest.setFastestInterval(1000); mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } } @Override public void onConnectionSuspended(int i) {} @Override public void onConnectionFailed(ConnectionResult connectionResult) {} @Override public void onLocationChanged(Location location) { mLastLocation = location; if (mCurrLocationMarker != null) { mCurrLocationMarker.remove(); } //Place current location marker LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng); markerOptions.title("Current Position"); markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)); mCurrLocationMarker = mGoogleMap.addMarker(markerOptions); //move map camera mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,11)); } public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99; private void checkLocationPermission() { if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)) { // Show an explanation to the user *asynchronously* -- don't block // this thread waiting for the user's response! After the user // sees the explanation, try again to request the permission. new AlertDialog.Builder(getActivity()) .setTitle("Location Permission Needed") .setMessage("This app needs the Location permission, please accept to use location functionality") .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { //Prompt the user once explanation has been shown ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION ); } }) .create() .show(); } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION ); } } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_LOCATION: { // 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. if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { if (mGoogleApiClient == null) { buildGoogleApiClient(); } mGoogleMap.setMyLocationEnabled(true); } } else { // permission denied, boo! Disable the // functionality that depends on this permission. Toast.makeText(getActivity(), "permission denied", Toast.LENGTH_LONG).show(); } return; } // other 'case' lines to check for other // permissions this app might request } } }
由于Location权限请求需要通过Activity,因此您需要将Activity中的结果路由到Fragment的onRequestPermissionsResult()
方法:
public class MainActivity extends AppCompatActivity { MapFragment mapFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); mapFragment = new MapFragment(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(R.id.mapframe, mapFragment); transaction.commit(); } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { if (requestCode == MapFragment.MY_PERMISSIONS_REQUEST_LOCATION){ mapFragment.onRequestPermissionsResult(requestCode, permissions, grantResults); } else { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } }
布局只包含MapFragment所在的FrameLayout.
activity_main.xml中:
结果
首先提示位置权限:
授予位置权限后,使用标记显示当前位置:
如果用户拒绝或撤消"位置"权限,则会在应用启动时显示:
一,解释:
然后,位置权限请求: