3

私の Android アプリケーションには、 one EditText、 one Button、および one がありListviewます。フィールドに映画の名前を入力してEditTextを押すと、フィールドに入力したものと一致する Rotten Tomatoes Web サイトの映画の名前が に取り込まれButtonます。ListViewEditText

しかし、 Rotten Tomatoes JSON APIを使用して映画データを取得する方法がわかりません。どうすればいいのですか?

4

2 に答える 2

15

基本的に、次の 4 つのことを行う必要があります。

  1. Android アプリケーション用の Rotten Tomatoes API キーを取得します。これは、こちらで行うことができます。このキーは、サービスに対してアプリを識別し、承認されたアクセスを提供します。API にリクエストを行うたびに使用する必要があります。複雑なことは何もありません。
  2. APIの Web サーバーにHTTPリクエストを送信します。リクエストの URL は、取得しようとしているデータによって異なります。たとえば、このページhttp://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=[your_api_key]&q=[search_keyword]&page_limit=[page_limit]に示されているように、映画のリストを取得する場合の URL は: です。
  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 の Web サーバーに要求を行う必要があります)。

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

ボーナス回答:

EditText フィールドに検索キーワードを入力したときに「ライブ」の検索結果が必要な場合は、EditText のaddTextChangedListener()メソッドを介して TextWatcher を追加し、onTextChanged().

于 2013-01-05T15:53:40.123 に答える
0

この種の問題に対する典型的なアプローチは次のようになります。

AsyncTaskメイン (または UI) スレッドで長時間実行される操作はお勧めできないため、要求と応答のネットワークと解析を処理する を作成します。AsyncTask では、HttpClient を使用して API サーバーと通信し、Google の gsonなどの JSON パーサー ライブラリを使用して JSON 要求/応答を解析します。

HttpClient を使用してリモート サーバーと通信する方法については、多くのチュートリアルを見つけることができます。ここにその 1 つを示します (品質については保証できません)。

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

于 2013-01-05T14:44:01.097 に答える