Android:调用 https://maps.googleapis.com/maps/api/geocode/json 时获取 HTTP 403 Forbidden
Android: Getting HTTP 403 Forbidden upon calling https://maps.googleapis.com/maps/api/geocode/json
我一直在尝试使用 Google api,更具体地说,这个 URL 来获取 U.S 州和城市,我一直在使用 403 Forbidden HTTP错误信息,我的代码如下:
private static boolean getAddressResult(String input, StringBuilder jsonResults) {
HttpURLConnection conn = null;
try {
String mapUrl;
StringBuilder sb = new StringBuilder(https://maps.googleapis.com/maps/api/geocode/json);
sb.append("?sensor=false&address=" + URLEncoder.encode(input, "utf8"));
mapUrl = sb.toString();
URL url = new URL(mapUrl);
Logger.d(TAG, ""+ url);
Logger.d(TAG, "trying to read");
conn = (HttpURLConnection) url.openConnection();
int status = conn.getResponseCode();
Logger.d(TAG, "status: "+ status);
InputStreamReader in = new InputStreamReader(conn.getInputStream());
// Load the results into a StringBuilder
int read;
char[] buff = new char[1024];
long currentTime = System.currentTimeMillis();
while ((read = in.read(buff)) != -1) {
Logger.d("NetworkUtil", "trying to parse");
long elapsedTime = System.currentTimeMillis();
if(elapsedTime-currentTime>=5000)
return false;
jsonResults.append(buff, 0, read);
}
} catch (MalformedURLException e) {
Logger.e(LOG_TAG, "Error processing Places API URL", e);
return true;
} catch (IOException e) {
Logger.e(LOG_TAG, "Error connecting to Places API", e);
return true;
} finally {
if (conn != null) {
conn.disconnect();
}
}
return false;
}
我尝试了不同的替代方法,包括将 URL 从 HTTP 更改为 HTTPS,我不确定此时我到底缺少什么,很少有此 Web 服务调用返回的情况200 次成功,但大多数时候它只是失败并显示 403 HTTP 错误代码,此时任何建议都会有所帮助,我还附上了来自 Logcat 的日志:
Error connecting to Places API
java.io.FileNotFoundException: https://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=08080
at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
at .getAddressResult(NetworkUtil.java:217)
at .access[=14=]0(NetworkUtil.java:30)
at $ResolveCityTask.doInBackground(NetworkUtil.java:81)
at $ResolveCityTask.doInBackground(NetworkUtil.java:42)
- 不再需要
sensor
参数。
- 此外,您没有在请求中提供 API_KEY url。
StringBuilder
的字符串应该用双引号括起来。
- 你的logcat地址字符串是08080,应该是字符串。
- 您应该在后台线程中执行您的 API 请求。
一个示例 API 需要 URL 应该是这样的:
https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&key=API_KEY
示例修改代码:
String API_KEY = "YOUR_API_KEY_STRING";
String input = "1600+Amphitheatre+Parkway,+Mountain+View,+CA";
private static boolean getAddressResult(String input, StringBuilder jsonResults) {
try {
URL requestUrl = new URL("https://maps.googleapis.com/maps/api/geocode/json?address=" + input " + &key=" + API_KEY;
);
HttpURLConnection connection = (HttpURLConnection)requestUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader reader = null;
InputStream inputStream = connection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return false;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
long elapsedTime = System.currentTimeMillis();
if(elapsedTime-currentTime>=5000) {
return false;
}
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
return false;
}
Log.d("Test", buffer.toString());
return buffer.toString();
}
else {
Log.i(TAG, "Unsuccessful HTTP Response Code: " + responseCode);
return false
}
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error processing Places API URL", e);
return false;
} catch (IOException e) {
Log.e(LOG_TAG, "Error connecting to Places API", e);
return false;
} catch (Expcetion e) {
return false;
}
return false;
}
此示例代码应 运行 在您的后台方法中。
还需要确保在清单文件中添加互联网权限。
<uses-permission android:name="android.permission.INTERNET" />
您还可以通过添加来检查您的互联网连接
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
并调用此方法查看您的互联网是否已连接:
private boolean isNetworkAvailable() {
ConnectivityManager manager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected()) {
isAvailable = true;
}
return isAvailable;
}
我一直在尝试使用 Google api,更具体地说,这个 URL 来获取 U.S 州和城市,我一直在使用 403 Forbidden HTTP错误信息,我的代码如下:
private static boolean getAddressResult(String input, StringBuilder jsonResults) {
HttpURLConnection conn = null;
try {
String mapUrl;
StringBuilder sb = new StringBuilder(https://maps.googleapis.com/maps/api/geocode/json);
sb.append("?sensor=false&address=" + URLEncoder.encode(input, "utf8"));
mapUrl = sb.toString();
URL url = new URL(mapUrl);
Logger.d(TAG, ""+ url);
Logger.d(TAG, "trying to read");
conn = (HttpURLConnection) url.openConnection();
int status = conn.getResponseCode();
Logger.d(TAG, "status: "+ status);
InputStreamReader in = new InputStreamReader(conn.getInputStream());
// Load the results into a StringBuilder
int read;
char[] buff = new char[1024];
long currentTime = System.currentTimeMillis();
while ((read = in.read(buff)) != -1) {
Logger.d("NetworkUtil", "trying to parse");
long elapsedTime = System.currentTimeMillis();
if(elapsedTime-currentTime>=5000)
return false;
jsonResults.append(buff, 0, read);
}
} catch (MalformedURLException e) {
Logger.e(LOG_TAG, "Error processing Places API URL", e);
return true;
} catch (IOException e) {
Logger.e(LOG_TAG, "Error connecting to Places API", e);
return true;
} finally {
if (conn != null) {
conn.disconnect();
}
}
return false;
}
我尝试了不同的替代方法,包括将 URL 从 HTTP 更改为 HTTPS,我不确定此时我到底缺少什么,很少有此 Web 服务调用返回的情况200 次成功,但大多数时候它只是失败并显示 403 HTTP 错误代码,此时任何建议都会有所帮助,我还附上了来自 Logcat 的日志:
Error connecting to Places API
java.io.FileNotFoundException: https://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=08080
at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
at .getAddressResult(NetworkUtil.java:217)
at .access[=14=]0(NetworkUtil.java:30)
at $ResolveCityTask.doInBackground(NetworkUtil.java:81)
at $ResolveCityTask.doInBackground(NetworkUtil.java:42)
- 不再需要
sensor
参数。 - 此外,您没有在请求中提供 API_KEY url。
StringBuilder
的字符串应该用双引号括起来。- 你的logcat地址字符串是08080,应该是字符串。
- 您应该在后台线程中执行您的 API 请求。
一个示例 API 需要 URL 应该是这样的:
https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&key=API_KEY
示例修改代码:
String API_KEY = "YOUR_API_KEY_STRING";
String input = "1600+Amphitheatre+Parkway,+Mountain+View,+CA";
private static boolean getAddressResult(String input, StringBuilder jsonResults) {
try {
URL requestUrl = new URL("https://maps.googleapis.com/maps/api/geocode/json?address=" + input " + &key=" + API_KEY;
);
HttpURLConnection connection = (HttpURLConnection)requestUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader reader = null;
InputStream inputStream = connection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return false;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
long elapsedTime = System.currentTimeMillis();
if(elapsedTime-currentTime>=5000) {
return false;
}
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
return false;
}
Log.d("Test", buffer.toString());
return buffer.toString();
}
else {
Log.i(TAG, "Unsuccessful HTTP Response Code: " + responseCode);
return false
}
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error processing Places API URL", e);
return false;
} catch (IOException e) {
Log.e(LOG_TAG, "Error connecting to Places API", e);
return false;
} catch (Expcetion e) {
return false;
}
return false;
}
此示例代码应 运行 在您的后台方法中。
还需要确保在清单文件中添加互联网权限。
<uses-permission android:name="android.permission.INTERNET" />
您还可以通过添加来检查您的互联网连接
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
并调用此方法查看您的互联网是否已连接:
private boolean isNetworkAvailable() {
ConnectivityManager manager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected()) {
isAvailable = true;
}
return isAvailable;
}