Try adding current javadoc to SVN
[zxing.git] / android / src / com / google / zxing / client / android / ShareActivity.java
1 /*
2  * Copyright (C) 2008 ZXing authors
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.ContentResolver;
21 import android.content.Intent;
22 import android.database.Cursor;
23 import android.net.Uri;
24 import android.os.Bundle;
25 import android.provider.Browser;
26 import android.provider.Contacts;
27 import android.provider.BaseColumns;
28 import android.text.ClipboardManager;
29 import android.view.View;
30 import android.widget.Button;
31
32 public final class ShareActivity extends Activity {
33
34   private static final int PICK_BOOKMARK = 0;
35   private static final int PICK_CONTACT = 1;
36
37   //private static final int METHODS_ID_COLUMN = 0;
38   private static final int METHODS_KIND_COLUMN = 1;
39   private static final int METHODS_DATA_COLUMN = 2;
40
41   private static final String[] METHODS_PROJECTION = {
42       BaseColumns._ID, // 0
43       Contacts.ContactMethodsColumns.KIND, // 1
44       Contacts.ContactMethodsColumns.DATA, // 2
45   };
46
47   private static final int PHONES_NUMBER_COLUMN = 1;
48
49   private static final String[] PHONES_PROJECTION = {
50       BaseColumns._ID, // 0
51       Contacts.PhonesColumns.NUMBER // 1
52   };
53
54   private Button mClipboardButton;
55
56   @Override
57   public void onCreate(Bundle icicle) {
58     super.onCreate(icicle);
59     setContentView(R.layout.share);
60
61     Button mContactButton = (Button) findViewById(R.id.contact_button);
62     mContactButton.setOnClickListener(mContactListener);
63     Button mBookmarkButton = (Button) findViewById(R.id.bookmark_button);
64     mBookmarkButton.setOnClickListener(mBookmarkListener);
65     mClipboardButton = (Button) findViewById(R.id.clipboard_button);
66     mClipboardButton.setOnClickListener(mClipboardListener);
67   }
68
69   @Override
70   protected void onResume() {
71     super.onResume();
72
73     ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
74     if (clipboard.hasText()) {
75       mClipboardButton.setEnabled(true);
76       mClipboardButton.setText(R.string.button_share_clipboard);
77     } else {
78       mClipboardButton.setEnabled(false);
79       mClipboardButton.setText(R.string.button_clipboard_empty);
80     }
81   }
82
83   private final Button.OnClickListener mContactListener = new Button.OnClickListener() {
84     public void onClick(View v) {
85       startActivityForResult(new Intent(Intent.ACTION_PICK, Contacts.People.CONTENT_URI),
86           PICK_CONTACT);
87     }
88   };
89
90   private final Button.OnClickListener mBookmarkListener = new Button.OnClickListener() {
91     public void onClick(View v) {
92       Intent intent = new Intent(Intent.ACTION_PICK);
93       intent.setClassName(ShareActivity.this, BookmarkPickerActivity.class.getName());
94       startActivityForResult(intent, PICK_BOOKMARK);
95     }
96   };
97
98   private final Button.OnClickListener mClipboardListener = new Button.OnClickListener() {
99     public void onClick(View v) {
100       ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
101       // Should always be true, because we grey out the clipboard button in onResume() if it's empty
102       if (clipboard.hasText()) {
103         Intent intent = new Intent(Intents.Encode.ACTION);
104         intent.putExtra(Intents.Encode.TYPE, Contents.Type.TEXT);
105         intent.putExtra(Intents.Encode.DATA, clipboard.getText());
106         intent.putExtra(Intents.Encode.FORMAT, Contents.Format.QR_CODE);
107         startActivity(intent);
108       }
109     }
110   };
111
112   @Override
113   public void onActivityResult(int requestCode, int resultCode, Intent intent) {
114     if (resultCode == RESULT_OK) {
115       switch (requestCode) {
116         case PICK_BOOKMARK:
117           showTextAsBarcode(intent.getStringExtra(Browser.BookmarkColumns.URL));
118           break;
119         case PICK_CONTACT:
120           // Data field is content://contacts/people/984
121           showContactAsBarcode(intent.getData());
122           break;
123       }
124     }
125   }
126
127   private void showTextAsBarcode(String text) {
128     Intent intent = new Intent(Intents.Encode.ACTION);
129     intent.putExtra(Intents.Encode.TYPE, Contents.Type.TEXT);
130     intent.putExtra(Intents.Encode.DATA, text);
131     intent.putExtra(Intents.Encode.FORMAT, Contents.Format.QR_CODE);
132     startActivity(intent);
133   }
134
135   /**
136    * Takes a contact Uri and does the necessary database lookups to retrieve that person's info,
137    * then sends an Encode intent to render it as a QR Code.
138    *
139    * @param contactUri A Uri of the form content://contacts/people/17
140    */
141   private void showContactAsBarcode(Uri contactUri) {
142     ContentResolver resolver = getContentResolver();
143     Cursor contactCursor = resolver.query(contactUri, null, null, null, null);
144     Bundle bundle = new Bundle();
145     if (contactCursor != null && contactCursor.moveToFirst()) {
146       int nameColumn = contactCursor.getColumnIndex(Contacts.PeopleColumns.NAME);
147       String name = contactCursor.getString(nameColumn);
148
149       // Don't require a name to be present, this contact might be just a phone number.
150       if (name != null && name.length() > 0) {
151         bundle.putString(Contacts.Intents.Insert.NAME, massageContactData(name));
152       }
153       contactCursor.close();
154
155       Uri phonesUri = Uri.withAppendedPath(contactUri, Contacts.People.Phones.CONTENT_DIRECTORY);
156       Cursor phonesCursor = resolver.query(phonesUri, PHONES_PROJECTION, null, null, null);
157       if (phonesCursor != null) {
158         int foundPhone = 0;
159         while (phonesCursor.moveToNext()) {
160           String number = phonesCursor.getString(PHONES_NUMBER_COLUMN);
161           if (foundPhone < Contents.PHONE_KEYS.length) {
162             bundle.putString(Contents.PHONE_KEYS[foundPhone], massageContactData(number));
163             foundPhone++;
164           }
165         }
166         phonesCursor.close();
167       }
168
169       Uri methodsUri = Uri.withAppendedPath(contactUri,
170           Contacts.People.ContactMethods.CONTENT_DIRECTORY);
171       Cursor methodsCursor = resolver.query(methodsUri, METHODS_PROJECTION, null, null, null);
172       if (methodsCursor != null) {
173         int foundEmail = 0;
174         boolean foundPostal = false;
175         while (methodsCursor.moveToNext()) {
176           int kind = methodsCursor.getInt(METHODS_KIND_COLUMN);
177           String data = methodsCursor.getString(METHODS_DATA_COLUMN);
178           switch (kind) {
179             case Contacts.KIND_EMAIL:
180               if (foundEmail < Contents.EMAIL_KEYS.length) {
181                 bundle.putString(Contents.EMAIL_KEYS[foundEmail], massageContactData(data));
182                 foundEmail++;
183               }
184               break;
185             case Contacts.KIND_POSTAL:
186               if (!foundPostal) {
187                 bundle.putString(Contacts.Intents.Insert.POSTAL, massageContactData(data));
188                 foundPostal = true;
189               }
190               break;
191           }
192         }
193         methodsCursor.close();
194       }
195
196       Intent intent = new Intent(Intents.Encode.ACTION);
197       intent.putExtra(Intents.Encode.TYPE, Contents.Type.CONTACT);
198       intent.putExtra(Intents.Encode.DATA, bundle);
199       intent.putExtra(Intents.Encode.FORMAT, Contents.Format.QR_CODE);
200
201       startActivity(intent);
202     }
203   }
204
205   private static String massageContactData(String data) {
206     // For now -- make sure we don't put newlines in shared contact data. It messes up
207     // any known encoding of contact data. Replace with space.
208     if (data.indexOf('\n') >= 0) {
209       data = data.replace("\n", " ");
210     }
211     if (data.indexOf('\r') >= 0) {
212       data = data.replace("\r", " ");
213     }
214     return data;
215   }
216
217 }