从 Google 地图请求 JSON 给我 REQUEST_DENIED

Requesting JSON from Google Maps gives me REQUEST_DENIED

我想知道为什么我的请求总是被拒绝。 我很确定我的 API 键是正确的,我在 Google 控制台中选择了 android,给它我的 sha1 和我的项目名称,然后抓住 API 键并粘贴它在我的项目中。但是,如果我尝试任何操作,它仍然会一直给我 REQUEST_DENIED。我假设这与我构建 URL 的方式有关,或者基础 URL 是否损坏,或者可能是我请求数据的方式。

我对此很陌生,几天前才开始玩,所以任何帮助将不胜感激。

这是我的代码 -

MainActivity

package io.github.invainn.quickeat;

import android.app.Activity;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.location.places.PlaceLikelihood;
import com.google.android.gms.location.places.PlaceLikelihoodBuffer;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.maps.model.LatLng;


public class MainActivity extends ActionBarActivity implements AdapterView.OnItemSelectedListener, GoogleApiClient.OnConnectionFailedListener {

    Spinner spinner;
    GoogleApiClient mGoogleApiClient;

    private CharSequence mostLikelyPlace;
    private LatLng mostLikelyPlaceLatLng;

    private static final String LOG_TAG = "MainActivity";
    private static final int GOOGLE_API_CLIENT_ID = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mGoogleApiClient = new GoogleApiClient.Builder(MainActivity.this)
                .addApi(Places.PLACE_DETECTION_API)
                .enableAutoManage(this, GOOGLE_API_CLIENT_ID, this)
                .build();

        spinner = (Spinner) findViewById(R.id.spinner);

        ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.choices, android.R.layout.simple_spinner_item);
        spinner.setAdapter(adapter);

        setupSearchButton();

        PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi.getCurrentPlace(mGoogleApiClient, null);
        result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
            @Override
            public void onResult(PlaceLikelihoodBuffer likelyPlaces) {
                for (PlaceLikelihood placeLikelihood : likelyPlaces) {
                    Log.i(LOG_TAG, String.format("Place '%s' with " +
                                    "likelihood: %g",
                            placeLikelihood.getPlace().getName(),
                            placeLikelihood.getLikelihood()));
                            if(placeLikelihood.getLikelihood() >= .20) {
                                mostLikelyPlace = placeLikelihood.getPlace().getName();
                                mostLikelyPlaceLatLng = placeLikelihood.getPlace().getLatLng();
                            }
                }
                Toast.makeText(MainActivity.this, "Your current location: " + mostLikelyPlace, Toast.LENGTH_LONG).show();
                likelyPlaces.release();
            }
        });
    }

    private void setupSearchButton() {
        Button searchKeyword = (Button)findViewById(R.id.searchKeyword);

        searchKeyword.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "Switched to ListActivity", Toast.LENGTH_SHORT).show();

                Bundle args = new Bundle();
                args.putParcelable("currentLocation", mostLikelyPlaceLatLng);

                Intent intent = new Intent(MainActivity.this, List_Activity.class);
                intent.putExtra("bundle", args);
                startActivity(intent);
            }
        });
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }
}

List_Activity

package io.github.invainn.quickeat;

import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.text.Html;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.ui.PlacePicker;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;

import org.apache.http.HttpRequestFactory;

import java.net.URL;


public class List_Activity extends ActionBarActivity {
    private static final int PLACE_PICKER_REQUEST = 1;
    private static final String apiAddress = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_);

        // Receive bundle and get currentlocation
        Bundle bundle = getIntent().getParcelableExtra("bundle");
        LatLng currentLocation = bundle.getParcelable("currentLocation");

        new QueryRequest().execute(currentLocation);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_info, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

查询请求

package io.github.invainn.quickeat;

import android.os.AsyncTask;
import android.util.Log;

import com.google.android.gms.location.places.Place;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.LatLng;

import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestFactory;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;

/**
 * Created by Anthony on 4/28/2015.
 */
public class QueryRequest extends AsyncTask<LatLng, Integer, String>  {

    private static final String LOG_TAG = "QueryRequest";
    private static final String apiBaseUrl = "https://maps.googleapis.com/maps/api/place";

    private static final String search = "/textsearch";
    private static final String jsonOut = "/json";

    private static final String apiKey = "MYAPIKEY";

    public static ArrayList<Place> search(String keyword, double lat, double lng) {
        ArrayList<Place> resultList = null;

        HttpURLConnection conn = null;
        StringBuilder jsonResults = new StringBuilder();

        try {
            StringBuilder sb = new StringBuilder(apiBaseUrl);
            sb.append(search);
            sb.append(jsonOut);
           // sb.append("?sensor=false");
            sb.append("?key=" + apiKey);
            sb.append("&keyword=" + URLEncoder.encode(keyword, "utf8"));
            sb.append("&location=" + String.valueOf(lat) + "," + String.valueOf(lng));
            sb.append("&radius=500");

            //System.out.println(sb.toString());

            URL url = new URL(sb.toString());
            conn = (HttpURLConnection) url.openConnection();
            InputStreamReader in = new InputStreamReader(conn.getInputStream());

            // need to test but im pretty sure this works
            int read;
            char[] buff = new char[1024];
            while ((read = in.read(buff)) != -1) {
                jsonResults.append(buff, 0, read);
            }

            System.out.println(jsonResults);

        } catch (MalformedURLException e) {
            Log.e(LOG_TAG, "Error processing Places API URL", e);
            return null;
        } catch (IOException e) {
            Log.e(LOG_TAG, "Error connecting to Places API", e);
            return null;
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        return null;
    }

    @Override
    protected String doInBackground(LatLng... params) {
        LatLng loc = params[0];
        search("chinese", loc.latitude, loc.longitude );
        return null;
    }
}

如果我的代码还有其他问题,请指出,我很想知道。

按照以下步骤操作:

Google 控制台:

APIs & Auth -> APIs(Google 地点 API Web 服务) 已启用。

APIs & Auth -> 凭据 -> 创建新密钥 -> 浏览器密钥(您需要创建一个浏览器密钥而不是 Android 密钥。)。

对于浏览器密钥,您无需使用 Sha1 创建特定密钥。

您需要启用以下地方api

-Google 地点 API Web 服务

并且您需要使用服务器密钥来获取地点数据。

要获取服务器密钥,请按照以下步骤操作: APIs & Auth -> 凭据 -> 创建新密钥 -> 服务器密钥

浏览器密钥无效。

我遇到了同样的问题,我用同样的方法解决了它。

按照以下步骤操作:

Google 控制台 Api:

(Google Places API Web 服务) 已启用。

APIs & Auth -> 凭据 -> 创建新密钥 ->

然后select None option in key restriction......