IOException请求关键Google Places / Maps API时出错

时间:2017-12-05 19:43:25

标签: java android google-maps google-places

我按照these方向尝试使用Google Places API在用户所在位置附近的所有餐馆上显示和添加标记。但是,我收到了这个错误:

12-05 11:23:33.378 1948-2857/com.google.android.gms.persistent W/GLSUser: [AppCertManager] IOException while requesting key: 
                                                                      java.io.IOException: Invalid device key response.
                                                                          at eyw.a(:com.google.android.gms@11743470:14)
                                                                          at eyw.a(:com.google.android.gms@11743470:65)
                                                                          at eyw.a(:com.google.android.gms@11743470:22)
                                                                          at eyu.a(:com.google.android.gms@11743470:4)
                                                                          at eyu.onTransact(:com.google.android.gms@11743470:4)
                                                                          at android.os.Binder.transact(Binder.java:387)
                                                                          at bvg.onTransact(:com.google.android.gms@11743470:3)
                                                                          at android.os.Binder.execTransact(Binder.java:453)

我在线搜索了一下,发现它可能与我的API密钥有关,或者我不通过Android应用程序允许某些权限,但我不知道是什么。代码有效,但因为我的密钥无效;它将列表大小(包含地点)返回为0,因此没有标记被绘制到我的应用程序的谷歌地图中。

我目前的代码:

public class FragmentMap extends Fragment implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{

private static final int FINE_LOCATION_PERMISSION_REQUEST = 1;
private static final int CONNECTION_RESOLUTION_REQUEST = 2;
private GoogleApiClient mGoogleApiClient;
private GoogleMap mMap;
public boolean permission = false;
Button showLoc;

private double mLat;
private double mLong;


public FragmentMap() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_map, null, false);
    SupportMapFragment mapFragment = (SupportMapFragment) this.getChildFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    buildGoogleAPIClient();

    showLoc = (Button) rootView.findViewById(R.id.showStore);
    showLoc.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            // hello
            if(permission == true){

                StringBuilder sbValue = new StringBuilder(sbMethod());
                PlacesTask placesTask = new PlacesTask();
                placesTask.execute(sbValue.toString());
            }
            else{
                Toast.makeText(getActivity(), "App does not have access to location services.", Toast.LENGTH_SHORT).show();
            }
        }
    });
    return rootView;
}

.
.
.

public StringBuilder sbMethod() {


    StringBuilder sb = new StringBuilder("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
    sb.append("location=" + mLat + "," + mLong);
    sb.append("&radius=5000");
    sb.append("&types=" + "restaurant");
    sb.append("&sensor=true");
    sb.append("&key=-My API Key is Here");

    Log.d("Map", "api: " + sb.toString());

    return sb;
}

private String downloadUrl(String strUrl) throws IOException {
    String data = "";
    InputStream iStream = null;
    HttpURLConnection urlConnection = null;
    try {
        URL url = new URL(strUrl);

        // Creating an http connection to communicate with url
        urlConnection = (HttpURLConnection) url.openConnection();

        // Connecting to url
        urlConnection.connect();

        // Reading data from url
        iStream = urlConnection.getInputStream();

        BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

        StringBuffer sb = new StringBuffer();

        String line = "";
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }

        data = sb.toString();

        br.close();

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        iStream.close();
        urlConnection.disconnect();
    }
    return data;
}

private class PlacesTask extends AsyncTask<String, Integer, String> {

    String data = null;

    // Invoked by execute() method of this object
    @Override
    protected String doInBackground(String... url) {
        try {
            data = downloadUrl(url[0]);
        } catch (Exception e) {
            Log.d("Background Task", e.toString());
        }
        return data;
    }

    // Executed after the complete execution of doInBackground() method
    @Override
    protected void onPostExecute(String result) {
        ParserTask parserTask = new ParserTask();

        // Start parsing the Google places in JSON format
        // Invokes the "doInBackground()" method of the class ParserTask
        parserTask.execute(result);
    }
}

private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String, String>>> {

    JSONObject jObject;

    // Invoked by execute() method of this object
    @Override
    protected List<HashMap<String, String>> doInBackground(String... jsonData) {

        List<HashMap<String, String>> places = null;
        Place_JSON placeJson = new Place_JSON();

        try {
            jObject = new JSONObject(jsonData[0]);

            places = placeJson.parse(jObject);

        } catch (Exception e) {
            Log.d("Exception", e.toString());
        }
        return places;
    }

    // Executed after the complete execution of doInBackground() method
    @Override
    protected void onPostExecute(List<HashMap<String, String>> list) {

        Log.d("Map", "list size: " + list.size());
        // Clears all the existing markers;
        mMap.clear();

        for (int i = 0; i < list.size(); i++) {

            // Creating a marker
            MarkerOptions markerOptions = new MarkerOptions();

            // Getting a place from the places list
            HashMap<String, String> hmPlace = list.get(i);


            // Getting latitude of the place
            double lat = Double.parseDouble(hmPlace.get("lat"));

            // Getting longitude of the place
            double lng = Double.parseDouble(hmPlace.get("lng"));

            // Getting name
            String name = hmPlace.get("place_name");

            Log.d("Map", "place: " + name);

            // Getting vicinity
            String vicinity = hmPlace.get("vicinity");

            LatLng latLng = new LatLng(lat, lng);

            // Setting the position for the marker
            markerOptions.position(latLng);

            markerOptions.title(name + " : " + vicinity);

            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));

            // Placing a marker on the touched position
            Marker m = mMap.addMarker(markerOptions);

        }
    }
}

public class Place_JSON {

    /**
     * Receives a JSONObject and returns a list
     */
    public List<HashMap<String, String>> parse(JSONObject jObject) {

        JSONArray jPlaces = null;
        try {
            /** Retrieves all the elements in the 'places' array */
            jPlaces = jObject.getJSONArray("results");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        /** Invoking getPlaces with the array of json object
         * where each json object represent a place
         */
        return getPlaces(jPlaces);
    }

    private List<HashMap<String, String>> getPlaces(JSONArray jPlaces) {
        int placesCount = jPlaces.length();
        List<HashMap<String, String>> placesList = new ArrayList<HashMap<String, String>>();
        HashMap<String, String> place = null;

        /** Taking each place, parses and adds to list object */
        for (int i = 0; i < placesCount; i++) {
            try {
                /** Call getPlace with place JSON object to parse the place */
                place = getPlace((JSONObject) jPlaces.get(i));
                placesList.add(place);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return placesList;
    }

    /**
     * Parsing the Place JSON object
     */
    private HashMap<String, String> getPlace(JSONObject jPlace) {

        HashMap<String, String> place = new HashMap<String, String>();
        String placeName = "-NA-";
        String vicinity = "-NA-";
        String latitude = "";
        String longitude = "";
        String reference = "";

        try {
            // Extracting Place name, if available
            if (!jPlace.isNull("name")) {
                placeName = jPlace.getString("name");
            }

            // Extracting Place Vicinity, if available
            if (!jPlace.isNull("vicinity")) {
                vicinity = jPlace.getString("vicinity");
            }

            latitude = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lat");
            longitude = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lng");
            reference = jPlace.getString("reference");

            place.put("place_name", placeName);
            place.put("vicinity", vicinity);
            place.put("lat", latitude);
            place.put("lng", longitude);
            place.put("reference", reference);

        } catch (JSONException e) {
            e.printStackTrace();
        }
        return place;
    }
}

我在Manifest中添加的相关权限:

<uses-permission android:name="android.permission.INTERNET" />
<permission
    android:name="cecs453.android.csulb.edu.recipeapp.permission.MAPS_RECEIVE"
    android:protectionLevel="signature"/>

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true"/>

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version"/> //within <application></application>

    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="-my API Key is pasted here-" /> //within <application></application>

我的gradle中的依赖:

dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
    exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.google.firebase:firebase-auth:11.6.2'
compile 'com.loopj.android:android-async-http:1.4.9'
testCompile 'junit:junit:4.12'
compile 'com.android.support:recyclerview-v7:26.+'
compile 'com.android.support:cardview-v7:26.+'
compile 'com.android.support:design:26.1.0'
implementation 'com.google.android.gms:play-services-maps:11.6.2'
compile 'com.google.android.gms:play-services:11.6.2'
compile 'com.google.android.gms:play-services-places:11.6.2'
compile "com.google.android.gms:play-services-location:11.6.2"
}

0 个答案:

没有答案