ApiException:9003:PLACES_API_ACCESS_NOT_CONFIGURED
Posted
技术标签:
【中文标题】ApiException:9003:PLACES_API_ACCESS_NOT_CONFIGURED【英文标题】:ApiException: 9003: PLACES_API_ACCESS_NOT_CONFIGURED 【发布时间】:2019-07-24 16:33:30 【问题描述】:我正在关注当前的地方教程:Select Current Place and Show Details on a Map
我不断收到以下运行时异常:
com.google.android.gms.common.api.ApiException: 9003: PLACES_API_ACCESS_NOT_CONFIGURED
我尝试了以下步骤:
-
在开发者控制台中启用 Places API
使用迁移指南:Migrating to the New Places SDK Client #New methods
对于新的 Places SDK,因为本教程使用已弃用的 Places SDK,即添加新的依赖项。
在我的 Android 清单文件中添加以下代码
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/api_key" />
-
重新生成了我的 API 密钥。
我也在使用似乎工作正常的 Maps SDK。 Maps SDK 和 Places API 都在开发者控制台上启用。
即使在尝试了所有这些步骤之后,我仍然会收到运行时错误:
ApiException: 9003: PLACES_API_ACCESS_NOT_CONFIGURED 错误
我的代码:
package com.arnav.akapplications.mapfinder;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.PersistableBundle;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.places.GeoDataClient;
import com.google.android.gms.location.places.PlaceDetectionClient;
import com.google.android.gms.location.places.PlaceLikelihood;
import com.google.android.gms.location.places.PlaceLikelihoodBufferResponse;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
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 com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.squareup.picasso.Picasso;
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, LocationListener
public static final String GOOGLE_ACCOUNT = "google_account";
private static final String TAG = MainActivity.class.getSimpleName();
public DrawerLayout drawerLayout;
public Toolbar toolbar;
TextView profileName,profileEmailID;
ImageView profilePhoto;
GoogleSignInAccount googleSignInAccount;
GoogleSignInClient googleSignInClient;
private GeoDataClient geoDataClient;
private PlaceDetectionClient placeDetectionClient;
private FusedLocationProviderClient fusedLocationProviderClient;
private GoogleMap mMap;
private Location lastKnownLocation;
private CameraPosition cameraPosition;
public LocationManager locationManager;
public Criteria criteria;
public String bestProvider;
public double latitude,longitude;
private boolean LocationPermissionGranted;
private static final int PERMISSION_REQUEST_ACCESS_LOCATION = 1;
private static final int DEFAULT_ZOOM = 15;
private final LatLng mDefaultLocation = new LatLng(-33.8523341, 151.2106085);
private static final int M_MAX_ENTRIES = 5;
private static final String KEY_CAMERA_POSITION = "camera_position";
private static final String KEY_LOCATION = "location";
private String[] likelyPlaceNames;
private String[] likelyPlaceAddresses;
private String[] likelyPlaceAttributions;
private LatLng[] likelyPlaceLatLng;
SupportMapFragment supportMapFragment;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
if(savedInstanceState!=null)
lastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION);
cameraPosition = savedInstanceState.getParcelable(KEY_CAMERA_POSITION);
setContentView(R.layout.activity_main);
// Places.initialize(getApplicationContext(), "AIzaSyCpmMHo0xQs-U_mXlGUOxFOReO0NlKv3CU");
//
// PlacesClient placesClient = Places.createClient(this);
googleSignInAccount = getIntent().getParcelableExtra(GOOGLE_ACCOUNT);
GoogleSignInOptions googleSignInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestEmail().build();
googleSignInClient = GoogleSignIn.getClient(this,googleSignInOptions);
drawerLayout=findViewById(R.id.drawer_layout);
toolbar=findViewById(R.id.toolbar);
ActionBar actionbar = getSupportActionBar();
actionbar.setDisplayHomeAsUpEnabled(true);
actionbar.setHomeButtonEnabled(true);
actionbar.setHomeAsUpIndicator(R.drawable.ic_menu_black_24dp);
geoDataClient = Places.getGeoDataClient(this);
placeDetectionClient = Places.getPlaceDetectionClient(this);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
supportMapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
supportMapFragment.getMapAsync(this);
NavigationView navigationView=findViewById(R.id.navigation_view);
profileName = navigationView.getHeaderView(0).findViewById(R.id.profileName);
profileEmailID = navigationView.getHeaderView(0).findViewById(R.id.profileEmailID);
profilePhoto = navigationView.getHeaderView(0).findViewById(R.id.profilePhoto);
Uri photoUrl = googleSignInAccount.getPhotoUrl();
profileName.setText(googleSignInAccount.getDisplayName());
profileEmailID.setText(googleSignInAccount.getEmail());
Picasso.with(getApplicationContext())
.load(photoUrl.toString())
.placeholder(android.R.drawable.sym_def_app_icon)
.resize(100, 100)
.transform(new CircleTransform())
.centerCrop()
.into(profilePhoto);
navigationView.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener()
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item)
// item.setChecked(true);
switch(item.getItemId())
case R.id.search_books: //do something
break;
case R.id.search_movie: //do something
break;
case R.id.logout:
googleSignInClient.signOut().addOnCompleteListener(new OnCompleteListener<Void>()
@Override
public void onComplete(@NonNull Task<Void> task)
Intent intent = new Intent(MainActivity.this,LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
);
break;
case R.id.finish:
System.exit(0);
break;
drawerLayout.closeDrawers();
return true;
);
@Override
public void onSaveInstanceState(Bundle outState)
if(mMap != null)
outState.putParcelable(KEY_CAMERA_POSITION,mMap.getCameraPosition());
outState.putParcelable(KEY_LOCATION,lastKnownLocation);
super.onSaveInstanceState(outState);
@Override
public void onBackPressed()
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START))
drawer.closeDrawer(GravityCompat.START);
else
super.onBackPressed();
@Override
public boolean onCreateOptionsMenu(Menu menu)
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_items,menu);
return super.onCreateOptionsMenu(menu);
@Override
public boolean onOptionsItemSelected(MenuItem item)
switch(item.getItemId())
case R.id.aboutProfile:
Intent intent = new Intent(this,ProfileActivity.class);
intent.putExtra(ProfileActivity.GOOGLE_ACCOUNT,googleSignInAccount);
startActivity(intent);
break;
case android.R.id.home:
drawerLayout.openDrawer(GravityCompat.START);
break;
case R.id.option_get_place:
showCurrentPlace();
break;
return true;
private void updateLocationUI()
if(mMap == null)
return;
try
if(LocationPermissionGranted)
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
else
mMap.setMyLocationEnabled(false);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
lastKnownLocation = null;
getLocationPermission();
catch (SecurityException e)
Log.e("Exception: %s",e.getMessage() );
private void getLocationPermission()
if(ContextCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
LocationPermissionGranted = true;
else
ActivityCompat.requestPermissions(this,new String[]Manifest.permission.ACCESS_FINE_LOCATION,PERMISSION_REQUEST_ACCESS_LOCATION);
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
LocationPermissionGranted = false;
switch(requestCode)
case PERMISSION_REQUEST_ACCESS_LOCATION:
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
LocationPermissionGranted = true;
updateLocationUI();
private void getDeviceLocation()
try
if(LocationPermissionGranted)
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
criteria = new Criteria();
bestProvider = String.valueOf(locationManager.getBestProvider(criteria, true));
Location location = locationManager.getLastKnownLocation(bestProvider);
if(location != null)
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(),location.getLongitude()),DEFAULT_ZOOM));
else
locationManager.requestLocationUpdates(bestProvider,1000,0,this);
catch(SecurityException e)
Log.e("Exception : %s" , e.getMessage());
@Override
public void onMapReady(GoogleMap googleMap)
mMap = googleMap;
googleMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter()
@Override
public View getInfoWindow(Marker marker)
return null;
@Override
public View getInfoContents(Marker marker)
View infoWindow = getLayoutInflater().inflate(R.layout.custom_info_contents,null);
TextView title = ((TextView) infoWindow.findViewById(R.id.title));
TextView snippet = ((TextView)infoWindow.findViewById(R.id.snippet));
title.setText(marker.getTitle());
snippet.setText(marker.getSnippet());
return infoWindow;
);
getLocationPermission();
updateLocationUI();
getDeviceLocation();
private void showCurrentPlace()
if(mMap == null)
Toast.makeText(this, "hello", Toast.LENGTH_LONG).show();
if(LocationPermissionGranted)
@SuppressLint("MissingPermission") final Task<PlaceLikelihoodBufferResponse> placeResult = placeDetectionClient.getCurrentPlace(null);
placeResult.addOnCompleteListener(new OnCompleteListener<PlaceLikelihoodBufferResponse>()
@Override
public void onComplete(@NonNull Task<PlaceLikelihoodBufferResponse> task)
if(task.isSuccessful() && task.getResult()!= null)
PlaceLikelihoodBufferResponse placeLikelihoodBufferResponse = task.getResult();
int count,i=0;
if(placeLikelihoodBufferResponse.getCount() < M_MAX_ENTRIES)
count = placeLikelihoodBufferResponse.getCount();
else
count = M_MAX_ENTRIES;
likelyPlaceNames = new String[count];
likelyPlaceAddresses = new String[count];
likelyPlaceAttributions = new String[count];
likelyPlaceLatLng = new LatLng[count];
for(PlaceLikelihood placeLikelihood : placeLikelihoodBufferResponse)
likelyPlaceNames[i] = (String) placeLikelihood.getPlace().getName();
likelyPlaceAddresses[i] = (String) placeLikelihood.getPlace().getAddress();
likelyPlaceAttributions[i] = (String) placeLikelihood.getPlace().getAttributions();
likelyPlaceLatLng[i] = placeLikelihood.getPlace().getLatLng();
i++;
if (i > (count - 1))
break;
placeLikelihoodBufferResponse.release();
openPlacesDialog();
else
Log.e(TAG,"Exception :%s" + task.getException());
);
else
Log.i(TAG,"the user did not grant location permission");
mMap.addMarker(new MarkerOptions().title(getString(R.string.default_info_title)).position(mDefaultLocation).snippet(getString(R.string.default_info_snippet)));
getLocationPermission();
private void openPlacesDialog()
DialogInterface.OnClickListener dialogListener = new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
LatLng markerLatLng = likelyPlaceLatLng[which];
String markerSnippet = likelyPlaceAddresses[which];
if(likelyPlaceAttributions[which] != null)
markerSnippet = markerSnippet + "\n" + likelyPlaceAttributions[which];
mMap.addMarker(new MarkerOptions().title(likelyPlaceNames[which]).position(markerLatLng).snippet(markerSnippet));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(markerLatLng,DEFAULT_ZOOM));
;
AlertDialog dialog = new AlertDialog.Builder(this).setTitle(R.string.pick_place).setItems(likelyPlaceNames,dialogListener).show();
dialog.create();
@Override
public void onLocationChanged(Location location)
locationManager.removeUpdates(this);
//open the map:
latitude = location.getLatitude();
longitude = location.getLongitude();
Toast.makeText(MainActivity.this, "latitude:" + latitude + " longitude:" + longitude, Toast.LENGTH_SHORT).show();
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
@Override
public void onProviderEnabled(String provider)
@Override
public void onProviderDisabled(String provider)
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.arnav.akapplications.mapfinder">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/api_key" />
<activity android:name=".ProfileActivity"/>
<activity android:name=".MainActivity"
android:theme="@style/AppTheme"/>
<activity android:name=".LoginActivity"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
应用级 build.gradle 文件:
apply plugin: 'com.android.application'
android
compileSdkVersion 27
defaultConfig
applicationId "com.arnav.akapplications.mapfinder"
minSdkVersion 15
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
resValue "string", "google_maps_key", (project.findProperty("GOOGLE_MAPS_API_KEY") ?: "")
resValue "string", "google_places_key", (project.findProperty("GOOGLE_PLACES_API_KEY") ?: "")
buildTypes
release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
dependencies
implementation fileTree(dir: 'libs', include: ['*.jar'])
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.android.support:design:27.1.1'
implementation 'com.google.android.gms:play-services-location:16.0.0'
implementation 'com.google.android.libraries.places:places-compat:1.0.0'
【问题讨论】:
过去两天我也面临同样的问题。如果您找到解决方案,请告诉我。 当然。您还尝试过哪些无效的方法? @arnavJJ 我认为您无法为您的代码实施迁移指南。我正在发布我的答案。查看并实施它。 【参考方案1】:很多朋友建议我发布我是如何在我的项目上实现这个(自动完成)的。所以我建议你看看这个迁移指南并逐步在你的项目上实现。
迁移指南:-https://developers.google.com/places/android-sdk/client-migration
转到此link 以创建 API 密钥:
按照以下步骤在您的项目中实施自动完成:-
自动完成有两种实现方式。
-
使用意图
使用 AutocompleteFragment
在这两种情况下,请按照以下步骤操作:-
1. Add this line in build.gradle file
dependencies
implementation 'com.google.android.libraries.places:places:2.1.0'
2. Add other dependencies (This is optional) .
dependencies
implementation 'com.google.android.libraries.places:places-compat:1.0.0'
implementation 'com.google.android.gms:play-services-places:16.0.0'
3. // Add an import statement for the client library.
import com.google.android.libraries.places.api.Places;
// Initialize Places.
Places.initialize(getApplicationContext(), apiKey);
// Create a new Places client instance.
PlacesClient placesClient = Places.createClient(this);
---------现在选择您要在项目中实施的任何方法。-----
使用意图
if (!Places.isInitialized())
Places.initialize(getApplicationContext(), "YOUR_API_KEY");
...
// Set the fields to specify which types of place data to return.
List<Place.Field> fields = Arrays.asList(Place.Field.ID, Place.Field.NAME);
// Start the autocomplete intent.
Intent intent = new Autocomplete.IntentBuilder(
AutocompleteActivityMode.FULLSCREEN, fields)
.build(this);
startActivityForResult(intent, AUTOCOMPLETE_REQUEST_CODE);
and OnActivityResult method-------
/**
* Override the activity's onActivityResult(), check the request code, and
* do something with the returned place data (in this example it's place name and place ID).
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
if (requestCode == AUTOCOMPLETE_REQUEST_CODE)
if (resultCode == RESULT_OK)
Place place = Autocomplete.getPlaceFromIntent(data);
Log.i(TAG, "Place: " + place.getName() + ", " + place.getId());
else if (resultCode == AutocompleteActivity.RESULT_ERROR)
// TODO: Handle the error.
Status status = Autocomplete.getStatusFromIntent(data);
Log.i(TAG, status.getStatusMessage());
else if (resultCode == RESULT_CANCELED)
// The user canceled the operation.
使用片段
在 .xml 文件上初始化此自动完成片段
<fragment
android:id="@+id/autocomplete_fragment"
android:layout_
android:layout_
android:name=
"com.google.android.libraries.places.widget.AutocompleteSupportFragment"
/>
-------------- 和.class文件--------------------------
初始化 Places,传递应用程序上下文和您的 API 密钥。 初始化 AutocompleteSupportFragment。 调用 setPlaceFields() 以指示您想要获取的地点数据的类型。 添加 PlaceSelectionListener 以对结果进行处理,并处理可能发生的任何错误。 以下示例显示了向 Activity 添加自动完成小部件:
if (!Places.isInitialized())
Places.initialize(getApplicationContext(), "YOUR_API_KEY");
// Initialize the AutocompleteSupportFragment.
AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
getSupportFragmentManager().findFragmentById(R.id.autocomplete_fragment);
autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME));
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener()
@Override
public void onPlaceSelected(Place place)
// TODO: Get info about the selected place.
Log.i(TAG, "Place: " + place.getName() + ", " + place.getId());
@Override
public void onError(Status status)
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
);
然后像这样从选定的地方获取 LATLONG:-
LatLng latLng = place.getLatLng();
String mStringLatitude = String.valueOf(latLng.latitude);
String mStringLongitude = String.valueOf(latLng.longitude);
希望这会对你有所帮助。
【讨论】:
places_compat有什么用? @IgorGanapolsky 抱歉回复晚了。但请参考此链接了解 place_compact。developers.google.com/places/android-sdk/…以上是关于ApiException:9003:PLACES_API_ACCESS_NOT_CONFIGURED的主要内容,如果未能解决你的问题,请参考以下文章
Laravel ->Exceptions ->ApiException 自定义错误异常的封装
(ApiException.class) -> 从 java 到 C#?
Google 登录失败(ApiException:12501)