在我的 Android 应用程序中,我有一个EditText
、一个Button
和一个Listview
。当我在我的EditText
字段中输入电影名称并按下 时Button
,我希望ListView
Rotten Tomatoes 网站上的电影名称与我在EditText
字段中输入的内容相匹配。
但我不知道如何使用烂番茄 JSON API来获取电影数据。我该怎么做?
在我的 Android 应用程序中,我有一个EditText
、一个Button
和一个Listview
。当我在我的EditText
字段中输入电影名称并按下 时Button
,我希望ListView
Rotten Tomatoes 网站上的电影名称与我在EditText
字段中输入的内容相匹配。
但我不知道如何使用烂番茄 JSON API来获取电影数据。我该怎么做?
基本上,你需要做四件事:
http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=[your_api_key]&q=[search_keyword]&page_limit=[page_limit]
,如本页所示。我已经组装了一个小型演示应用程序来执行此操作。请尝试以下代码。
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!");
}
}
}
}
}
资源/布局/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 应用程序使用 Internet 的权限,您显然需要向 Rotten Tomatoes 的网络服务器发出请求):
<uses-permission android:name="android.permission.INTERNET" />
奖励答案:
如果您在 EditText 字段中键入搜索关键字时想要“实时”搜索结果,请通过 EditText 的addTextChangedListener()
方法添加一个 TextWatcher,并使其在onTextChanged()
.
解决此类问题的典型方法是:
创建一个AsyncTask
处理请求和响应的网络和解析,因为在主(或 UI)线程中长时间运行的操作是一个坏主意。在 AsyncTask 中,您使用 HttpClient 与 API 服务器通信,并使用 JSON 解析器库(例如Google 的 gson)解析 JSON 请求/响应。
你可以找到很多关于如何使用 HttpClient 与远程服务器通信的教程,这里是其中之一(我不能保证它的质量):
http://www.mysamplecode.com/2011/09/android-asynctask-httpclient-with.html