Initialized merge tracking via "svnmerge" with revisions "1-319" from
[zxing.git] / android / src / com / google / zxing / client / android / BarcodeReaderCaptureActivity.java
1 /*
2  * Copyright (C) 2008 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.google.zxing.client.android;
18
19 import android.app.Activity;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.os.Bundle;
23 import android.os.Handler;
24 import android.os.Message;
25 import android.view.KeyEvent;
26 import android.view.Menu;
27 import android.view.Window;
28 import com.google.zxing.Result;
29 import com.google.zxing.ResultPoint;
30 import com.google.zxing.client.result.ParsedReaderResult;
31 import com.google.zxing.client.result.ParsedReaderResultType;
32
33 /**
34  * The barcode reader activity itself. This is loosely based on the CameraPreview
35  * example included in the Android SDK.
36  *
37  * @author dswitkin@google.com (Daniel Switkin)
38  * @author Android Team (for CameraPreview example)
39  */
40 public final class BarcodeReaderCaptureActivity extends Activity {
41
42   private CameraManager cameraManager;
43   private CameraSurfaceView surfaceView;
44   private WorkerThread workerThread;
45
46   private static final int ABOUT_ID = Menu.FIRST;
47
48   @Override
49   public void onCreate(Bundle icicle) {
50     super.onCreate(icicle);
51     requestWindowFeature(Window.FEATURE_NO_TITLE);
52
53     cameraManager = new CameraManager(getApplication());
54     surfaceView = new CameraSurfaceView(getApplication(), cameraManager);
55     setContentView(surfaceView);
56     workerThread = new WorkerThread(surfaceView, cameraManager, messageHandler);
57     workerThread.requestPreviewLoop();
58     workerThread.start();
59
60     // TODO re-enable this when issues with Matrix.setPolyToPoly() are resolved
61     //GridSampler.setGridSampler(new AndroidGraphicsGridSampler());
62   }
63
64   @Override
65   protected void onResume() {
66     super.onResume();
67     cameraManager.openDriver();
68     if (workerThread == null) {
69       workerThread = new WorkerThread(surfaceView, cameraManager, messageHandler);
70       workerThread.requestPreviewLoop();
71       workerThread.start();
72     }
73   }
74
75   @Override
76   protected void onPause() {
77     super.onPause();
78     if (workerThread != null) {
79       workerThread.requestExitAndWait();
80       workerThread = null;
81     }
82     cameraManager.closeDriver();
83   }
84
85   @Override
86   public boolean onKeyDown(int keyCode, KeyEvent event) {
87     if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
88       workerThread.requestStillAndDecode();
89       return true;
90     } else {
91       return super.onKeyDown(keyCode, event);
92     }
93   }
94
95   @Override
96   public boolean onCreateOptionsMenu(Menu menu) {
97     super.onCreateOptionsMenu(menu);
98     menu.add(0, ABOUT_ID, R.string.menu_about);
99     return true;
100   }
101
102   @Override
103   public boolean onOptionsItemSelected(Menu.Item item) {
104     switch (item.getId()) {
105       case ABOUT_ID:
106         Context context = getApplication();
107         showAlert(
108           context.getString(R.string.title_about),
109           0,
110           context.getString(R.string.msg_about),
111           context.getString(R.string.button_ok),
112           true);
113         break;
114     }
115     return super.onOptionsItemSelected(item);
116   }
117
118   private final Handler messageHandler = new Handler() {
119     @Override
120     public void handleMessage(Message message) {
121       switch (message.what) {
122         case R.id.decoding_succeeded_message:
123           handleDecode((Result) message.obj);
124           break;
125         case R.id.decoding_failed_message:
126           Context context = getApplication();
127           showAlert(
128             context.getString(R.string.title_no_barcode_detected),
129             0,
130             context.getString(R.string.msg_no_barcode_detected),
131             context.getString(R.string.button_ok),
132             true);
133           break;
134       }
135     }
136   };
137
138   public void restartPreview() {
139     workerThread.requestPreviewLoop();
140   }
141
142   private void handleDecode(Result rawResult) {
143     ResultPoint[] points = rawResult.getResultPoints();
144     if (points != null && points.length > 0) {
145       surfaceView.drawResultPoints(points);
146     }
147
148     Context context = getApplication();
149     ParsedReaderResult readerResult = parseReaderResult(rawResult);
150     ResultHandler handler = new ResultHandler(this, readerResult);
151     if (handler.getIntent() != null) {
152       // Can be handled by some external app; ask if the user wants to
153       // proceed first though
154       showAlert(
155         context.getString(getDialogTitleID(readerResult.getType())),
156         0,
157         readerResult.getDisplayResult(),
158         context.getString(R.string.button_yes),
159         handler,
160         context.getString(R.string.button_no),
161         null,
162         true,
163         null
164       );
165
166     } else {
167       // Just show information to user
168       showAlert(
169         context.getString(R.string.title_barcode_detected),
170         0,
171         readerResult.getDisplayResult(),
172         context.getString(R.string.button_ok),
173         true);
174     }
175   }
176
177   private static ParsedReaderResult parseReaderResult(Result rawResult) {
178     ParsedReaderResult readerResult = ParsedReaderResult.parseReaderResult(rawResult);
179     if (readerResult.getType().equals(ParsedReaderResultType.TEXT)) {
180       String rawText = rawResult.getText();
181       AndroidIntentParsedResult androidResult = AndroidIntentParsedResult.parse(rawText);
182       if (androidResult != null) {
183         Intent intent = androidResult.getIntent();
184         if (!Intent.VIEW_ACTION.equals(intent.getAction())) {
185           // For now, don't take anything that just parses as a View action. A lot
186           // of things are accepted as a View action by default.
187           readerResult = androidResult;          
188         }
189       }
190     }
191     return readerResult;
192   }
193
194   private static int getDialogTitleID(ParsedReaderResultType type) {
195     if (type.equals(ParsedReaderResultType.ADDRESSBOOK)) {
196       return R.string.title_add_contact;
197     } else if (type.equals(ParsedReaderResultType.URI) ||
198                type.equals(ParsedReaderResultType.BOOKMARK) ||
199                type.equals(ParsedReaderResultType.URLTO)) {
200       return R.string.title_open_url;
201     } else if (type.equals(ParsedReaderResultType.EMAIL) ||
202                type.equals(ParsedReaderResultType.EMAIL_ADDRESS)) {
203       return R.string.title_compose_email;
204     } else if (type.equals(ParsedReaderResultType.UPC)) {
205       return R.string.title_lookup_barcode;
206     } else if (type.equals(ParsedReaderResultType.TEL)) {
207       return R.string.title_dial;
208     } else if (type.equals(ParsedReaderResultType.GEO)) {
209       return R.string.title_view_maps;
210     } else {
211       return R.string.title_barcode_detected;
212     }
213   }
214
215 }