places_compat

дую текущему учебнику по месту:Выберите текущее место и показать детали на карте

Я продолжаю получать следующее исключение времени выполнения:

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

Я попробовал следующие шаги:

Включение API Places в консоли разработчикаИспользуя руководство по миграции:Переход на SDK-клиент New Places # Новые методы для нового 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, который, кажется, работает нормально. И SDK для карт, и 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);

                Tex,tView 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'

}

Ответы на вопрос(1)

Ваш ответ на вопрос