570ad6da2c68c64b4aa515ab099aa80047aca9c5
[zxing.git] / android / src / com / android / barcodes / QRCodeEncoder.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.android.barcodes;
18
19 import android.app.Activity;
20 import android.content.Intent;
21 import android.graphics.Bitmap;
22 import android.graphics.BitmapFactory;
23 import android.net.http.AndroidHttpClient;
24 import android.os.Bundle;
25 import android.os.Handler;
26 import android.os.Message;
27 import android.provider.Contacts;
28 import android.util.Log;
29 import org.apache.http.HttpEntity;
30 import org.apache.http.HttpResponse;
31 import org.apache.http.client.methods.HttpGet;
32
33 import java.net.URI;
34
35 public class QRCodeEncoder {
36
37     private static final String TAG = "QRCodeEncoder";
38
39     private Activity mActivity;
40     private String mContents;
41     private String mDisplayContents;
42     private String mTitle;
43     private NetworkThread mNetworkThread;
44
45     public QRCodeEncoder(Activity activity, Intent intent) {
46         mActivity = activity;
47         if (!encodeContents(intent)) {
48             throw new IllegalArgumentException("No valid data to encode.");
49         }
50     }
51
52     // Once the core ZXing library supports encoding, we'll be able to generate the bitmap
53     // synchronously. For now, it's a network request, so it's handled on a thread.
54     public void requestBarcode(Handler handler, int pixelResolution) {
55         mNetworkThread = new NetworkThread(mContents, handler, pixelResolution);
56         mNetworkThread.start();
57     }
58
59     public String getContents() {
60         return mContents;
61     }
62
63     public String getDisplayContents() {
64         return mDisplayContents;
65     }
66
67     public String getTitle() {
68         return mTitle;
69     }
70
71     // Perhaps the string encoding should live in the core ZXing library too.
72     private boolean encodeContents(Intent intent) {
73         if (intent == null) return false;
74         String type = intent.getStringExtra(Intents.Encode.TYPE);
75         if (type == null || type.length() == 0) return false;
76
77         if (type.equals(Contents.Type.TEXT)) {
78             String string = intent.getStringExtra(Intents.Encode.DATA);
79             if (string != null && string.length() > 0) {
80                 mContents = string;
81                 mDisplayContents = string;
82                 mTitle = mActivity.getString(R.string.contents_text);
83             }
84         } else if (type.equals(Contents.Type.EMAIL)) {
85             String string = intent.getStringExtra(Intents.Encode.DATA);
86             if (string != null && string.length() > 0) {
87                 mContents = "mailto:" + string;
88                 mDisplayContents = string;
89                 mTitle = mActivity.getString(R.string.contents_email);
90             }
91         } else if (type.equals(Contents.Type.PHONE)) {
92             String string = intent.getStringExtra(Intents.Encode.DATA);
93             if (string != null && string.length() > 0) {
94                 mContents = "tel:" + string;
95                 mDisplayContents = string;
96                 mTitle = mActivity.getString(R.string.contents_phone);
97             }
98         } else if (type.equals(Contents.Type.SMS)) {
99             String string = intent.getStringExtra(Intents.Encode.DATA);
100             if (string != null && string.length() > 0) {
101                 mContents = "sms:" + string;
102                 mDisplayContents = string;
103                 mTitle = mActivity.getString(R.string.contents_sms);
104             }
105         } else if (type.equals(Contents.Type.CONTACT)) {
106             Bundle bundle = intent.getBundleExtra(Intents.Encode.DATA);
107             if (bundle != null) {
108                 String name = bundle.getString(Contacts.Intents.Insert.NAME);
109                 if (name != null && !name.equals("")) {
110                     mContents = "MECARD:N:" + name + ";";
111                     mDisplayContents = name;
112                     String phone = bundle.getString(Contacts.Intents.Insert.PHONE);
113                     if (phone != null && !phone.equals("")) {
114                         mContents += "TEL:" + phone + ";";
115                         mDisplayContents += "\n" + phone;
116                     }
117                     String email = bundle.getString(Contacts.Intents.Insert.EMAIL);
118                     if (email != null && !email.equals("")) {
119                         mContents += "EMAIL:" + email + ";";
120                         mDisplayContents += "\n" + email;
121                     }
122                     mContents += ";";
123                     mTitle = mActivity.getString(R.string.contents_contact);
124                 }
125             }
126         } else if (type.equals(Contents.Type.LOCATION)) {
127             Bundle bundle = intent.getBundleExtra(Intents.Encode.DATA);
128             if (bundle != null) {
129                 float latitude = bundle.getFloat("LAT", Float.MAX_VALUE);
130                 float longitude = bundle.getFloat("LONG", Float.MAX_VALUE);
131                 if (latitude != Float.MAX_VALUE && longitude != Float.MAX_VALUE) {
132                     mContents = "geo:" + latitude + "," + longitude;
133                     mDisplayContents = latitude + "," + longitude;
134                     mTitle = mActivity.getString(R.string.contents_location);
135                 }
136             }
137         }
138         return mContents != null && mContents.length() > 0;
139     }
140
141     private class NetworkThread extends Thread {
142
143         private String mContents;
144         private Handler mHandler;
145         private int mPixelResolution;
146
147         public NetworkThread(String contents, Handler handler, int pixelResolution) {
148             mContents = contents;
149             mHandler = handler;
150             mPixelResolution = pixelResolution;
151         }
152
153         public void run() {
154             String url = "//chartserver.apis.google.com/chart?cht=qr&chs=";
155             url += mPixelResolution + "x" + mPixelResolution + "&chl=" + mContents;
156             try {
157                 URI uri = new URI("http", url, null);
158                 HttpGet get = new HttpGet(uri);
159                 AndroidHttpClient client = AndroidHttpClient.newInstance("Android-BarcodeScanner/0.1");
160                 HttpResponse response = client.execute(get);
161                 HttpEntity entity = response.getEntity();
162                 Bitmap image = BitmapFactory.decodeStream(entity.getContent());
163                 if (image != null) {
164                     Message message = Message.obtain(mHandler, R.id.encode_succeeded);
165                     message.obj = image;
166                     message.sendToTarget();
167                 } else {
168                     Log.e(TAG, "Could not decode png from the network");
169                     Message message = Message.obtain(mHandler, R.id.encode_failed);
170                     message.sendToTarget();
171                 }
172             } catch (Exception e) {
173                 Log.e(TAG, e.toString());
174                 Message message = Message.obtain(mHandler, R.id.encode_failed);
175                 message.sendToTarget();
176             }
177         }
178     }
179
180 }