我尝试使用此示例代码访问当前位置(我已经配置了我的API密钥):
MapActivity:
public class MapsActivityCurrentPlace extends AppCompatActivity
implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = MapsActivityCurrentPlace.class.getSimpleName();
private GoogleMap mMap;
private CameraPosition mCameraPosition;
// The entry point to Google Play services, used by the Places API and Fused Location Provider.
private GoogleApiClient mGoogleApiClient;
// A default location (Sydney, Australia) and default zoom to use when location permission is
// not granted.
private final LatLng mDefaultLocation = new LatLng(-33.8523341, 151.2106085);
private static final int DEFAULT_ZOOM = 15;
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private boolean mLocationPermissionGranted;
// The geographical location where the device is currently located. That is, the last-known
// location retrieved by the Fused Location Provider.
private Location mLastKnownLocation;
// Keys for storing activity state.
private static final String KEY_CAMERA_POSITION = "camera_position";
private static final String KEY_LOCATION = "location";
// Used for selecting the current place.
private final int mMaxEntries = 5;
private String[] mLikelyPlaceNames = new String[mMaxEntries];
private String[] mLikelyPlaceAddresses = new String[mMaxEntries];
private String[] mLikelyPlaceAttributions = new String[mMaxEntries];
private LatLng[] mLikelyPlaceLatLngs = new LatLng[mMaxEntries];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retrieve location and camera position from saved instance state.
if (savedInstanceState != null) {
mLastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION);
mCameraPosition = savedInstanceState.getParcelable(KEY_CAMERA_POSITION);
}
// Retrieve the content view that renders the map.
setContentView(R.layout.activity_maps);
// Build the Play services client for use by the Fused Location Provider and the Places API.
// Use the addApi() method to request the Google Places API and the Fused Location Provider.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */,
this /* OnConnectionFailedListener */)
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.build();
mGoogleApiClient.connect();
}
/**
* Saves the state of the map when the activity is paused.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
if (mMap != null) {
outState.putParcelable(KEY_CAMERA_POSITION, mMap.getCameraPosition());
outState.putParcelable(KEY_LOCATION, mLastKnownLocation);
super.onSaveInstanceState(outState);
}
}
/**
* Builds the map when the Google Play services client is successfully connected.
*/
@Override
public void onConnected(Bundle connectionHint) {
// Build the map.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
/**
* Handles failure to connect to the Google Play services client.
*/
@Override
public void onConnectionFailed(@NonNull ConnectionResult result) {
// Refer to the reference doc for ConnectionResult to see what error codes might
// be returned in onConnectionFailed.
Log.d(TAG, "Play services connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
/**
* Handles suspension of the connection to the Google Play services client.
*/
@Override
public void onConnectionSuspended(int cause) {
Log.d(TAG, "Play services connection suspended");
}
/**
* Sets up the options menu.
* @param menu The options menu.
* @return Boolean.
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.current_place_menu, menu);
return true;
}
/**
* Handles a click on the menu option to get a place.
* @param item The menu item to handle.
* @return Boolean.
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.option_get_place) {
showCurrentPlace();
}
return true;
}
/**
* Manipulates the map when it's available.
* This callback is triggered when the map is ready to be used.
*/
@Override
public void onMapReady(GoogleMap map) {
mMap = map;
// Use a custom info window adapter to handle multiple lines of text in the
// info window contents.
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
@Override
// Return null here, so that getInfoContents() is called next.
public View getInfoWindow(Marker arg0) {
return null;
}
@Override
public View getInfoContents(Marker marker) {
// Inflate the layouts for the info window, title and snippet.
View infoWindow = getLayoutInflater().inflate(R.layout.custom_info_contents,
(FrameLayout)findViewById(R.id.map), false);
TextView title = ((TextView) infoWindow.findViewById(R.id.title));
title.setText(marker.getTitle());
TextView snippet = ((TextView) infoWindow.findViewById(R.id.snippet));
snippet.setText(marker.getSnippet());
return infoWindow;
}
});
// Turn on the My Location layer and the related control on the map.
updateLocationUI();
// Get the current location of the device and set the position of the map.
getDeviceLocation();
}
/**
* Gets the current location of the device, and positions the map's camera.
*/
private void getDeviceLocation() {
/*
* Request location permission, so that we can get the location of the
* device. The result of the permission request is handled by a callback,
* onRequestPermissionsResult.
*/
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
} else {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
/*
* Get the best and most recent location of the device, which may be null in rare
* cases when a location is not available.
*/
if (mLocationPermissionGranted) {
mLastKnownLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
}
// Set the map's camera position to the current location of the device.
if (mCameraPosition != null) {
mMap.moveCamera(CameraUpdateFactory.newCameraPosition(mCameraPosition));
} else if (mLastKnownLocation != null) {
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(mLastKnownLocation.getLatitude(),
mLastKnownLocation.getLongitude()), DEFAULT_ZOOM));
} else {
Log.d(TAG, "Current location is null. Using defaults.");
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
mMap.getUiSettings().setMyLocationButtonEnabled(false);
}
}
/**
* Handles the result of the request for location permissions.
*/
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[],
@NonNull int[] grantResults) {
mLocationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
}
}
}
updateLocationUI();
}
/**
* Prompts the user to select the current place from a list of likely places, and shows the
* current place on the map - provided the user has granted location permission.
*/
private void showCurrentPlace() {
if (mMap == null) {
return;
}
if (mLocationPermissionGranted) {
// Get the likely places - that is, the businesses and other points of interest that
// are the best match for the device's current location.
@SuppressWarnings("MissingPermission")
PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
.getCurrentPlace(mGoogleApiClient, null);
result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
@Override
public void onResult(@NonNull PlaceLikelihoodBuffer likelyPlaces) {
int i = 0;
mLikelyPlaceNames = new String[mMaxEntries];
mLikelyPlaceAddresses = new String[mMaxEntries];
mLikelyPlaceAttributions = new String[mMaxEntries];
mLikelyPlaceLatLngs = new LatLng[mMaxEntries];
for (PlaceLikelihood placeLikelihood : likelyPlaces) {
// Build a list of likely places to show the user. Max 5.
mLikelyPlaceNames[i] = (String) placeLikelihood.getPlace().getName();
mLikelyPlaceAddresses[i] = (String) placeLikelihood.getPlace().getAddress();
mLikelyPlaceAttributions[i] = (String) placeLikelihood.getPlace()
.getAttributions();
mLikelyPlaceLatLngs[i] = placeLikelihood.getPlace().getLatLng();
i++;
if (i > (mMaxEntries - 1)) {
break;
}
}
// Release the place likelihood buffer, to avoid memory leaks.
likelyPlaces.release();
// Show a dialog offering the user the list of likely places, and add a
// marker at the selected place.
openPlacesDialog();
}
});
} else {
// Add a default marker, because the user hasn't selected a place.
mMap.addMarker(new MarkerOptions()
.title(getString(R.string.default_info_title))
.position(mDefaultLocation)
.snippet(getString(R.string.default_info_snippet)));
}
}
/**
* Displays a form allowing the user to select a place from a list of likely places.
*/
private void openPlacesDialog() {
// Ask the user to choose the place where they are now.
DialogInterface.OnClickListener listener =
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// The "which" argument contains the position of the selected item.
LatLng markerLatLng = mLikelyPlaceLatLngs[which];
String markerSnippet = mLikelyPlaceAddresses[which];
if (mLikelyPlaceAttributions[which] != null) {
markerSnippet = markerSnippet + "\n" + mLikelyPlaceAttributions[which];
}
// Add a marker for the selected place, with an info window
// showing information about that place.
mMap.addMarker(new MarkerOptions()
.title(mLikelyPlaceNames[which])
.position(markerLatLng)
.snippet(markerSnippet));
// Position the map's camera at the location of the marker.
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(markerLatLng,
DEFAULT_ZOOM));
}
};
// Display the dialog.
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle(R.string.pick_place)
.setItems(mLikelyPlaceNames, listener)
.show();
}
/**
* Updates the map's UI settings based on whether the user has granted location permission.
*/
private void updateLocationUI() {
if (mMap == null) {
return;
}
/*
* Request location permission, so that we can get the location of the
* device. The result of the permission request is handled by a callback,
* onRequestPermissionsResult.
*/
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
} else {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
}
if (mLocationPermissionGranted) {
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
} else {
mMap.setMyLocationEnabled(false);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
mLastKnownLocation = null;
}
}
}
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="packagename">
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<permission
android:name="package.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.envent_pc03.googlemap.permission.MAPS_RECEIVE"/>
<uses-feature android:name="android.hardware.location.gps" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<!--
The API key for Google Maps-based APIs.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
<activity
android:name="com.example.currentplacedetailsonmap.MapsActivityCurrentPlace"
android:label="@string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
我的问题是它没有获得当前位置,直到预先安装的谷歌地图没有获得这样的权限:
如何通过我预先安装的谷歌地图的应用程序获得上述权限并获取当前位置,而不使用预先安装的谷歌地图。