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

use*_*895 3 android json httpclient httprequest rotten-tomatoes

在我的Android应用程序中,我有一个EditText,一个Button和一个Listview.当我在我的EditText字段中键入电影名称并按下时Button,我希望ListView在Rotten Tomatoes网站上填写与我输入的EditText字段相匹配的电影名称.

但我无法弄清楚如何使用烂番茄JSON API来获取电影数据.我该怎么做?

Xåp*_* - 14

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

  1. 获取Android应用程序的烂番茄API密钥,您可以在此处执行此操作.此密钥可识别您的应用程序,并为您提供授权访问权限.每次向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]所示.
  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!");
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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

<uses-permission android:name="android.permission.INTERNET" />
Run Code Online (Sandbox Code Playgroud)

奖金回答:

如果您在EditText字段中键入搜索关键字时需要"实时"搜索结果,请通过EditText的addTextChangedListener()方法添加TextWatcher ,并使其执行HTTP请求onTextChanged().