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, String, String, String, String)} or
59 * {@link #initiateScan(Activity, int, int, int, int)} to customize the download prompt with
60 * different text labels.</p>
62 * <h2>Sharing text via barcode</h2>
64 * <p>To share text, encoded as a QR Code on-screen, similarly, see {@link #shareText(Activity, String)}.</p>
66 * <p>Some code, particularly download integration, was contributed from the Anobiit application.</p>
70 * @author Isaac Potoczny-Jones
71 * @author Brad Drehmer
73 public final class IntentIntegrator {
75 public static final int REQUEST_CODE = 0x0ba7c0de; // get it?
77 public static final String DEFAULT_TITLE = "Install Barcode Scanner?";
78 public static final String DEFAULT_MESSAGE =
79 "This application requires Barcode Scanner. Would you like to install it?";
80 public static final String DEFAULT_YES = "Yes";
81 public static final String DEFAULT_NO = "No";
83 // supported barcode formats
84 public static final String PRODUCT_CODE_TYPES = "UPC_A,UPC_E,EAN_8,EAN_13";
85 public static final String ONE_D_CODE_TYPES = PRODUCT_CODE_TYPES + ",CODE_39,CODE_128";
86 public static final String QR_CODE_TYPES = "QR_CODE";
87 public static final String ALL_CODE_TYPES = null;
89 private IntentIntegrator() {
93 * See {@link #initiateScan(Activity, String, String, String, String)} --
94 * same, but uses default English labels.
96 public static void initiateScan(Activity activity) {
97 initiateScan(activity, DEFAULT_TITLE, DEFAULT_MESSAGE, DEFAULT_YES, DEFAULT_NO);
101 * See {@link #initiateScan(Activity, String, String, String, String)} --
102 * same, but takes string IDs which refer
103 * to the {@link Activity}'s resource bundle entries.
105 public static void initiateScan(Activity activity,
109 int stringButtonNo) {
110 initiateScan(activity,
111 activity.getString(stringTitle),
112 activity.getString(stringMessage),
113 activity.getString(stringButtonYes),
114 activity.getString(stringButtonNo));
118 * See {@link #initiateScan(Activity, String, String, String, String, String)} --
119 * same, but scans for all supported barcode types.
120 * @param stringTitle title of dialog prompting user to download Barcode Scanner
121 * @param stringMessage text of dialog prompting user to download Barcode Scanner
122 * @param stringButtonYes text of button user clicks when agreeing to download
123 * Barcode Scanner (e.g. "Yes")
124 * @param stringButtonNo text of button user clicks when declining to download
125 * Barcode Scanner (e.g. "No")
127 public static void initiateScan(Activity activity,
129 String stringMessage,
130 String stringButtonYes,
131 String stringButtonNo) {
133 initiateScan(activity,
144 * @param stringTitle title of dialog prompting user to download Barcode Scanner
145 * @param stringMessage text of dialog prompting user to download Barcode Scanner
146 * @param stringButtonYes text of button user clicks when agreeing to download
147 * Barcode Scanner (e.g. "Yes")
148 * @param stringButtonNo text of button user clicks when declining to download
149 * Barcode Scanner (e.g. "No")
150 * @param stringDesiredBarcodeFormats a comma separated list of codes you would
152 * @return the contents of the barcode that was scanned, or null if none was found
153 * @throws InterruptedException if timeout expires before a scan completes
155 public static void initiateScan(Activity activity,
157 String stringMessage,
158 String stringButtonYes,
159 String stringButtonNo,
160 String stringDesiredBarcodeFormats) {
161 Intent intentScan = new Intent("com.google.zxing.client.android.SCAN");
162 intentScan.addCategory(Intent.CATEGORY_DEFAULT);
164 // check which types of codes to scan for
165 if (stringDesiredBarcodeFormats != null) {
166 // set the desired barcode types
167 intentScan.putExtra("SCAN_FORMATS", stringDesiredBarcodeFormats);
171 activity.startActivityForResult(intentScan, REQUEST_CODE);
172 } catch (ActivityNotFoundException e) {
173 showDownloadDialog(activity, stringTitle, stringMessage, stringButtonYes, stringButtonNo);
177 private static void showDownloadDialog(final Activity activity,
179 String stringMessage,
180 String stringButtonYes,
181 String stringButtonNo) {
182 AlertDialog.Builder downloadDialog = new AlertDialog.Builder(activity);
183 downloadDialog.setTitle(stringTitle);
184 downloadDialog.setMessage(stringMessage);
185 downloadDialog.setPositiveButton(stringButtonYes, new DialogInterface.OnClickListener() {
186 public void onClick(DialogInterface dialogInterface, int i) {
187 Uri uri = Uri.parse("market://search?q=pname:com.google.zxing.client.android");
188 Intent intent = new Intent(Intent.ACTION_VIEW, uri);
189 activity.startActivity(intent);
192 downloadDialog.setNegativeButton(stringButtonNo, new DialogInterface.OnClickListener() {
193 public void onClick(DialogInterface dialogInterface, int i) {}
195 downloadDialog.show();
200 * <p>Call this from your {@link Activity}'s
201 * {@link Activity#onActivityResult(int, int, Intent)} method.</p>
203 * @return null if the event handled here was not related to {@link IntentIntegrator}, or
204 * else an {@link IntentResult} containing the result of the scan. If the user cancelled scanning,
205 * the fields will be null.
207 public static IntentResult parseActivityResult(int requestCode, int resultCode, Intent intent) {
208 if (requestCode == REQUEST_CODE) {
209 if (resultCode == Activity.RESULT_OK) {
210 String contents = intent.getStringExtra("SCAN_RESULT");
211 String formatName = intent.getStringExtra("SCAN_RESULT_FORMAT");
212 return new IntentResult(contents, formatName);
214 return new IntentResult(null, null);
221 * See {@link #shareText(Activity, String, String, String, String, String)} --
222 * same, but uses default English labels.
224 public static void shareText(Activity activity, String text) {
225 shareText(activity, text, DEFAULT_TITLE, DEFAULT_MESSAGE, DEFAULT_YES, DEFAULT_NO);
229 * See {@link #shareText(Activity, String, String, String, String, String)} --
230 * same, but takes string IDs which refer to the {@link Activity}'s resource bundle entries.
232 public static void shareText(Activity activity,
237 int stringButtonNo) {
240 activity.getString(stringTitle),
241 activity.getString(stringMessage),
242 activity.getString(stringButtonYes),
243 activity.getString(stringButtonNo));
247 * Shares the given text by encoding it as a barcode, such that another user can
248 * scan the text off the screen of the device.
250 * @param text the text string to encode as a barcode
251 * @param stringTitle title of dialog prompting user to download Barcode Scanner
252 * @param stringMessage text of dialog prompting user to download Barcode Scanner
253 * @param stringButtonYes text of button user clicks when agreeing to download
254 * Barcode Scanner (e.g. "Yes")
255 * @param stringButtonNo text of button user clicks when declining to download
256 * Barcode Scanner (e.g. "No")
258 public static void shareText(Activity activity,
261 String stringMessage,
262 String stringButtonYes,
263 String stringButtonNo) {
265 Intent intent = new Intent();
266 intent.setAction("com.google.zxing.client.android.ENCODE");
267 intent.putExtra("ENCODE_TYPE", "TEXT_TYPE");
268 intent.putExtra("ENCODE_DATA", text);
270 activity.startActivity(intent);
271 } catch (ActivityNotFoundException e) {
272 showDownloadDialog(activity, stringTitle, stringMessage, stringButtonYes, stringButtonNo);