如何使用他们的JSON API从烂番茄中请求电影数据?

时间:2013-01-05 14:28:47

标签: android json httprequest httpclient rotten-tomatoes

在我的Android应用中,我有一个EditText,一个Button和一个Listview。当我在EditText字段中输入电影名称并按下Button时,我希望{Roteri Grasses网站上的电影名称填充ListView与我输入的电影名称相匹配EditText字段。

但我无法弄清楚如何使用Rotten Tomatoes JSON API来获取电影数据。我该怎么做?

2 个答案:

答案 0 :(得分:14)

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

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

    <强> 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 /布局/ 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请求。

答案 1 :(得分:0)

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

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

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

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