在我的Android应用中,我有一个EditText
,一个Button
和一个Listview
。当我在EditText
字段中输入电影名称并按下Button
时,我希望{Roteri Grasses网站上的电影名称填充ListView
与我输入的电影名称相匹配EditText
字段。
但我无法弄清楚如何使用Rotten Tomatoes JSON API来获取电影数据。我该怎么做?
答案 0 :(得分:14)
基本上,你需要做四件事:
http://api.rottentomatoes.com/api/public/v1.0/movies.json?apikey=[your_api_key]&q=[search_keyword]&page_limit=[page_limit]
,如this页上所示。我已经整理了一个小型的演示应用程序,可以做到这一点。请试用下面的代码。
<强> 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