2 * Copyright 2009 ZXing authors
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.google.zxing.integration.android;
19 import android.app.AlertDialog;
20 import android.app.Activity;
21 import android.content.ActivityNotFoundException;
22 import android.content.DialogInterface;
23 import android.content.Intent;
24 import android.net.Uri;
27 * <p>A utility class which helps ease integration with Barcode Scanner via {@link Intent}s. This is a simple
28 * way to invoke barcode scanning and receive the result, without any need to integrate, modify, or learn the
29 * project's source code.</p>
31 * <h2>Initiating a barcode scan</h2>
33 * <p>Integration is essentially as easy as calling {@link #initiateScan(Activity)} and waiting
34 * for the result in your app.</p>
36 * <p>It does require that the Barcode Scanner application is installed. The
37 * {@link #initiateScan(Activity)} method will prompt the user to download the application, if needed.</p>
39 * <p>There are a few steps to using this integration. First, your {@link Activity} must implement
40 * the method {@link Activity#onActivityResult(int, int, Intent)} and include a line of code like this:</p>
43 * public void onActivityResult(int requestCode, int resultCode, Intent intent) {
44 * IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
45 * if (scanResult != null) {
46 * // handle scan result
48 * // else continue with any other code you need in the method
53 * <p>This is where you will handle a scan result.
54 * Second, just call this in response to a user action somewhere to begin the scan process:</p>
56 * <p>{@code IntentIntegrator.initiateScan(yourActivity);}</p>
58 * <p>You can use {@link #initiateScan(Activity, CharSequence, CharSequence, CharSequence, CharSequence)} or
59 * {@link #initiateScan(Activity, int, int, int, int)} to customize the download prompt with
60 * different text labels.</p>
62 * <p>Note that {@link #initiateScan(Activity)} returns an {@link AlertDialog} which is non-null if the
63 * user was prompted to download the application. This lets the calling app potentially manage the dialog.
64 * In particular, ideally, the app dismisses the dialog if it's still active in its {@link Activity#onPause()}
67 * <h2>Sharing text via barcode</h2>
69 * <p>To share text, encoded as a QR Code on-screen, similarly, see {@link #shareText(Activity, CharSequence)}.</p>
71 * <p>Some code, particularly download integration, was contributed from the Anobiit application.</p>
75 * @author Isaac Potoczny-Jones
76 * @author Brad Drehmer
78 public final class IntentIntegrator {
80 public static final int REQUEST_CODE = 0x0ba7c0de; // get it?
82 public static final String DEFAULT_TITLE = "Install Barcode Scanner?";
83 public static final String DEFAULT_MESSAGE =
84 "This application requires Barcode Scanner. Would you like to install it?";
85 public static final String DEFAULT_YES = "Yes";
86 public static final String DEFAULT_NO = "No";
88 // supported barcode formats
89 public static final String PRODUCT_CODE_TYPES = "UPC_A,UPC_E,EAN_8,EAN_13";
90 public static final String ONE_D_CODE_TYPES = PRODUCT_CODE_TYPES + ",CODE_39,CODE_93,CODE_128";
91 public static final String QR_CODE_TYPES = "QR_CODE";
92 public static final String ALL_CODE_TYPES = null;
94 private IntentIntegrator() {
98 * See {@link #initiateScan(Activity, CharSequence, CharSequence, CharSequence, CharSequence)} --
99 * same, but uses default English labels.
101 public static AlertDialog initiateScan(Activity activity) {
102 return initiateScan(activity, DEFAULT_TITLE, DEFAULT_MESSAGE, DEFAULT_YES, DEFAULT_NO);
106 * See {@link #initiateScan(Activity, CharSequence, CharSequence, CharSequence, CharSequence)} --
107 * same, but takes string IDs which refer
108 * to the {@link Activity}'s resource bundle entries.
110 public static AlertDialog initiateScan(Activity activity,
114 int stringButtonNo) {
115 return initiateScan(activity,
116 activity.getString(stringTitle),
117 activity.getString(stringMessage),
118 activity.getString(stringButtonYes),
119 activity.getString(stringButtonNo));
123 * See {@link #initiateScan(Activity, CharSequence, CharSequence, CharSequence, CharSequence, CharSequence)} --
124 * same, but scans for all supported barcode types.
125 * @param stringTitle title of dialog prompting user to download Barcode Scanner
126 * @param stringMessage text of dialog prompting user to download Barcode Scanner
127 * @param stringButtonYes text of button user clicks when agreeing to download
128 * Barcode Scanner (e.g. "Yes")
129 * @param stringButtonNo text of button user clicks when declining to download
130 * Barcode Scanner (e.g. "No")
131 * @return an {@link AlertDialog} if the user was prompted to download the app,
134 public static AlertDialog initiateScan(Activity activity,
135 CharSequence stringTitle,
136 CharSequence stringMessage,
137 CharSequence stringButtonYes,
138 CharSequence stringButtonNo) {
140 return initiateScan(activity,
151 * @param stringTitle title of dialog prompting user to download Barcode Scanner
152 * @param stringMessage text of dialog prompting user to download Barcode Scanner
153 * @param stringButtonYes text of button user clicks when agreeing to download
154 * Barcode Scanner (e.g. "Yes")
155 * @param stringButtonNo text of button user clicks when declining to download
156 * Barcode Scanner (e.g. "No")
157 * @param stringDesiredBarcodeFormats a comma separated list of codes you would
159 * @return an {@link AlertDialog} if the user was prompted to download the app,
161 * @throws InterruptedException if timeout expires before a scan completes
163 public static AlertDialog initiateScan(Activity activity,
164 CharSequence stringTitle,
165 CharSequence stringMessage,
166 CharSequence stringButtonYes,
167 CharSequence stringButtonNo,
168 CharSequence stringDesiredBarcodeFormats) {
169 Intent intentScan = new Intent("com.google.zxing.client.android.SCAN");
170 intentScan.addCategory(Intent.CATEGORY_DEFAULT);
172 // check which types of codes to scan for
173 if (stringDesiredBarcodeFormats != null) {
174 // set the desired barcode types
175 intentScan.putExtra("SCAN_FORMATS", stringDesiredBarcodeFormats);
179 activity.startActivityForResult(intentScan, REQUEST_CODE);
181 } catch (ActivityNotFoundException e) {
182 return showDownloadDialog(activity, stringTitle, stringMessage, stringButtonYes, stringButtonNo);
186 private static AlertDialog showDownloadDialog(final Activity activity,
187 CharSequence stringTitle,
188 CharSequence stringMessage,
189 CharSequence stringButtonYes,
190 CharSequence stringButtonNo) {
191 AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
192 downloadDialog.setTitle(stringTitle);
193 downloadDialog.setMessage(stringMessage);
194 downloadDialog.setPositiveButton(stringButtonYes, new DialogInterface.OnClickListener() {
195 public void onClick(DialogInterface dialogInterface, int i) {
196 Uri uri = Uri.parse("market://search?q=pname:com.google.zxing.client.android");
197 Intent intent = new Intent(Intent.ACTION_VIEW, uri);
198 activity.startActivity(intent);
201 downloadDialog.setNegativeButton(stringButtonNo, new DialogInterface.OnClickListener() {
202 public void onClick(DialogInterface dialogInterface, int i) {}
204 return downloadDialog.show();
209 * <p>Call this from your {@link Activity}'s
210 * {@link Activity#onActivityResult(int, int, Intent)} method.</p>
212 * @return null if the event handled here was not related to {@link IntentIntegrator}, or
213 * else an {@link IntentResult} containing the result of the scan. If the user cancelled scanning,
214 * the fields will be null.
216 public static IntentResult parseActivityResult(int requestCode, int resultCode, Intent intent) {
217 if (requestCode == REQUEST_CODE) {
218 if (resultCode == Activity.RESULT_OK) {
219 String contents = intent.getStringExtra("SCAN_RESULT");
220 String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
221 return new IntentResult(contents, formatName);
223 return new IntentResult(null, null);
230 * See {@link #shareText(Activity, CharSequence, CharSequence, CharSequence, CharSequence, CharSequence)} --
231 * same, but uses default English labels.
233 public static void shareText(Activity activity, CharSequence text) {
234 shareText(activity, text, DEFAULT_TITLE, DEFAULT_MESSAGE, DEFAULT_YES, DEFAULT_NO);
238 * See {@link #shareText(Activity, CharSequence, CharSequence, CharSequence, CharSequence, CharSequence)} --
239 * same, but takes string IDs which refer to the {@link Activity}'s resource bundle entries.
241 public static void shareText(Activity activity,
246 int stringButtonNo) {
249 activity.getString(stringTitle),
250 activity.getString(stringMessage),
251 activity.getString(stringButtonYes),
252 activity.getString(stringButtonNo));
256 * Shares the given text by encoding it as a barcode, such that another user can
257 * scan the text off the screen of the device.
259 * @param text the text string to encode as a barcode
260 * @param stringTitle title of dialog prompting user to download Barcode Scanner
261 * @param stringMessage text of dialog prompting user to download Barcode Scanner
262 * @param stringButtonYes text of button user clicks when agreeing to download
263 * Barcode Scanner (e.g. "Yes")
264 * @param stringButtonNo text of button user clicks when declining to download
265 * Barcode Scanner (e.g. "No")
267 public static void shareText(Activity activity,
269 CharSequence stringTitle,
270 CharSequence stringMessage,
271 CharSequence stringButtonYes,
272 CharSequence stringButtonNo) {
274 Intent intent = new Intent();
275 intent.setAction("com.google.zxing.client.android.ENCODE");
276 intent.putExtra("ENCODE_TYPE", "TEXT_TYPE");
277 intent.putExtra("ENCODE_DATA", text);
279 activity.startActivity(intent);
280 } catch (ActivityNotFoundException e) {
281 showDownloadDialog(activity, stringTitle, stringMessage, stringButtonYes, stringButtonNo);