为Google Maps API v2 Android发布流媒体方向的问题

4

我的应用程序的一部分是构建一个导航方向字符串,然后尝试解析JSON并在我的地图上绘制折线路线。我首先使用位置变量或区域设置常量来构建我的字符串,最终得到类似以下的内容:

https://maps.googleapis.com/maps/api/directions/json?origin=Full Frame Documentary Film 
Festival, Durham, 27701&destination=601 W Peace St, Raleigh,27605&sensor=false&key={API_KEY}
  • 这里没有换行(为了可读性我加了一个),{API_KEY}是我的实际api密钥。

我遇到的问题是,当我把这个URL字符串传递给downloadUrl(String urlString)方法时,会出现问题。

private String downloadUrl(String urlString) throws IOException {
    Log.d(TAG, "Downloaded string = " + urlString);
    String data = "";
    InputStream stream = null;
    HttpURLConnection urlConnection = null;
    try {

        // Display our JSON in our browser (to show us how we need to implement our parser)
        Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(urlString)); 
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);

        URL url = new URL(urlString);

        // Create a http connection to communicate with url
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.connect();

        // read in our data
        stream = urlConnection.getInputStream(); 
        BufferedReader br = new BufferedReader(new InputStreamReader(stream)); 
        StringBuffer sb = new StringBuffer();   

        // read in our data in, and append it as a single data string
        String line = "";
        while ((line = br.readLine()) != null) {
            Log.d(TAG,"url download stream: " + line);
            sb.append(line);
        }
        data = sb.toString();
        br.close();
    } 
    catch (Exception e) {
        e.printStackTrace();
    }
    finally {
        Log.d(TAG, "Downloaded data = " + data);
        stream.close();
        urlConnection.disconnect();
    }

    return data;
}    

JSON在我的浏览器中正确显示,我看到了Google文档中描述的一切内容。但是,在接下来的几行代码中,当我尝试打开与URL的连接并将JSON拉入字符串进行解析时,我收到了System.err通知。

05-02 09:56:01.540: W/System.err(32232): java.io.FileNotFoundException: 
https://maps.googleapis.com/maps/api/directions/json?origin=Full Frame Documentary 
Film Festival, Durham, 27701&destination=601 W Peace St, Raleigh, 27605&sensor=false&key={API_KEY}

我的困惑在于浏览器可以完美显示解析后的地址,但是连接到(我认为是)同一台服务器时返回一个 FNFE。我是否错误地假设了这种情况?如果是这样,我的密钥可能真的是错的吗?令人困惑的是,这段代码在另一个应用程序中是有效的。


另外一件事:不确定,但似乎你正在将 HTTP 请求与 UI 逻辑混合使用。涉及网络流量的 IO 操作不应在 UI 线程上执行。请使用 AsyncTask 或类似工具。 - hgoebl
@hgoebl 这段代码有点误导人,因为这个方法实际上是从我的AsyncTask的doInBackground()中调用的,并且只是为了清理一下代码。再次感谢。 - zgc7009
好的,那么你已经以最佳方式完成了它 :-),但你可以稍微改进一下异常处理:在依赖于getInputStream()返回响应之前,调用urlConnection.getResponseCode()。在HTTP状态码为4xx5xx的情况下,调用getInputStream()会抛出异常,如果你对错误响应的主体感兴趣,你必须调用getErrorStream() - hgoebl
@hgoebl 我感觉你在HTTP连接方面有一些经验 :P 非常感谢,所有的帮助都非常有用。 - zgc7009
1个回答

6

您需要对参数进行URL编码,例如,在URL中,“ ”(空格)写成“+”。您的浏览器在内部执行此操作,可能没有显示提交的URL。

static String urlEncode(String value) {
    try {
        return URLEncoder.encode(value, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return value;
    }
}

但是不要对整个 URL 进行编码,只需对参数值进行编码。如果参数名是非 ASCII 字符,则也必须进行编码,但 Google API 不使用这种参数。


非常感谢您,可以坦率地说,我从未想过这一点,因为我以为这些类型的转换会在内部处理。结果非常完美。谢谢! - zgc7009
1
如果你想避免繁琐的编程HttpURLConnection,你可以使用DavidWebb - hgoebl
非常好,值得深入研究。 - zgc7009

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接