【问题标题】:How to request movie data from Rotten Tomatoes using their JSON API?如何使用 Rotten Tomatoes 的 JSON API 请求电影数据?
【发布时间】:2013-01-05 14:28:47
【问题描述】:

在我的 Android 应用程序中,我有一个 EditText、一个 Button 和一个 Listview。当我在 EditText 字段中输入电影名称并按下 Button 时,我希望在 ListView 中填充与我在 EditText 字段中输入的内容匹配的烂番茄网站上的电影名称。

但我不知道如何使用Rotten Tomatoes JSON API 来获取电影数据。我该怎么做?

【问题讨论】:

    标签: android json httprequest httpclient rotten-tomatoes


    【解决方案1】:

    基本上,你需要做四件事:

    1. 为您的 Android 应用程序获取 Rotten Tomatoes API 密钥,您可以这样做here。此密钥将您的应用程序识别到他们的服务并授予您授权的访问权限。每次向他们的 API 发出请求时都必须使用它。就是这样,没什么复杂的。
    2. 向其 API 的 Web 服务器发出 HTTP 请求。请求的 URL 将取决于您尝试获取的数据。例如,要获取电影列表,URL 为:http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=[your_api_key]&q=[search_keyword]&page_limit=[page_limit],如this 页面所示。​​
    3. 从他们的 Web 服务器读取响应。如我刚刚链接的最后一页所示,响应将是一个 JSON 对象,因为这是 Rotten Tomatoes 选择用于其 API 的数据格式。
    4. 从 JSON 对象中获取您想要的任何值(例如电影标题)并相应地更新您应用的 UI。

    我已经制作了一个小型演示应用程序来执行此操作。请尝试以下代码。

    MainActivity.java

    import android.app.Activity;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.ArrayAdapter;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.ListView;
    
    import org.apache.http.HttpResponse;
    import org.apache.http.HttpStatus;
    import org.apache.http.StatusLine;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    
    public class MainActivity extends Activity
    {
        // the Rotten Tomatoes API key of your application! get this from their website
        private static final String API_KEY = <your api key!>; 
    
        // the number of movies you want to get in a single request to their web server
        private static final int MOVIE_PAGE_LIMIT = 10; 
    
        private EditText searchBox;
        private Button searchButton;
        private ListView moviesList;
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            searchBox = (EditText) findViewById(R.id.text_search_box);
            searchButton = (Button) findViewById(R.id.button_search);
            searchButton.setOnClickListener(new OnClickListener()
            {
                // send an API request when the button is pressed
                @Override
                public void onClick(View arg0)
                {
                    new RequestTask().execute("http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=" + API_KEY + "&q=" + searchBox.getText().toString().trim() + "&page_limit=" + MOVIE_PAGE_LIMIT);
                }
            });
            moviesList = (ListView) findViewById(R.id.list_movies);
        }
    
        private void refreshMoviesList(String[] movieTitles)
        {
            moviesList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, movieTitles));
        }
    
        private class RequestTask extends AsyncTask<String, String, String>
        {
            // make a request to the specified url
            @Override
            protected String doInBackground(String... uri)
            {
                HttpClient httpclient = new DefaultHttpClient();
                HttpResponse response;
                String responseString = null;
                try
                {
                    // make a HTTP request
                    response = httpclient.execute(new HttpGet(uri[0]));
                    StatusLine statusLine = response.getStatusLine();
                    if (statusLine.getStatusCode() == HttpStatus.SC_OK)
                    {
                        // request successful - read the response and close the connection
                        ByteArrayOutputStream out = new ByteArrayOutputStream();
                        response.getEntity().writeTo(out);
                        out.close();
                        responseString = out.toString();
                    }
                    else
                    {
                        // request failed - close the connection
                        response.getEntity().getContent().close();
                        throw new IOException(statusLine.getReasonPhrase());
                    }
                }
                catch (Exception e)
                {
                    Log.d("Test", "Couldn't make a successful request!");
                }
                return responseString;
            }
    
            // if the request above completed successfully, this method will 
            // automatically run so you can do something with the response
            @Override
            protected void onPostExecute(String response)
            {
                super.onPostExecute(response);
    
                if (response != null)
                {
                    try
                    {
                        // convert the String response to a JSON object,
                        // because JSON is the response format Rotten Tomatoes uses
                        JSONObject jsonResponse = new JSONObject(response);
    
                        // fetch the array of movies in the response
                        JSONArray movies = jsonResponse.getJSONArray("movies");
    
                        // add each movie's title to an array
                        String[] movieTitles = new String[movies.length()];
                        for (int i = 0; i < movies.length(); i++)
                        {
                            JSONObject movie = movies.getJSONObject(i);
                            movieTitles[i] = movie.getString("title");
                        }
    
                        // update the UI
                        refreshMoviesList(movieTitles);
                    }
                    catch (JSONException e)
                    {
                        Log.d("Test", "Failed to parse the JSON response!");
                    }
                }
            }
        }
    }
    

    res/layouts/activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#E9E9E9"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:orientation="horizontal"
            android:padding="3dip" >
    
            <EditText
                android:id="@+id/text_search_box"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                android:gravity="center" />
    
            <Button
                android:id="@+id/button_search"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:drawableRight="@android:drawable/ic_search_category_default" />
        </LinearLayout>
    
        <ListView
            android:id="@+id/list_movies"
            android:layout_width="match_parent"
            android:layout_height="0dip"
            android:layout_weight="1.0" />
    
    </LinearLayout>
    

    并将这一行添加到您的AndroidManifest.xml(它授予您的 Android 应用程序使用互联网的权限,您显然需要向 Rotten Tomatoes 的网络服务器发出请求):

    <uses-permission android:name="android.permission.INTERNET" />
    

    奖励答案:

    如果您想在 EditText 字段中键入搜索关键字时获得“实时”搜索结果,请通过 EditText 的 addTextChangedListener() 方法添加一个 TextWatcher,并使其在 onTextChanged() 中执行 HTTP 请求。

    【讨论】:

    • 哇,我不敢相信,你的帖子对我帮助很大,非常详细且易于阅读,我现在将测试代码并让你知道它是如何运行的,但首先所有,我必须对此表示非常感谢!!!
    • 我已经测试了代码,它就像魅力一样,我浪费了几个小时甚至几天,试图弄清楚这一切,你的回答为我节省了很多时间,这是因为像你这样的人,那个stackoverflow是如此成功,你付出的努力是非常令人钦佩的,我对此表示感谢,我忍不住要问,我有没有机会让你发电子邮件,或者无论如何我可以以后联系你?在互联网上的所有地方中,没有什么能像你那样帮助我,如果没有办法联系到像你这样才华横溢的人,那将是一种耻辱。
    • 抱歉,我想暂时保持匿名。 :) 干杯。
    • 没问题,感谢您的帮助!回头见:)
    • 嘿 XåpplI'-I0llwlg'I,你能看看这个吗(stackoverflow.com/questions/23031999/…)。在这里可以做什么?
    【解决方案2】:

    解决此类问题的典型方法是:

    创建一个AsyncTask 来处理您的请求和响应的网络和解析,因为在主(或 UI)线程中长时间运行操作是一个坏主意。在 AsyncTask 中,您使用 HttpClient 与 API 服务器通信,并使用 JSON 解析器库(例如 Google's gson)解析 JSON 请求/响应。

    你可以找到很多关于如何使用 HttpClient 与远程服务器通信的教程,这里是其中之一(我不能保证它的质量):

    http://www.mysamplecode.com/2011/09/android-asynctask-httpclient-with.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-13
      • 2019-08-17
      • 1970-01-01
      • 2011-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多