Issue 155: allow custom product search, and, other small tweaks I think nobody will...
authorsrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Wed, 10 Jun 2009 16:40:56 +0000 (16:40 +0000)
committersrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Wed, 10 Jun 2009 16:40:56 +0000 (16:40 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@967 59b500cc-1b3d-0410-9834-0bbf25fbcc57

android/res/values/strings.xml
android/res/xml/preferences.xml
android/src/com/google/zxing/client/android/AndroidHttpClient.java
android/src/com/google/zxing/client/android/DecodeThread.java
android/src/com/google/zxing/client/android/EncodeActivity.java
android/src/com/google/zxing/client/android/PreferencesActivity.java
android/src/com/google/zxing/client/android/SearchBookContentsActivity.java
android/src/com/google/zxing/client/android/SearchBookContentsListItem.java
android/src/com/google/zxing/client/android/ViewfinderView.java
android/src/com/google/zxing/client/android/result/ISBNResultHandler.java
android/src/com/google/zxing/client/android/result/ProductResultHandler.java

index c6d06f8..d87af9f 100755 (executable)
   <string name="app_name">Barcode Scanner</string>
   <string name="bookmark_picker_name">Bookmarks</string>
 
-  <string name="button_add_calendar">Add event to calendar</string>
+  <string name="button_add_calendar">Add to calendar</string>
   <string name="button_add_contact">Add contact</string>
   <string name="button_back">Back</string>
-  <string name="button_book_search">Open Book Search</string>
+  <string name="button_book_search">Book Search</string>
   <string name="button_cancel">Cancel</string>
   <string name="button_clipboard_empty">Clipboard empty</string>
+  <string name="button_custom_product_search">Custom search</string>
   <string name="button_dial">Dial number</string>
   <string name="button_done">Done</string>
   <string name="button_email">Send email</string>
@@ -31,8 +32,8 @@
   <string name="button_mms">Send MMS</string>
   <string name="button_ok">OK</string>
   <string name="button_open_browser">Open browser</string>
-  <string name="button_product_search">Open Product Search</string>
-  <string name="button_search_book_contents">Search book contents</string>
+  <string name="button_product_search">Product Search</string>
+  <string name="button_search_book_contents">Search book</string>
   <string name="button_share_bookmark">Share bookmark</string>
   <string name="button_share_by_email">Share via email</string>
   <string name="button_share_by_sms">Share via SMS</string>
@@ -86,6 +87,9 @@
   <string name="preferences_name">Settings</string>
   <string name="preferences_play_beep_title">Beep</string>
   <string name="preferences_vibrate_title">Vibrate</string>
+  <string name="preferences_result_title">Result Settings</string>
+  <string name="preferences_custom_product_search_title">Custom product search URL</string>
+  <string name="preferences_custom_product_search_summary">Use %s as placeholder for product ID</string>
 
   <string name="result_address_book">Found contact info</string>
   <string name="result_calendar">Found calendar event</string>
index ac6d883..2962a3a 100755 (executable)
         android:defaultValue="true"
         android:title="@string/preferences_copy_to_clipboard_title"/>
   </PreferenceCategory>
+  <PreferenceCategory android:title="@string/preferences_result_title">
+    <EditTextPreference
+        android:key="preferences_custom_product_search"
+        android:title="@string/preferences_custom_product_search_title"
+        android:summary="@string/preferences_custom_product_search_summary"/>
+  </PreferenceCategory>
 </PreferenceScreen>
index eca83cf..bb27034 100644 (file)
 
 package com.google.zxing.client.android;
 
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
 import org.apache.http.HttpHost;
-import org.apache.http.HttpMessage;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
@@ -33,8 +30,6 @@ import org.apache.http.conn.scheme.PlainSocketFactory;
 import org.apache.http.conn.scheme.Scheme;
 import org.apache.http.conn.scheme.SchemeRegistry;
 import org.apache.http.conn.ssl.SSLSocketFactory;
-import org.apache.http.entity.AbstractHttpEntity;
-import org.apache.http.entity.ByteArrayEntity;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
 import org.apache.http.params.BasicHttpParams;
@@ -45,12 +40,7 @@ import org.apache.http.protocol.BasicHttpContext;
 import org.apache.http.protocol.BasicHttpProcessor;
 import org.apache.http.protocol.HttpContext;
 
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.GZIPOutputStream;
 
 /**
  * <p>Subclass of the Apache {@link DefaultHttpClient} that is configured with
@@ -65,9 +55,6 @@ import java.util.zip.GZIPOutputStream;
  */
 public final class AndroidHttpClient implements HttpClient {
 
-  // Gzip of data shorter than this probably won't be worthwhile
-  private static final long DEFAULT_SYNC_MIN_GZIP_BYTES = 256;
-
   /**
    * Set if HTTP requests are blocked from being executed on this thread
    */
@@ -80,7 +67,7 @@ public final class AndroidHttpClient implements HttpClient {
   private static final HttpRequestInterceptor sThreadCheckInterceptor =
       new HttpRequestInterceptor() {
         public void process(HttpRequest request, HttpContext context) {
-          if (sThreadBlocked.get() != null && sThreadBlocked.get()) {
+          if (Boolean.TRUE.equals(sThreadBlocked.get())) {
             throw new RuntimeException("This thread forbids HTTP requests");
           }
         }
@@ -149,54 +136,6 @@ public final class AndroidHttpClient implements HttpClient {
     };
   }
 
-  /**
-   * Block this thread from executing HTTP requests.
-   * Used to guard against HTTP requests blocking the main application thread.
-   *
-   * @param blocked if HTTP requests run on this thread should be denied
-   */
-  public static void setThreadBlocked(boolean blocked) {
-    sThreadBlocked.set(blocked);
-  }
-
-  /**
-   * Modifies a request to indicate to the server that we would like a
-   * gzipped response.  (Uses the "Accept-Encoding" HTTP header.)
-   *
-   * @param request the request to modify
-   * @see #getUngzippedContent
-   */
-  public static void modifyRequestToAcceptGzipResponse(HttpMessage request) {
-    request.addHeader("Accept-Encoding", "gzip");
-  }
-
-  /**
-   * Gets the input stream from a response entity.  If the entity is gzipped
-   * then this will get a stream over the uncompressed data.
-   *
-   * @param entity the entity whose content should be read
-   * @return the input stream to read from
-   * @throws IOException
-   */
-  public static InputStream getUngzippedContent(HttpEntity entity) throws IOException {
-    InputStream responseStream = entity.getContent();
-    if (responseStream == null) {
-      return responseStream;
-    }
-    Header header = entity.getContentEncoding();
-    if (header == null) {
-      return responseStream;
-    }
-    String contentEncoding = header.getValue();
-    if (contentEncoding == null) {
-      return responseStream;
-    }
-    if (contentEncoding.contains("gzip")) {
-      responseStream = new GZIPInputStream(responseStream);
-    }
-    return responseStream;
-  }
-
   /**
    * Release resources associated with this client.  You must call this,
    * or significant resources (sockets and memory) may be leaked.
@@ -251,30 +190,4 @@ public final class AndroidHttpClient implements HttpClient {
     return delegate.execute(target, request, responseHandler, context);
   }
 
-  /**
-   * Compress data to send to server.
-   * Creates a Http Entity holding the gzipped data.
-   * The data will not be compressed if it is too short.
-   *
-   * @param data The bytes to compress
-   * @return Entity holding the data
-   */
-  public static AbstractHttpEntity getCompressedEntity(byte[] data) throws IOException {
-    AbstractHttpEntity entity;
-    if (data.length < DEFAULT_SYNC_MIN_GZIP_BYTES) {
-      entity = new ByteArrayEntity(data);
-    } else {
-      ByteArrayOutputStream arr = new ByteArrayOutputStream();
-      OutputStream zipper = new GZIPOutputStream(arr);
-      try {
-        zipper.write(data);
-      } finally {
-        zipper.close();
-      }
-      entity = new ByteArrayEntity(arr.toByteArray());
-      entity.setContentEncoding("gzip");
-    }
-    return entity;
-  }
-
 }
index 98288d0..587b0ca 100755 (executable)
@@ -94,7 +94,7 @@ final class DecodeThread extends Thread {
 
   private void setDecodeProductMode() {
     Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(3);
-    Vector<BarcodeFormat> vector = new Vector<BarcodeFormat>();
+    Vector<BarcodeFormat> vector = new Vector<BarcodeFormat>(4);
     vector.addElement(BarcodeFormat.UPC_A);
     vector.addElement(BarcodeFormat.UPC_E);
     vector.addElement(BarcodeFormat.EAN_13);
@@ -108,7 +108,7 @@ final class DecodeThread extends Thread {
    */
   private void setDecode1DMode() {
     Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(3);
-    Vector<BarcodeFormat> vector = new Vector<BarcodeFormat>();
+    Vector<BarcodeFormat> vector = new Vector<BarcodeFormat>(7);
     vector.addElement(BarcodeFormat.UPC_A);
     vector.addElement(BarcodeFormat.UPC_E);
     vector.addElement(BarcodeFormat.EAN_13);
@@ -122,7 +122,7 @@ final class DecodeThread extends Thread {
 
   private void setDecodeQRMode() {
     Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(3);
-    Vector<BarcodeFormat> vector = new Vector<BarcodeFormat>();
+    Vector<BarcodeFormat> vector = new Vector<BarcodeFormat>(1);
     vector.addElement(BarcodeFormat.QR_CODE);
     hints.put(DecodeHintType.POSSIBLE_FORMATS, vector);
     mMultiFormatReader.setHints(hints);
@@ -134,7 +134,7 @@ final class DecodeThread extends Thread {
    */
   private void setDecodeAllMode() {
     Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(3);
-    Vector<BarcodeFormat> vector = new Vector<BarcodeFormat>();
+    Vector<BarcodeFormat> vector = new Vector<BarcodeFormat>(8);
     vector.addElement(BarcodeFormat.UPC_A);
     vector.addElement(BarcodeFormat.UPC_E);
     vector.addElement(BarcodeFormat.EAN_13);
index ebd5c55..b77e354 100755 (executable)
@@ -74,7 +74,7 @@ public final class EncodeActivity extends Activity {
         View layout = findViewById(R.id.encode_view);
         int width = layout.getWidth();
         int height = layout.getHeight();
-        int smallerDimension = (width < height) ? width : height;
+        int smallerDimension = width < height ? width : height;
         smallerDimension = smallerDimension * 7 / 8;
 
         Intent intent = getIntent();
index 98542ee..847f4fb 100755 (executable)
@@ -20,13 +20,15 @@ import android.content.SharedPreferences;
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.os.Bundle;
 import android.preference.CheckBoxPreference;
+import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
 
-public final class PreferencesActivity extends android.preference.PreferenceActivity
+public final class PreferencesActivity extends PreferenceActivity
     implements OnSharedPreferenceChangeListener {
 
   static final String KEY_DECODE_1D = "preferences_decode_1D";
   static final String KEY_DECODE_QR = "preferences_decode_QR";
+  public static final String KEY_CUSTOM_PRODUCT_SEARCH = "preferences_custom_product_search";
 
   static final String KEY_PLAY_BEEP = "preferences_play_beep";
   static final String KEY_VIBRATE = "preferences_vibrate";
index b3f5a07..77a285e 100644 (file)
@@ -51,7 +51,7 @@ import java.util.List;
 public final class SearchBookContentsActivity extends Activity {
 
   private static final String TAG = "SearchBookContents";
-  private static final String USER_AGENT = "ZXing/1.3 (Android)";
+  private static final String USER_AGENT = "ZXing/1.5 (Android)";
 
   private NetworkThread mNetworkThread;
   private String mISBN;
@@ -168,7 +168,7 @@ public final class SearchBookContentsActivity extends Activity {
   private void handleSearchResults(JSONObject json) {
     try {
       int count = json.getInt("number_of_results");
-      mHeaderView.setText("Found " + ((count == 1) ? "1 result" : count + " results"));
+      mHeaderView.setText("Found " + (count == 1 ? "1 result" : count + " results"));
       if (count > 0) {
         JSONArray results = json.getJSONArray("search_results");
         SearchBookContentsResult.setQuery(mQueryTextView.getText().toString());
@@ -179,7 +179,7 @@ public final class SearchBookContentsActivity extends Activity {
         mResultListView.setAdapter(new SearchBookContentsAdapter(this, items));
       } else {
         String searchable = json.optString("searchable");
-        if (searchable != null && searchable.equals("false")) {
+        if ("false".equals(searchable)) {
           mHeaderView.setText(R.string.msg_sbc_book_not_searchable);
         }
         mResultListView.setAdapter(null);
@@ -287,8 +287,8 @@ public final class SearchBookContentsActivity extends Activity {
           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);
index c5bdae1..356d708 100644 (file)
@@ -17,6 +17,7 @@
 package com.google.zxing.client.android;
 
 import android.content.Context;
+import android.graphics.Typeface;
 import android.text.SpannableString;
 import android.text.Spannable;
 import android.text.style.StyleSpan;
@@ -52,7 +53,7 @@ public final class SearchBookContentsListItem extends LinearLayout {
         String lowerQuery = SearchBookContentsResult.getQuery().toLowerCase();
         String lowerSnippet = snippet.toLowerCase();
         Spannable styledSnippet = new SpannableString(snippet);
-        StyleSpan boldSpan = new StyleSpan(android.graphics.Typeface.BOLD);
+        StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
         int queryLength = lowerQuery.length();
         int offset = 0;
         while (true) {
index 5570ca4..47d82af 100755 (executable)
@@ -32,7 +32,7 @@ import android.view.View;
 public final class ViewfinderView extends View {
 
   private static final int[] SCANNER_ALPHA = {0, 64, 128, 192, 255, 192, 128, 64};
-  private static final int ANIMATION_DELAY = 100;
+  private static final long ANIMATION_DELAY = 100L;
 
   private final Paint mPaint;
   private final Rect mBox;
index 1488f28..fb56fed 100644 (file)
 package com.google.zxing.client.android.result;
 
 import android.app.Activity;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
 import com.google.zxing.client.android.R;
+import com.google.zxing.client.android.PreferencesActivity;
 import com.google.zxing.client.result.ISBNParsedResult;
 import com.google.zxing.client.result.ParsedResult;
 
@@ -26,16 +29,21 @@ public final class ISBNResultHandler extends ResultHandler {
   private static final int[] mButtons = {
       R.string.button_product_search,
       R.string.button_book_search,
-      R.string.button_search_book_contents
+      R.string.button_search_book_contents,
+      R.string.button_custom_product_search,
   };
 
+  private final String mCustomProductSearch;
+
   public ISBNResultHandler(Activity activity, ParsedResult result) {
     super(activity, result);
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
+    mCustomProductSearch = prefs.getString(PreferencesActivity.KEY_CUSTOM_PRODUCT_SEARCH, null);
   }
 
   @Override
   public int getButtonCount() {
-    return mButtons.length;
+    return mCustomProductSearch != null && mCustomProductSearch.length() > 0 ? mButtons.length : mButtons.length - 1;
   }
 
   @Override
@@ -56,6 +64,10 @@ public final class ISBNResultHandler extends ResultHandler {
       case 2:
         searchBookContents(isbnResult.getISBN());
         break;
+      case 3:
+        String url = mCustomProductSearch.replace("%s", isbnResult.getISBN());
+        openURL(url);
+        break;
     }
   }
 
index f712b47..29d8a76 100644 (file)
 package com.google.zxing.client.android.result;
 
 import android.app.Activity;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
 import com.google.zxing.client.android.R;
+import com.google.zxing.client.android.PreferencesActivity;
 import com.google.zxing.client.result.ParsedResult;
 import com.google.zxing.client.result.ProductParsedResult;
 
@@ -25,16 +28,21 @@ public final class ProductResultHandler extends ResultHandler {
 
   private static final int[] mButtons = {
       R.string.button_product_search,
-      R.string.button_web_search
+      R.string.button_web_search,
+      R.string.button_custom_product_search,
   };
 
+  private final String mCustomProductSearch;
+
   public ProductResultHandler(Activity activity, ParsedResult result) {
     super(activity, result);
+    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
+    mCustomProductSearch = prefs.getString(PreferencesActivity.KEY_CUSTOM_PRODUCT_SEARCH, null);
   }
 
   @Override
   public int getButtonCount() {
-    return mButtons.length;
+    return mCustomProductSearch != null ? mButtons.length : mButtons.length - 1;
   }
 
   @Override
@@ -52,6 +60,10 @@ public final class ProductResultHandler extends ResultHandler {
       case 1:
         webSearch(productResult.getNormalizedProductID());
         break;
+      case 2:
+        String url = mCustomProductSearch.replace("%s", productResult.getNormalizedProductID());
+        openURL(url);
+        break;
     }
   }