web-dev-qa-db-ja.com

ApiException:9003:PLACES_API_ACCESS_NOT_CONFIGURED

私は現在の場所のチュートリアルに従っています: 現在の場所を選択し、地図に詳細を表示

次のランタイム例外が発生し続けます。

com.google.Android.gms.common.api.ApiException:9003:PLACES_API_ACCESS_NOT_CONFIGURED

私は次の手順を試しました:

  1. 開発者コンソールでPlaces APIを有効にする
  2. 移行ガイドの使用: 新しいPlaces SDKクライアントへの移行#Newメソッド このチュートリアルは非推奨のPlaces SDKを使用していたため、新しい依存関係を追加しました。
  3. 次のコードをmy Android Manifest Fileに追加します
<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" />
  1. 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'

}
10
arnavJJ

多くの友達から、これ(オートコンプリート)をプロジェクトに実装する方法を投稿するように勧められました。この移行ガイドを見て、プロジェクトに段階的に実装することをお勧めします。

移行ガイド:- https://developers.google.com/places/Android-sdk/client-migration

これに移動 link APIキーを作成するには:

次の手順に従って、プロジェクトにオートコンプリートを実装します。

オートコンプリートに実装するには2つの方法があります。

  1. インテントの使用
  2. 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.
                }
            }
        }
    

    Fregmentの使用

    .xmlファイルでこのAutocomplete Fregmentを初期化します

    <fragment
      Android:id="@+id/autocomplete_fragment"
      Android:layout_width="match_parent"
      Android:layout_height="wrap_content"
      Android:name=
    "com.google.Android.libraries.places.widget.AutocompleteSupportFragment"
      />
    

    --------------および.classファイル--------------------------

    場所を初期化し、アプリケーションコンテキストとAPIキーを渡します。 AutocompleteSupportFragmentを初期化します。 setPlaceFields()を呼び出して、取得する場所データのタイプを示します。 PlaceSelectionListenerを追加して、結果を処理し、発生する可能性のあるエラーを処理します。次の例は、オートコンプリートウィジェットをアクティビティに追加する方法を示しています。

     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);

これがお役に立てば幸いです。

8
Rahul Kushwaha