X-Git-Url: http://git.rot13.org/?p=zxing.git;a=blobdiff_plain;f=android%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Fclient%2Fandroid%2FCaptureActivity.java;h=02cb6b06af435e14c2f590d6719b507b7bd88925;hp=2d9b014e26c7297d5c2304f4b702ba9ab60a1da4;hb=bbd2b8fa4e0abaacd855b90dcbd8a6c740d7e822;hpb=b4dbafd45e7e994bc4da2e2a95562d83262c6208 diff --git a/android/src/com/google/zxing/client/android/CaptureActivity.java b/android/src/com/google/zxing/client/android/CaptureActivity.java index 2d9b014e..02cb6b06 100755 --- a/android/src/com/google/zxing/client/android/CaptureActivity.java +++ b/android/src/com/google/zxing/client/android/CaptureActivity.java @@ -16,9 +16,12 @@ package com.google.zxing.client.android; +import android.util.TypedValue; import com.google.zxing.BarcodeFormat; import com.google.zxing.Result; +import com.google.zxing.ResultMetadataType; import com.google.zxing.ResultPoint; +import com.google.zxing.client.android.camera.CameraManager; import com.google.zxing.client.android.history.HistoryManager; import com.google.zxing.client.android.result.ResultButtonListener; import com.google.zxing.client.android.result.ResultHandler; @@ -38,7 +41,6 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; -import android.graphics.drawable.BitmapDrawable; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; @@ -49,10 +51,7 @@ import android.os.Message; import android.os.Vibrator; import android.preference.PreferenceManager; import android.text.ClipboardManager; -import android.text.SpannableStringBuilder; -import android.text.style.UnderlineSpan; import android.util.Log; -import android.view.Gravity; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; @@ -66,6 +65,13 @@ import android.widget.ImageView; import android.widget.TextView; import java.io.IOException; +import java.text.DateFormat; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Date; +import java.util.Map; +import java.util.Set; import java.util.Vector; import java.util.regex.Pattern; @@ -77,7 +83,8 @@ import java.util.regex.Pattern; */ public final class CaptureActivity extends Activity implements SurfaceHolder.Callback { - private static final String TAG = "CaptureActivity"; + private static final String TAG = CaptureActivity.class.getSimpleName(); + private static final Pattern COMMA_PATTERN = Pattern.compile(","); private static final int SHARE_ID = Menu.FIRST; @@ -86,7 +93,6 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal private static final int HELP_ID = Menu.FIRST + 3; private static final int ABOUT_ID = Menu.FIRST + 4; - private static final int MAX_RESULT_IMAGE_SIZE = 150; private static final long INTENT_RESULT_DURATION = 1500L; private static final float BEEP_VOLUME = 0.10f; private static final long VIBRATE_DURATION = 200L; @@ -95,6 +101,8 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal private static final String PRODUCT_SEARCH_URL_PREFIX = "http://www.google"; private static final String PRODUCT_SEARCH_URL_SUFFIX = "/m/products/scan"; private static final String ZXING_URL = "http://zxing.appspot.com/scan"; + private static final String RETURN_CODE_PLACEHOLDER = "{CODE}"; + private static final String RETURN_URL_PARAM = "ret"; static final Vector PRODUCT_FORMATS; static final Vector ONE_D_FORMATS; @@ -111,6 +119,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal ONE_D_FORMATS = new Vector(PRODUCT_FORMATS.size() + 3); ONE_D_FORMATS.addAll(PRODUCT_FORMATS); ONE_D_FORMATS.add(BarcodeFormat.CODE_39); + ONE_D_FORMATS.add(BarcodeFormat.CODE_93); ONE_D_FORMATS.add(BarcodeFormat.CODE_128); ONE_D_FORMATS.add(BarcodeFormat.ITF); QR_CODE_FORMATS = new Vector(1); @@ -120,6 +129,15 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal ALL_FORMATS.addAll(QR_CODE_FORMATS); } + private static final Set DISPLAYABLE_METADATA_TYPES; + static { + DISPLAYABLE_METADATA_TYPES = new HashSet(5); + DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.ISSUE_NUMBER); + DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.SUGGESTED_PRICE); + DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.ERROR_CORRECTION_LEVEL); + DISPLAYABLE_METADATA_TYPES.add(ResultMetadataType.POSSIBLE_COUNTRY); + } + private enum Source { NATIVE_APP_INTENT, PRODUCT_SEARCH_LINK, @@ -130,7 +148,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal private CaptureActivityHandler handler; private ViewfinderView viewfinderView; - private View statusView; + private TextView statusView; private View resultView; private MediaPlayer mediaPlayer; private Result lastResult; @@ -140,6 +158,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal private boolean copyToClipboard; private Source source; private String sourceUrl; + private String returnUrlTemplate; private Vector decodeFormats; private String characterSet; private String versionName; @@ -175,7 +194,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal CameraManager.init(getApplication()); viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view); resultView = findViewById(R.id.result_view); - statusView = findViewById(R.id.status_view); + statusView = (TextView) findViewById(R.id.status_view); handler = null; lastResult = null; hasSurface = false; @@ -217,12 +236,14 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal sourceUrl = dataString; decodeFormats = PRODUCT_FORMATS; resetStatusView(); - } else if (dataString != null && dataString.equals(ZXING_URL)) { - // Scan all formats and handle the results ourselves. - // TODO: In the future we could allow the hyperlink to include a URL to send the results to. + } else if (dataString != null && dataString.startsWith(ZXING_URL)) { + // Scan formats requested in query string (all formats if none specified). + // If a return URL is specified, send the results there. Otherwise, handle the results ourselves. source = Source.ZXING_LINK; sourceUrl = dataString; - decodeFormats = null; + Uri inputUri = Uri.parse(sourceUrl); + returnUrlTemplate = inputUri.getQueryParameter(RETURN_URL_PARAM); + decodeFormats = parseDecodeFormats(inputUri); resetStatusView(); } else { // Scan all formats and handle the results ourselves (launched from Home). @@ -242,17 +263,41 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); playBeep = prefs.getBoolean(PreferencesActivity.KEY_PLAY_BEEP, true); + if (playBeep) { + // See if sound settings overrides this + AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE); + if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) { + playBeep = false; + } + } vibrate = prefs.getBoolean(PreferencesActivity.KEY_VIBRATE, false); copyToClipboard = prefs.getBoolean(PreferencesActivity.KEY_COPY_TO_CLIPBOARD, true); initBeepSound(); } private static Vector parseDecodeFormats(Intent intent) { - String scanFormats = intent.getStringExtra(Intents.Scan.SCAN_FORMATS); + List scanFormats = null; + String scanFormatsString = intent.getStringExtra(Intents.Scan.SCAN_FORMATS); + if (scanFormatsString != null) { + scanFormats = Arrays.asList(COMMA_PATTERN.split(scanFormatsString)); + } + return parseDecodeFormats(scanFormats, intent.getStringExtra(Intents.Scan.MODE)); + } + + private static Vector parseDecodeFormats(Uri inputUri) { + List formats = inputUri.getQueryParameters(Intents.Scan.SCAN_FORMATS); + if (formats != null && formats.size() == 1 && formats.get(0) != null){ + formats = Arrays.asList(COMMA_PATTERN.split(formats.get(0))); + } + return parseDecodeFormats(formats, inputUri.getQueryParameter(Intents.Scan.MODE)); + } + + private static Vector parseDecodeFormats(List scanFormats, + String decodeMode) { if (scanFormats != null) { Vector formats = new Vector(); try { - for (String format : COMMA_PATTERN.split(scanFormats)) { + for (String format : scanFormats) { formats.add(BarcodeFormat.valueOf(format)); } return formats; @@ -260,7 +305,6 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal // ignore it then } } - String decodeMode = intent.getStringExtra(Intents.Scan.MODE); if (decodeMode != null) { if (Intents.Scan.PRODUCT_MODE.equals(decodeMode)) { return PRODUCT_FORMATS; @@ -363,7 +407,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(getString(R.string.title_about) + versionName); builder.setMessage(getString(R.string.msg_about) + "\n\n" + getString(R.string.zxing_url)); - builder.setIcon(R.drawable.zxing_icon); + builder.setIcon(R.drawable.launcher_icon); builder.setPositiveButton(R.string.button_open_browser, aboutListener); builder.setNegativeButton(R.string.button_cancel, null); builder.show(); @@ -414,6 +458,12 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal handleDecodeExternally(rawResult, barcode); break; case ZXING_LINK: + if(returnUrlTemplate == null){ + handleDecodeInternally(rawResult, barcode); + } else { + handleDecodeExternally(rawResult, barcode); + } + break; case NONE: handleDecodeInternally(rawResult, barcode); break; @@ -458,32 +508,54 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal viewfinderView.setVisibility(View.GONE); resultView.setVisibility(View.VISIBLE); + ImageView barcodeImageView = (ImageView) findViewById(R.id.barcode_image_view); if (barcode == null) { - barcode = ((BitmapDrawable) getResources().getDrawable(R.drawable.unknown_barcode)).getBitmap(); + barcodeImageView.setImageResource(R.drawable.launcher_icon_large); + } else { + barcodeImageView.setImageBitmap(barcode); } - ImageView barcodeImageView = (ImageView) findViewById(R.id.barcode_image_view); barcodeImageView.setVisibility(View.VISIBLE); - barcodeImageView.setMaxWidth(MAX_RESULT_IMAGE_SIZE); - barcodeImageView.setMaxHeight(MAX_RESULT_IMAGE_SIZE); - barcodeImageView.setImageBitmap(barcode); TextView formatTextView = (TextView) findViewById(R.id.format_text_view); - formatTextView.setVisibility(View.VISIBLE); - formatTextView.setText(getString(R.string.msg_default_format) + ": " + - rawResult.getBarcodeFormat().toString()); + formatTextView.setText(rawResult.getBarcodeFormat().toString()); ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult); TextView typeTextView = (TextView) findViewById(R.id.type_text_view); - typeTextView.setText(getString(R.string.msg_default_type) + ": " + - resultHandler.getType().toString()); + typeTextView.setText(resultHandler.getType().toString()); + + DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT); + String formattedTime = formatter.format(new Date(rawResult.getTimestamp())); + TextView timeTextView = (TextView) findViewById(R.id.time_text_view); + timeTextView.setText(formattedTime); + + + TextView metaTextView = (TextView) findViewById(R.id.meta_text_view); + View metaTextViewLabel = findViewById(R.id.meta_text_view_label); + metaTextView.setVisibility(View.GONE); + metaTextViewLabel.setVisibility(View.GONE); + Map metadata = + (Map) rawResult.getResultMetadata(); + if (metadata != null) { + StringBuilder metadataText = new StringBuilder(20); + for (Map.Entry entry : metadata.entrySet()) { + if (DISPLAYABLE_METADATA_TYPES.contains(entry.getKey())) { + metadataText.append(entry.getValue()).append('\n'); + } + } + if (metadataText.length() > 0) { + metadataText.setLength(metadataText.length() - 1); + metaTextView.setText(metadataText); + metaTextView.setVisibility(View.VISIBLE); + metaTextViewLabel.setVisibility(View.VISIBLE); + } + } TextView contentsTextView = (TextView) findViewById(R.id.contents_text_view); - CharSequence title = getString(resultHandler.getDisplayTitle()); - SpannableStringBuilder styled = new SpannableStringBuilder(title + "\n\n"); - styled.setSpan(new UnderlineSpan(), 0, title.length(), 0); CharSequence displayContents = resultHandler.getDisplayContents(); - styled.append(displayContents); - contentsTextView.setText(styled); + contentsTextView.setText(displayContents); + // Crudely scale betweeen 22 and 36 -- bigger font for shorter text + int scaledSize = Math.max(22, 36 - displayContents.length() / 4); + contentsTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, scaledSize); int buttonCount = resultHandler.getButtonCount(); ViewGroup buttonView = (ViewGroup) findViewById(R.id.result_button_view); @@ -513,12 +585,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal // barcode was found (e.g. contact info) rather than the full contents, which they won't // have time to read. ResultHandler resultHandler = ResultHandlerFactory.makeResultHandler(this, rawResult); - TextView textView = (TextView) findViewById(R.id.status_text_view); - textView.setGravity(Gravity.CENTER); - textView.setTextSize(18.0f); - textView.setText(getString(resultHandler.getDisplayTitle())); - - statusView.setBackgroundColor(getResources().getColor(R.color.transparent)); + statusView.setText(getString(resultHandler.getDisplayTitle())); if (copyToClipboard) { ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); @@ -543,6 +610,12 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal message.obj = sourceUrl.substring(0, end) + "?q=" + resultHandler.getDisplayContents().toString() + "&source=zxing"; handler.sendMessageDelayed(message, INTENT_RESULT_DURATION); + } else if (source == Source.ZXING_LINK) { + // Replace each occurrence of RETURN_CODE_PLACEHOLDER in the returnUrlTemplate + // with the scanned code. This allows both queries and REST-style URLs to work. + Message message = Message.obtain(handler, R.id.launch_product_query); + message.obj = returnUrlTemplate.replace(RETURN_CODE_PLACEHOLDER, resultHandler.getDisplayContents().toString()); + handler.sendMessageDelayed(message, INTENT_RESULT_DURATION); } } @@ -622,7 +695,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal } catch (RuntimeException e) { // Barcode Scanner has seen crashes in the wild of this variety: // java.?lang.?RuntimeException: Fail to connect to camera service - Log.e(TAG, e.toString()); + Log.w(TAG, "Unexpected error initializating camera", e); displayFrameworkBugMessageAndExit(); return; } @@ -646,14 +719,9 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal private void resetStatusView() { resultView.setVisibility(View.GONE); + statusView.setText(R.string.msg_default_status); statusView.setVisibility(View.VISIBLE); - statusView.setBackgroundColor(getResources().getColor(R.color.status_view)); viewfinderView.setVisibility(View.VISIBLE); - - TextView textView = (TextView) findViewById(R.id.status_text_view); - textView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); - textView.setTextSize(14.0f); - textView.setText(R.string.msg_default_status); lastResult = null; }