import android.view.View;
import android.widget.Button;
+/**
+ * Barcode Scanner can share data like contacts and bookmarks by displaying a QR Code on screen,
+ * such that another user can scan the barcode with their phone.
+ *
+ * @author dswitkin@google.com (Daniel Switkin)
+ */
public final class ShareActivity extends Activity {
-
private static final int PICK_BOOKMARK = 0;
private static final int PICK_CONTACT = 1;
Contacts.ContactMethodsColumns.DATA, // 2
};
- private Button mClipboardButton;
+ private static final int PHONES_NUMBER_COLUMN = 1;
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- setContentView(R.layout.share);
-
- Button mContactButton = (Button) findViewById(R.id.contact_button);
- mContactButton.setOnClickListener(mContactListener);
- Button mBookmarkButton = (Button) findViewById(R.id.bookmark_button);
- mBookmarkButton.setOnClickListener(mBookmarkListener);
- mClipboardButton = (Button) findViewById(R.id.clipboard_button);
- mClipboardButton.setOnClickListener(mClipboardListener);
- }
-
- @Override
- protected void onResume() {
- super.onResume();
+ private static final String[] PHONES_PROJECTION = {
+ BaseColumns._ID, // 0
+ Contacts.PhonesColumns.NUMBER // 1
+ };
- ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
- if (clipboard.hasText()) {
- mClipboardButton.setEnabled(true);
- mClipboardButton.setText(R.string.button_share_clipboard);
- } else {
- mClipboardButton.setEnabled(false);
- mClipboardButton.setText(R.string.button_clipboard_empty);
- }
- }
+ private Button clipboardButton;
- private final Button.OnClickListener mContactListener = new Button.OnClickListener() {
+ private final Button.OnClickListener contactListener = new Button.OnClickListener() {
public void onClick(View v) {
startActivityForResult(new Intent(Intent.ACTION_PICK, Contacts.People.CONTENT_URI),
PICK_CONTACT);
}
};
- private final Button.OnClickListener mBookmarkListener = new Button.OnClickListener() {
+ private final Button.OnClickListener bookmarkListener = new Button.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setClassName(ShareActivity.this, BookmarkPickerActivity.class.getName());
}
};
- private final Button.OnClickListener mClipboardListener = new Button.OnClickListener() {
+ private final Button.OnClickListener clipboardListener = new Button.OnClickListener() {
public void onClick(View v) {
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
// Should always be true, because we grey out the clipboard button in onResume() if it's empty
Intent intent = new Intent(Intents.Encode.ACTION);
intent.putExtra(Intents.Encode.TYPE, Contents.Type.TEXT);
intent.putExtra(Intents.Encode.DATA, clipboard.getText());
+ intent.putExtra(Intents.Encode.FORMAT, Contents.Format.QR_CODE);
startActivity(intent);
}
}
};
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.share);
+
+ Button mContactButton = (Button) findViewById(R.id.contact_button);
+ mContactButton.setOnClickListener(contactListener);
+ Button mBookmarkButton = (Button) findViewById(R.id.bookmark_button);
+ mBookmarkButton.setOnClickListener(bookmarkListener);
+ clipboardButton = (Button) findViewById(R.id.clipboard_button);
+ clipboardButton.setOnClickListener(clipboardListener);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
+ if (clipboard.hasText()) {
+ clipboardButton.setEnabled(true);
+ clipboardButton.setText(R.string.button_share_clipboard);
+ } else {
+ clipboardButton.setEnabled(false);
+ clipboardButton.setText(R.string.button_clipboard_empty);
+ }
+ }
+
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode == RESULT_OK) {
Intent intent = new Intent(Intents.Encode.ACTION);
intent.putExtra(Intents.Encode.TYPE, Contents.Type.TEXT);
intent.putExtra(Intents.Encode.DATA, text);
+ intent.putExtra(Intents.Encode.FORMAT, Contents.Format.QR_CODE);
startActivity(intent);
}
/**
* Takes a contact Uri and does the necessary database lookups to retrieve that person's info,
* then sends an Encode intent to render it as a QR Code.
- *
+ *
* @param contactUri A Uri of the form content://contacts/people/17
*/
private void showContactAsBarcode(Uri contactUri) {
if (contactCursor != null && contactCursor.moveToFirst()) {
int nameColumn = contactCursor.getColumnIndex(Contacts.PeopleColumns.NAME);
String name = contactCursor.getString(nameColumn);
- if (name == null || name.length() == 0) {
- // TODO: Show error
- return;
- }
- bundle.putString(Contacts.Intents.Insert.NAME, name);
- int phoneColumn = contactCursor.getColumnIndex(Contacts.PhonesColumns.NUMBER);
- bundle.putString(Contacts.Intents.Insert.PHONE, contactCursor.getString(phoneColumn));
+ // Don't require a name to be present, this contact might be just a phone number.
+ if (name != null && name.length() > 0) {
+ bundle.putString(Contacts.Intents.Insert.NAME, massageContactData(name));
+ }
contactCursor.close();
+ Uri phonesUri = Uri.withAppendedPath(contactUri, Contacts.People.Phones.CONTENT_DIRECTORY);
+ Cursor phonesCursor = resolver.query(phonesUri, PHONES_PROJECTION, null, null, null);
+ if (phonesCursor != null) {
+ int foundPhone = 0;
+ while (phonesCursor.moveToNext()) {
+ String number = phonesCursor.getString(PHONES_NUMBER_COLUMN);
+ if (foundPhone < Contents.PHONE_KEYS.length) {
+ bundle.putString(Contents.PHONE_KEYS[foundPhone], massageContactData(number));
+ foundPhone++;
+ }
+ }
+ phonesCursor.close();
+ }
+
Uri methodsUri = Uri.withAppendedPath(contactUri,
Contacts.People.ContactMethods.CONTENT_DIRECTORY);
Cursor methodsCursor = resolver.query(methodsUri, METHODS_PROJECTION, null, null, null);
if (methodsCursor != null) {
- boolean foundEmail = false;
+ int foundEmail = 0;
boolean foundPostal = false;
while (methodsCursor.moveToNext()) {
int kind = methodsCursor.getInt(METHODS_KIND_COLUMN);
String data = methodsCursor.getString(METHODS_DATA_COLUMN);
switch (kind) {
case Contacts.KIND_EMAIL:
- if (!foundEmail) {
- // Use the first address encountered, since we can't encode multiple addresses
- bundle.putString(Contacts.Intents.Insert.EMAIL, data);
- foundEmail = true;
+ if (foundEmail < Contents.EMAIL_KEYS.length) {
+ bundle.putString(Contents.EMAIL_KEYS[foundEmail], massageContactData(data));
+ foundEmail++;
}
break;
case Contacts.KIND_POSTAL:
if (!foundPostal) {
- bundle.putString(Contacts.Intents.Insert.POSTAL, data);
+ bundle.putString(Contacts.Intents.Insert.POSTAL, massageContactData(data));
foundPostal = true;
}
break;
Intent intent = new Intent(Intents.Encode.ACTION);
intent.putExtra(Intents.Encode.TYPE, Contents.Type.CONTACT);
intent.putExtra(Intents.Encode.DATA, bundle);
+ intent.putExtra(Intents.Encode.FORMAT, Contents.Format.QR_CODE);
+
startActivity(intent);
}
}
+ private static String massageContactData(String data) {
+ // For now -- make sure we don't put newlines in shared contact data. It messes up
+ // any known encoding of contact data. Replace with space.
+ if (data.indexOf('\n') >= 0) {
+ data = data.replace("\n", " ");
+ }
+ if (data.indexOf('\r') >= 0) {
+ data = data.replace("\r", " ");
+ }
+ return data;
+ }
}