X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=android%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Fclient%2Fandroid%2FCaptureActivity.java;h=249fd84d86e29ad91688eafb25b8109283694dd5;hb=da130ccadc1cc50f7e5de2a34fc63740ca0d27b9;hp=f0b8e6f1f02f9b052310b8cd41a2c6b86d9cf6e5;hpb=a054d60a8432f1635518b04117127e06283fe131;p=zxing.git diff --git a/android/src/com/google/zxing/client/android/CaptureActivity.java b/android/src/com/google/zxing/client/android/CaptureActivity.java index f0b8e6f1..249fd84d 100755 --- a/android/src/com/google/zxing/client/android/CaptureActivity.java +++ b/android/src/com/google/zxing/client/android/CaptureActivity.java @@ -18,6 +18,7 @@ package com.google.zxing.client.android; 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; @@ -49,10 +50,8 @@ 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.util.TypedValue; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; @@ -64,12 +63,16 @@ import android.view.Window; import android.view.WindowManager; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; import java.io.IOException; import java.text.DateFormat; import java.util.Arrays; -import java.util.List; import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.Vector; import java.util.regex.Pattern; @@ -78,6 +81,7 @@ import java.util.regex.Pattern; * example included in the Android SDK. * * @author dswitkin@google.com (Daniel Switkin) + * @author Sean Owen */ public final class CaptureActivity extends Activity implements SurfaceHolder.Callback { @@ -92,6 +96,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal private static final int ABOUT_ID = Menu.FIRST + 4; private static final long INTENT_RESULT_DURATION = 1500L; + private static final long BULK_MODE_SCAN_DELAY_MS = 1000L; private static final float BEEP_VOLUME = 0.10f; private static final long VIBRATE_DURATION = 200L; @@ -114,9 +119,10 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal PRODUCT_FORMATS.add(BarcodeFormat.EAN_13); PRODUCT_FORMATS.add(BarcodeFormat.EAN_8); PRODUCT_FORMATS.add(BarcodeFormat.RSS14); - ONE_D_FORMATS = new Vector(PRODUCT_FORMATS.size() + 3); + ONE_D_FORMATS = new Vector(PRODUCT_FORMATS.size() + 4); 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); @@ -126,6 +132,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, @@ -136,7 +151,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; @@ -152,7 +167,14 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal private String versionName; private HistoryManager historyManager; - private final OnCompletionListener beepListener = new BeepListener(); + /** + * When the beep has finished playing, rewind to queue up another one. + */ + private final OnCompletionListener beepListener = new OnCompletionListener() { + public void onCompletion(MediaPlayer mediaPlayer) { + mediaPlayer.seekTo(0); + } + }; private final DialogInterface.OnClickListener aboutListener = new DialogInterface.OnClickListener() { @@ -182,7 +204,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; @@ -195,6 +217,7 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal @Override protected void onResume() { super.onResume(); + resetStatusView(); SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view); SurfaceHolder surfaceHolder = surfaceView.getHolder(); @@ -216,37 +239,30 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal // Scan the formats the intent requested, and return the result to the calling activity. source = Source.NATIVE_APP_INTENT; decodeFormats = parseDecodeFormats(intent); - resetStatusView(); } else if (dataString != null && dataString.contains(PRODUCT_SEARCH_URL_PREFIX) && dataString.contains(PRODUCT_SEARCH_URL_SUFFIX)) { // Scan only products and send the result to mobile Product Search. source = Source.PRODUCT_SEARCH_LINK; sourceUrl = dataString; decodeFormats = PRODUCT_FORMATS; - resetStatusView(); } 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. + // If a return URL is specified, send the results there. Otherwise, handle it ourselves. source = Source.ZXING_LINK; sourceUrl = dataString; 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). source = Source.NONE; decodeFormats = null; - resetStatusView(); } characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET); } else { source = Source.NONE; decodeFormats = null; characterSet = null; - if (lastResult == null) { - resetStatusView(); - } } SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); @@ -395,7 +411,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(); @@ -446,14 +462,24 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal handleDecodeExternally(rawResult, barcode); break; case ZXING_LINK: - if(returnUrlTemplate == null){ + if (returnUrlTemplate == null){ handleDecodeInternally(rawResult, barcode); } else { handleDecodeExternally(rawResult, barcode); } break; case NONE: - handleDecodeInternally(rawResult, barcode); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + if (prefs.getBoolean(PreferencesActivity.KEY_BULK_MODE, false)) { + Toast.makeText(this, R.string.msg_bulk_mode_scanned, Toast.LENGTH_SHORT).show(); + // Wait a moment or else it will scan the same barcode continuously about 3 times + if (handler != null) { + handler.sendEmptyMessageDelayed(R.id.restart_preview, BULK_MODE_SCAN_DELAY_MS); + } + resetStatusView(); + } else { + handleDecodeInternally(rawResult, barcode); + } break; } } @@ -498,36 +524,52 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal ImageView barcodeImageView = (ImageView) findViewById(R.id.barcode_image_view); if (barcode == null) { - barcodeImageView.setImageResource(R.drawable.zxing_icon); + barcodeImageView.setImageResource(R.drawable.launcher_icon_large); } else { barcodeImageView.setImageBitmap(barcode); } barcodeImageView.setVisibility(View.VISIBLE); 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.setVisibility(View.VISIBLE); - 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.setVisibility(View.VISIBLE); - timeTextView.setText(getString(R.string.msg_default_time) + ": " + formattedTime); + 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 32 -- bigger font for shorter text + int scaledSize = Math.max(22, 32 - displayContents.length() / 4); + contentsTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, scaledSize); int buttonCount = resultHandler.getButtonCount(); ViewGroup buttonView = (ViewGroup) findViewById(R.id.result_button_view); @@ -557,12 +599,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); @@ -588,10 +625,11 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal 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. + // 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()); + message.obj = returnUrlTemplate.replace(RETURN_CODE_PLACEHOLDER, + resultHandler.getDisplayContents().toString()); handler.sendMessageDelayed(message, INTENT_RESULT_DURATION); } } @@ -672,13 +710,12 @@ 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; } if (handler == null) { - boolean beginScanning = lastResult == null; - handler = new CaptureActivityHandler(this, decodeFormats, characterSet, beginScanning); + handler = new CaptureActivityHandler(this, decodeFormats, characterSet); } } @@ -686,37 +723,20 @@ public final class CaptureActivity extends Activity implements SurfaceHolder.Cal AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(getString(R.string.app_name)); builder.setMessage(getString(R.string.msg_camera_framework_bug)); - builder.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialogInterface, int i) { - finish(); - } - }); + builder.setPositiveButton(R.string.button_ok, new FinishListener(this)); + builder.setOnCancelListener(new FinishListener(this)); builder.show(); } 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; } public void drawViewfinder() { viewfinderView.drawViewfinder(); } - - /** - * When the beep has finished playing, rewind to queue up another one. - */ - private static class BeepListener implements OnCompletionListener { - public void onCompletion(MediaPlayer mediaPlayer) { - mediaPlayer.seekTo(0); - } - } }