2 * Copyright (C) 2008 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.client.android;
19 import android.app.Activity;
20 import android.content.Intent;
21 import android.graphics.Bitmap;
22 import android.os.Bundle;
23 import android.os.Handler;
24 import android.os.Message;
25 import android.provider.Contacts;
26 import android.util.Log;
27 import android.telephony.PhoneNumberUtils;
28 import com.google.zxing.BarcodeFormat;
29 import com.google.zxing.MultiFormatWriter;
30 import com.google.zxing.WriterException;
31 import com.google.zxing.common.ByteMatrix;
33 public final class QRCodeEncoder {
35 private final Activity mActivity;
36 private String mContents;
37 private String mDisplayContents;
38 private String mTitle;
40 public QRCodeEncoder(Activity activity, Intent intent) {
42 if (!encodeContents(intent)) {
43 throw new IllegalArgumentException("No valid data to encode.");
47 public void requestBarcode(Handler handler, int pixelResolution) {
48 Thread encodeThread = new EncodeThread(mContents, handler, pixelResolution);
52 public String getContents() {
56 public String getDisplayContents() {
57 return mDisplayContents;
60 public String getTitle() {
64 // TODO: The string encoding should live in the core ZXing library.
65 private boolean encodeContents(Intent intent) {
69 String type = intent.getStringExtra(Intents.Encode.TYPE);
70 if (type == null || type.length() == 0) {
74 if (type.equals(Contents.Type.TEXT)) {
75 String data = intent.getStringExtra(Intents.Encode.DATA);
76 if (data != null && data.length() > 0) {
78 mDisplayContents = data;
79 mTitle = mActivity.getString(R.string.contents_text);
81 } else if (type.equals(Contents.Type.EMAIL)) {
82 String data = intent.getStringExtra(Intents.Encode.DATA);
83 if (data != null && data.length() > 0) {
84 mContents = "mailto:" + data;
85 mDisplayContents = data;
86 mTitle = mActivity.getString(R.string.contents_email);
88 } else if (type.equals(Contents.Type.PHONE)) {
89 String data = intent.getStringExtra(Intents.Encode.DATA);
90 if (data != null && data.length() > 0) {
91 mContents = "tel:" + data;
92 mDisplayContents = PhoneNumberUtils.formatNumber(data);
93 mTitle = mActivity.getString(R.string.contents_phone);
95 } else if (type.equals(Contents.Type.SMS)) {
96 String data = intent.getStringExtra(Intents.Encode.DATA);
97 if (data != null && data.length() > 0) {
98 mContents = "sms:" + data;
99 mDisplayContents = PhoneNumberUtils.formatNumber(data);
100 mTitle = mActivity.getString(R.string.contents_sms);
102 } else if (type.equals(Contents.Type.CONTACT)) {
103 Bundle bundle = intent.getBundleExtra(Intents.Encode.DATA);
104 if (bundle != null) {
105 String name = bundle.getString(Contacts.Intents.Insert.NAME);
106 if (name != null && name.length() > 0) {
107 mContents = "MECARD:N:" + name + ';';
108 mDisplayContents = name;
109 String address = bundle.getString(Contacts.Intents.Insert.POSTAL);
110 if (address != null && address.length() > 0) {
111 mContents += "ADR:" + address + ';';
112 mDisplayContents += '\n' + address;
114 for (int x = 0; x < Contents.PHONE_KEYS.length; x++) {
115 String phone = bundle.getString(Contents.PHONE_KEYS[x]);
116 if (phone != null && phone.length() > 0) {
117 mContents += "TEL:" + phone + ';';
118 mDisplayContents += '\n' + PhoneNumberUtils.formatNumber(phone);
121 for (int x = 0; x < Contents.EMAIL_KEYS.length; x++) {
122 String email = bundle.getString(Contents.EMAIL_KEYS[x]);
123 if (email != null && email.length() > 0) {
124 mContents += "EMAIL:" + email + ';';
125 mDisplayContents += '\n' + email;
129 mTitle = mActivity.getString(R.string.contents_contact);
132 } else if (type.equals(Contents.Type.LOCATION)) {
133 Bundle bundle = intent.getBundleExtra(Intents.Encode.DATA);
134 if (bundle != null) {
135 double latitude = bundle.getDouble("LAT", Double.NaN);
136 double longitude = bundle.getDouble("LONG", Double.NaN);
137 if (!Double.isNaN(latitude) && !Double.isNaN(longitude)) {
138 mContents = "geo:" + latitude + ',' + longitude;
139 mDisplayContents = latitude + "," + longitude;
140 mTitle = mActivity.getString(R.string.contents_location);
144 return mContents != null && mContents.length() > 0;
147 private static final class EncodeThread extends Thread {
149 private static final String TAG = "EncodeThread";
151 private final String mContents;
152 private final Handler mHandler;
153 private final int mPixelResolution;
155 EncodeThread(String contents, Handler handler, int pixelResolution) {
156 mContents = contents;
158 mPixelResolution = pixelResolution;
163 ByteMatrix result = new MultiFormatWriter().encode(mContents, BarcodeFormat.QR_CODE,
164 mPixelResolution, mPixelResolution);
165 int width = result.width();
166 int height = result.height();
167 byte[][] array = result.getArray();
168 int[] pixels = new int[width * height];
169 for (int y = 0; y < height; y++) {
170 for (int x = 0; x < width; x++) {
171 int grey = array[y][x] & 0xff;
172 //pixels[y * width + x] = (0xff << 24) | (grey << 16) | (grey << 8) | grey;
173 pixels[y * width + x] = 0xff000000 | (0x00010101 * grey);
177 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
178 bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
179 Message message = Message.obtain(mHandler, R.id.encode_succeeded);
180 message.obj = bitmap;
181 message.sendToTarget();
182 } catch (WriterException e) {
183 Log.e(TAG, e.toString());
184 Message message = Message.obtain(mHandler, R.id.encode_failed);
185 message.sendToTarget();
186 } catch (IllegalArgumentException e) {
187 Log.e(TAG, e.toString());
188 Message message = Message.obtain(mHandler, R.id.encode_failed);
189 message.sendToTarget();