import java.util.ArrayList;
import java.util.List;
+/**
+ * Uses Google Book Search to find a word or phrase in the requested book.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
public final class SearchBookContentsActivity extends Activity {
-
private static final String TAG = "SearchBookContents";
+ private static final String USER_AGENT = "ZXing (Android)";
+
+ private NetworkThread networkThread;
+ private String isbn;
+ private EditText queryTextView;
+ private Button queryButton;
+ private ListView resultListView;
+ private TextView headerView;
- private NetworkThread mNetworkThread;
- private String mISBN;
- private EditText mQueryTextView;
- private Button mQueryButton;
- private ListView mResultListView;
- private TextView mHeaderView;
- private String mUserAgent;
+ public final Handler handler = new Handler() {
+ @Override
+ public void handleMessage(Message message) {
+ switch (message.what) {
+ case R.id.search_book_contents_succeeded:
+ handleSearchResults((JSONObject) message.obj);
+ resetForNewQuery();
+ break;
+ case R.id.search_book_contents_failed:
+ resetForNewQuery();
+ headerView.setText(R.string.msg_sbc_failed);
+ break;
+ }
+ }
+ };
+
+ private final Button.OnClickListener buttonListener = new Button.OnClickListener() {
+ public void onClick(View view) {
+ launchSearch();
+ }
+ };
+
+ private final View.OnKeyListener keyListener = new View.OnKeyListener() {
+ public boolean onKey(View view, int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_ENTER) {
+ launchSearch();
+ return true;
+ }
+ return false;
+ }
+ };
@Override
public void onCreate(Bundle icicle) {
CookieManager.getInstance().removeExpiredCookie();
Intent intent = getIntent();
- if (intent == null || (!intent.getAction().equals(Intents.SearchBookContents.ACTION) &&
- !intent.getAction().equals(Intents.SearchBookContents.DEPRECATED_ACTION))) {
+ if (intent == null || (!intent.getAction().equals(Intents.SearchBookContents.ACTION))) {
finish();
return;
}
- mISBN = intent.getStringExtra(Intents.SearchBookContents.ISBN);
- setTitle(getString(R.string.sbc_name) + ": ISBN " + mISBN);
+ isbn = intent.getStringExtra(Intents.SearchBookContents.ISBN);
+ setTitle(getString(R.string.sbc_name) + ": ISBN " + isbn);
setContentView(R.layout.search_book_contents);
- mQueryTextView = (EditText) findViewById(R.id.query_text_view);
+ queryTextView = (EditText) findViewById(R.id.query_text_view);
String initialQuery = intent.getStringExtra(Intents.SearchBookContents.QUERY);
if (initialQuery != null && initialQuery.length() > 0) {
// Populate the search box but don't trigger the search
- mQueryTextView.setText(initialQuery);
+ queryTextView.setText(initialQuery);
}
- mQueryTextView.setOnKeyListener(mKeyListener);
+ queryTextView.setOnKeyListener(keyListener);
- mQueryButton = (Button) findViewById(R.id.query_button);
- mQueryButton.setOnClickListener(mButtonListener);
+ queryButton = (Button) findViewById(R.id.query_button);
+ queryButton.setOnClickListener(buttonListener);
- mResultListView = (ListView) findViewById(R.id.result_list_view);
+ resultListView = (ListView) findViewById(R.id.result_list_view);
LayoutInflater factory = LayoutInflater.from(this);
- mHeaderView = (TextView) factory.inflate(R.layout.search_book_contents_header,
- mResultListView, false);
- mResultListView.addHeaderView(mHeaderView);
-
- mUserAgent = getString(R.string.zxing_user_agent);
+ headerView = (TextView) factory.inflate(R.layout.search_book_contents_header,
+ resultListView, false);
+ resultListView.addHeaderView(headerView);
}
@Override
protected void onResume() {
super.onResume();
- mQueryTextView.selectAll();
+ queryTextView.selectAll();
}
@Override
super.onConfigurationChanged(config);
}
- public final Handler mHandler = new Handler() {
- public void handleMessage(Message message) {
- switch (message.what) {
- case R.id.search_book_contents_succeeded:
- handleSearchResults((JSONObject) message.obj);
- resetForNewQuery();
- break;
- case R.id.search_book_contents_failed:
- resetForNewQuery();
- mHeaderView.setText(R.string.msg_sbc_failed);
- break;
- }
- }
- };
-
private void resetForNewQuery() {
- mNetworkThread = null;
- mQueryTextView.setEnabled(true);
- mQueryTextView.selectAll();
- mQueryButton.setEnabled(true);
+ networkThread = null;
+ queryTextView.setEnabled(true);
+ queryTextView.selectAll();
+ queryButton.setEnabled(true);
}
- private final Button.OnClickListener mButtonListener = new Button.OnClickListener() {
- public void onClick(View view) {
- launchSearch();
- }
- };
-
- private final View.OnKeyListener mKeyListener = new View.OnKeyListener() {
- public boolean onKey(View view, int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_ENTER) {
- launchSearch();
- return true;
- }
- return false;
- }
- };
-
private void launchSearch() {
- if (mNetworkThread == null) {
- String query = mQueryTextView.getText().toString();
+ if (networkThread == null) {
+ String query = queryTextView.getText().toString();
if (query != null && query.length() > 0) {
- mNetworkThread = new NetworkThread(mISBN, query, mHandler, mUserAgent);
- mNetworkThread.start();
- mHeaderView.setText(R.string.msg_sbc_searching_book);
- mResultListView.setAdapter(null);
- mQueryTextView.setEnabled(false);
- mQueryButton.setEnabled(false);
+ networkThread = new NetworkThread(isbn, query, handler);
+ networkThread.start();
+ headerView.setText(R.string.msg_sbc_searching_book);
+ resultListView.setAdapter(null);
+ queryTextView.setEnabled(false);
+ queryButton.setEnabled(false);
}
}
}
private void handleSearchResults(JSONObject json) {
try {
int count = json.getInt("number_of_results");
- mHeaderView.setText("Found " + ((count == 1) ? "1 result" : count + " results"));
+ headerView.setText("Found " + (count == 1 ? "1 result" : count + " results"));
if (count > 0) {
JSONArray results = json.getJSONArray("search_results");
- SearchBookContentsResult.setQuery(mQueryTextView.getText().toString());
+ SearchBookContentsResult.setQuery(queryTextView.getText().toString());
List<SearchBookContentsResult> items = new ArrayList<SearchBookContentsResult>(count);
for (int x = 0; x < count; x++) {
items.add(parseResult(results.getJSONObject(x)));
}
- mResultListView.setAdapter(new SearchBookContentsAdapter(this, items));
+ resultListView.setAdapter(new SearchBookContentsAdapter(this, items));
} else {
String searchable = json.optString("searchable");
- if (searchable != null && searchable.equals("false")) {
- mHeaderView.setText(R.string.msg_sbc_book_not_searchable);
+ if ("false".equals(searchable)) {
+ headerView.setText(R.string.msg_sbc_book_not_searchable);
}
- mResultListView.setAdapter(null);
+ resultListView.setAdapter(null);
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
- mResultListView.setAdapter(null);
- mHeaderView.setText(R.string.msg_sbc_failed);
+ resultListView.setAdapter(null);
+ headerView.setText(R.string.msg_sbc_failed);
}
}
try {
String pageNumber = json.getString("page_number");
if (pageNumber.length() > 0) {
- pageNumber = getString(R.string.msg_sbc_page) + " " + pageNumber;
+ pageNumber = getString(R.string.msg_sbc_page) + ' ' + pageNumber;
} else {
// This can happen for text on the jacket, and possibly other reasons.
pageNumber = getString(R.string.msg_sbc_unknown_page);
snippet = snippet.replaceAll("'", "'");
snippet = snippet.replaceAll(""", "\"");
} else {
- snippet = "(" + getString(R.string.msg_sbc_snippet_unavailable) + ")";
+ snippet = '(' + getString(R.string.msg_sbc_snippet_unavailable) + ')';
valid = false;
}
return new SearchBookContentsResult(pageNumber, snippet, valid);
}
private static final class NetworkThread extends Thread {
-
- private final String mISBN;
- private final String mQuery;
- private final Handler mHandler;
- private final String mUserAgent;
-
- public NetworkThread(String isbn, String query, Handler handler, String userAgent) {
- mISBN = isbn;
- mQuery = query;
- mHandler = handler;
- mUserAgent = userAgent;
+ private final String isbn;
+ private final String query;
+ private final Handler handler;
+
+ NetworkThread(String isbn, String query, Handler handler) {
+ this.isbn = isbn;
+ this.query = query;
+ this.handler = handler;
}
- public final void run() {
+ @Override
+ public void run() {
AndroidHttpClient client = null;
try {
// These return a JSON result which describes if and where the query was found. This API may
// break or disappear at any time in the future. Since this is an API call rather than a
// website, we don't use LocaleManager to change the TLD.
- URI uri = new URI("http", null, "www.google.com", -1, "/books", "vid=isbn" + mISBN +
- "&jscmd=SearchWithinVolume2&q=" + mQuery, null);
+ URI uri = new URI("http", null, "www.google.com", -1, "/books", "vid=isbn" + isbn +
+ "&jscmd=SearchWithinVolume2&q=" + query, null);
HttpUriRequest get = new HttpGet(uri);
get.setHeader("cookie", getCookie(uri.toString()));
- client = AndroidHttpClient.newInstance(mUserAgent);
+ client = AndroidHttpClient.newInstance(USER_AGENT);
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
JSONObject json = new JSONObject(jsonHolder.toString(getEncoding(entity)));
jsonHolder.close();
- Message message = Message.obtain(mHandler, R.id.search_book_contents_succeeded);
+ Message message = Message.obtain(handler, R.id.search_book_contents_succeeded);
message.obj = json;
message.sendToTarget();
} else {
Log.e(TAG, "HTTP returned " + response.getStatusLine().getStatusCode() + " for " + uri);
- Message message = Message.obtain(mHandler, R.id.search_book_contents_failed);
+ Message message = Message.obtain(handler, R.id.search_book_contents_failed);
message.sendToTarget();
}
} catch (Exception e) {
Log.e(TAG, e.toString());
- Message message = Message.obtain(mHandler, R.id.search_book_contents_failed);
+ Message message = Message.obtain(handler, R.id.search_book_contents_failed);
message.sendToTarget();
} finally {
if (client != null) {
if (cookie == null || cookie.length() == 0) {
Log.v(TAG, "Book Search cookie was missing or expired");
HttpUriRequest head = new HttpHead(url);
- AndroidHttpClient client = AndroidHttpClient.newInstance(mUserAgent);
+ AndroidHttpClient client = AndroidHttpClient.newInstance(USER_AGENT);
try {
HttpResponse response = client.execute(head);
if (response.getStatusLine().getStatusCode() == 200) {
Header[] cookies = response.getHeaders("set-cookie");
- for (int x = 0; x < cookies.length; x++) {
- CookieManager.getInstance().setCookie(url, cookies[x].getValue());
+ for (Header theCookie : cookies) {
+ CookieManager.getInstance().setCookie(url, theCookie.getValue());
}
CookieSyncManager.getInstance().sync();
cookie = CookieManager.getInstance().getCookie(url);
return cookie;
}
- private String getEncoding(HttpEntity entity) {
+ private static String getEncoding(HttpEntity entity) {
// FIXME: The server is returning ISO-8859-1 but the content is actually windows-1252.
// Once Jeff fixes the HTTP response, remove this hardcoded value and go back to getting
// the encoding dynamically.
// return "UTF-8";
}
}
-
}