mirror of
https://github.com/zxing/zxing.git
synced 2024-11-10 13:04:05 -08:00
Converted the Android client to use a status bar on the bottom of the screen instead of dialogs for a much better, less interrupting user experience.
git-svn-id: https://zxing.googlecode.com/svn/trunk@365 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
989dc395f0
commit
cd7c4d21ac
|
@ -14,8 +14,52 @@
|
|||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
<FrameLayout id="@+id/preview_view"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"/>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="#00000000">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="#00000000"/>
|
||||
|
||||
<!-- FIXME(dswitkin): Temporary hack to force the height to 48 pixels-->
|
||||
<LinearLayout id="@+id/status_view"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="48px"
|
||||
android:layout_weight="0"
|
||||
android:background="#55000000"
|
||||
android:baselineAligned="false"
|
||||
android:padding="4px">
|
||||
|
||||
<TextView id="@+id/status_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left|center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/msg_default_status"
|
||||
android:textColor="#ffffff"/>
|
||||
|
||||
<Button id="@+id/status_action_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center|fill_horizontal"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Messages IDs -->
|
||||
<item type="id" name="preview"/>
|
||||
<item type="id" name="decode"/>
|
||||
<item type="id" name="save"/>
|
||||
|
@ -29,4 +30,10 @@
|
|||
<item type="id" name="decode_failed"/>
|
||||
<item type="id" name="save_succeeded"/>
|
||||
<item type="id" name="save_failed"/>
|
||||
|
||||
<!-- Objects in the view hierarchy -->
|
||||
<item type="id" name="preview_view"/>
|
||||
<item type="id" name="status_action_button"/>
|
||||
<item type="id" name="status_text_view"/>
|
||||
<item type="id" name="status_view"/>
|
||||
</resources>
|
||||
|
|
|
@ -25,8 +25,12 @@ import android.os.Handler;
|
|||
import android.os.Message;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import com.google.zxing.Result;
|
||||
import com.google.zxing.ResultPoint;
|
||||
import com.google.zxing.client.result.ParsedReaderResult;
|
||||
|
@ -44,6 +48,7 @@ public final class BarcodeReaderCaptureActivity extends Activity {
|
|||
private CameraManager cameraManager;
|
||||
private CameraSurfaceView surfaceView;
|
||||
private CameraThread cameraThread;
|
||||
private String lastResult;
|
||||
|
||||
private static final int ABOUT_ID = Menu.FIRST;
|
||||
private static final int HELP_ID = Menu.FIRST + 1;
|
||||
|
@ -59,11 +64,16 @@ public final class BarcodeReaderCaptureActivity extends Activity {
|
|||
LayoutParams.NO_STATUS_BAR_FLAG));
|
||||
getWindow().setFormat(PixelFormat.TRANSLUCENT);
|
||||
|
||||
setContentView(R.layout.main);
|
||||
|
||||
cameraManager = new CameraManager(getApplication());
|
||||
surfaceView = new CameraSurfaceView(getApplication(), cameraManager);
|
||||
setContentView(surfaceView);
|
||||
cameraThread = new CameraThread(this, surfaceView, cameraManager, messageHandler);
|
||||
cameraThread.start();
|
||||
surfaceView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
|
||||
LayoutParams.FILL_PARENT));
|
||||
|
||||
ViewGroup previewView = (ViewGroup) findViewById(R.id.preview_view);
|
||||
previewView.addView(surfaceView);
|
||||
cameraThread = null;
|
||||
|
||||
// TODO re-enable this when issues with Matrix.setPolyToPoly() are resolved
|
||||
//GridSampler.setGridSampler(new AndroidGraphicsGridSampler());
|
||||
|
@ -80,6 +90,7 @@ public final class BarcodeReaderCaptureActivity extends Activity {
|
|||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
resetStatusView();
|
||||
cameraManager.openDriver();
|
||||
if (cameraThread == null) {
|
||||
cameraThread = new CameraThread(this, surfaceView, cameraManager, messageHandler);
|
||||
|
@ -154,6 +165,9 @@ public final class BarcodeReaderCaptureActivity extends Activity {
|
|||
int duration = message.arg1;
|
||||
handleDecode((Result) message.obj, duration);
|
||||
break;
|
||||
case R.id.restart_preview:
|
||||
restartPreview();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -163,33 +177,45 @@ public final class BarcodeReaderCaptureActivity extends Activity {
|
|||
restart.sendToTarget();
|
||||
}
|
||||
|
||||
// TODO(dswitkin): These deprecated showAlert calls need to be updated.
|
||||
private void handleDecode(Result rawResult, int duration) {
|
||||
if (!rawResult.toString().equals(lastResult)) {
|
||||
lastResult = rawResult.toString();
|
||||
|
||||
ResultPoint[] points = rawResult.getResultPoints();
|
||||
if (points != null && points.length > 0) {
|
||||
surfaceView.drawResultPoints(points);
|
||||
}
|
||||
|
||||
Context context = getApplication();
|
||||
TextView textView = (TextView) findViewById(R.id.status_text_view);
|
||||
ParsedReaderResult readerResult = parseReaderResult(rawResult);
|
||||
textView.setText(readerResult.getDisplayResult() + " (" + duration + " ms)");
|
||||
|
||||
Button actionButton = (Button) findViewById(R.id.status_action_button);
|
||||
int buttonText = getActionButtonText(readerResult.getType());
|
||||
if (buttonText != 0) {
|
||||
actionButton.setVisibility(View.VISIBLE);
|
||||
actionButton.setText(buttonText);
|
||||
ResultHandler handler = new ResultHandler(this, readerResult);
|
||||
if (handler.getIntent() != null) {
|
||||
// Can be handled by some external app; ask if the user wants to
|
||||
// proceed first though
|
||||
Message yesMessage = handler.obtainMessage(R.string.button_yes);
|
||||
Message noMessage = handler.obtainMessage(R.string.button_no);
|
||||
String title = context.getString(getDialogTitleID(readerResult.getType())) +
|
||||
" (" + duration + " ms)";
|
||||
showAlert(title, readerResult.getDisplayResult(), context.getString(R.string.button_yes),
|
||||
yesMessage, context.getString(R.string.button_no), noMessage, true, noMessage);
|
||||
actionButton.setOnClickListener(handler);
|
||||
actionButton.requestFocus();
|
||||
} else {
|
||||
// Just show information to user
|
||||
Message okMessage = handler.obtainMessage(R.string.button_ok);
|
||||
String title = context.getString(R.string.title_barcode_detected) +
|
||||
" (" + duration + " ms)";
|
||||
showAlert(title, readerResult.getDisplayResult(), context.getString(R.string.button_ok),
|
||||
okMessage, null, null, true, okMessage);
|
||||
actionButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Show the green finder patterns for one second, then restart the preview
|
||||
Message message = Message.obtain(messageHandler, R.id.restart_preview);
|
||||
messageHandler.sendMessageDelayed(message, 1000);
|
||||
} else {
|
||||
restartPreview();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetStatusView() {
|
||||
TextView textView = (TextView) findViewById(R.id.status_text_view);
|
||||
textView.setText(R.string.msg_default_status);
|
||||
Button actionButton = (Button) findViewById(R.id.status_action_button);
|
||||
actionButton.setVisibility(View.GONE);
|
||||
lastResult = "";
|
||||
}
|
||||
|
||||
private static ParsedReaderResult parseReaderResult(Result rawResult) {
|
||||
|
@ -209,25 +235,27 @@ public final class BarcodeReaderCaptureActivity extends Activity {
|
|||
return readerResult;
|
||||
}
|
||||
|
||||
private static int getDialogTitleID(ParsedReaderResultType type) {
|
||||
private static int getActionButtonText(ParsedReaderResultType type) {
|
||||
int buttonText;
|
||||
if (type.equals(ParsedReaderResultType.ADDRESSBOOK)) {
|
||||
return R.string.title_add_contact;
|
||||
buttonText = R.string.button_add_contact;
|
||||
} else if (type.equals(ParsedReaderResultType.URI) ||
|
||||
type.equals(ParsedReaderResultType.BOOKMARK) ||
|
||||
type.equals(ParsedReaderResultType.URLTO)) {
|
||||
return R.string.title_open_url;
|
||||
buttonText = R.string.button_open_browser;
|
||||
} else if (type.equals(ParsedReaderResultType.EMAIL) ||
|
||||
type.equals(ParsedReaderResultType.EMAIL_ADDRESS)) {
|
||||
return R.string.title_compose_email;
|
||||
buttonText = R.string.button_email;
|
||||
} else if (type.equals(ParsedReaderResultType.UPC)) {
|
||||
return R.string.title_lookup_barcode;
|
||||
buttonText = R.string.button_lookup_product;
|
||||
} else if (type.equals(ParsedReaderResultType.TEL)) {
|
||||
return R.string.title_dial;
|
||||
buttonText = R.string.button_dial;
|
||||
} else if (type.equals(ParsedReaderResultType.GEO)) {
|
||||
return R.string.title_view_maps;
|
||||
buttonText = R.string.button_show_map;
|
||||
} else {
|
||||
return R.string.title_barcode_detected;
|
||||
buttonText = 0;
|
||||
}
|
||||
return buttonText;
|
||||
}
|
||||
|
||||
}
|
|
@ -241,9 +241,13 @@ final class CameraManager {
|
|||
" nativeResolution " + nativeResolution + " stillMultiplier " + stillMultiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* The goal of the preview resolution is to show a little context around the framing rectangle
|
||||
* which is the actual captured area in still mode.
|
||||
*/
|
||||
private void calculatePreviewResolution() {
|
||||
if (previewResolution == null) {
|
||||
int previewHeight = (int) (stillResolution.x * stillMultiplier * 1.4f);
|
||||
int previewHeight = (int) (stillResolution.x * stillMultiplier * 1.8f);
|
||||
int previewWidth = previewHeight * screenResolution.x / screenResolution.y;
|
||||
previewWidth = ((previewWidth + 7) >> 3) << 3;
|
||||
if (previewWidth > cameraResolution.x) previewWidth = cameraResolution.x;
|
||||
|
|
|
@ -18,33 +18,22 @@ package com.google.zxing.client.android;
|
|||
|
||||
import android.content.Intent;
|
||||
import android.net.ContentURI;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.provider.Contacts;
|
||||
import android.util.Log;
|
||||
import com.google.zxing.client.result.AddressBookAUParsedResult;
|
||||
import com.google.zxing.client.result.AddressBookDoCoMoParsedResult;
|
||||
import com.google.zxing.client.result.BookmarkDoCoMoParsedResult;
|
||||
import com.google.zxing.client.result.EmailAddressParsedResult;
|
||||
import com.google.zxing.client.result.EmailDoCoMoParsedResult;
|
||||
import com.google.zxing.client.result.GeoParsedResult;
|
||||
import com.google.zxing.client.result.ParsedReaderResult;
|
||||
import com.google.zxing.client.result.ParsedReaderResultType;
|
||||
import com.google.zxing.client.result.TelParsedResult;
|
||||
import com.google.zxing.client.result.UPCParsedResult;
|
||||
import com.google.zxing.client.result.URIParsedResult;
|
||||
import com.google.zxing.client.result.URLTOParsedResult;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import com.google.zxing.client.result.*;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
* Handles the result of barcode decoding in the context of the Android platform,
|
||||
* by dispatching the proper intents and so on.
|
||||
* by dispatching the proper intents to open other activities like GMail, Maps, etc.
|
||||
*
|
||||
* @author srowen@google.com (Sean Owen)
|
||||
* @author dswitkin@google.com (Daniel Switkin)
|
||||
*/
|
||||
final class ResultHandler extends Handler {
|
||||
final class ResultHandler implements Button.OnClickListener {
|
||||
|
||||
private static final String TAG = "ResultHandler";
|
||||
|
||||
|
@ -133,15 +122,10 @@ final class ResultHandler extends Handler {
|
|||
return intent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
if (message.what == R.string.button_yes) {
|
||||
public void onClick(View view) {
|
||||
if (intent != null) {
|
||||
captureActivity.startActivity(intent);
|
||||
}
|
||||
} else {
|
||||
captureActivity.restartPreview();
|
||||
}
|
||||
}
|
||||
|
||||
Intent getIntent() {
|
||||
|
|
|
@ -16,21 +16,18 @@
|
|||
-->
|
||||
<resources>
|
||||
<string name="app_name">Barcode Reader</string>
|
||||
<string name="button_no">No</string>
|
||||
<string name="button_add_contact">Add Contact</string>
|
||||
<string name="button_dial">Dial</string>
|
||||
<string name="button_email">Email</string>
|
||||
<string name="button_lookup_product">Lookup Product</string>
|
||||
<string name="button_ok">OK</string>
|
||||
<string name="button_yes">Yes</string>
|
||||
<string name="button_open_browser">Open Browser</string>
|
||||
<string name="button_show_map">Show Map</string>
|
||||
<string name="menu_about">About...</string>
|
||||
<string name="menu_help">Help...</string>
|
||||
<string name="msg_about">ZXing Barcode Reader v@VERSION@\nhttp://code.google.com/p/zxing</string>
|
||||
<string name="msg_help">A: Decode all barcodes\nC: Capture and save a JPEG\nP: Use the preview image for decoding\nQ: Decode only QR Codes\nS: Use a still image for decoding\nT: Toggle debug method tracing\nU: Decode only UPC/1D barcodes</string>
|
||||
<string name="msg_default_status">Place a barcode inside the viewfinder rectangle to read it.</string>
|
||||
<string name="title_about">About</string>
|
||||
<string name="title_add_contact">Add Contact?</string>
|
||||
<string name="title_barcode_detected">Barcode Detected</string>
|
||||
<string name="title_compose_email">Compose E-mail?</string>
|
||||
<string name="title_dial">Dial Number?</string>
|
||||
<string name="title_error">Error</string>
|
||||
<string name="title_help">Keyboard Shortcut Help</string>
|
||||
<string name="title_lookup_barcode">Look Up Barcode Online?</string>
|
||||
<string name="title_open_url">Open Web Page?</string>
|
||||
<string name="title_view_maps">View In Google Maps?</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue