7 package com.google.appinventor.components.runtime;
9 import java.util.ArrayList;
10 import java.util.Arrays;
11 import java.util.List;
13 import android.app.Activity;
14 import android.content.Intent;
15 import android.database.Cursor;
16 import android.net.Uri;
17 import android.provider.Contacts;
18 import android.util.Log;
19 import android.Manifest;
57 @DesignerComponent(version = YaVersion.CONTACTPICKER_COMPONENT_VERSION,
58 description =
"A button that, when clicked on, displays a list of " +
59 "the contacts to choose among. After the user has made a " +
60 "selection, the following properties will be set to information about " +
61 "the chosen contact: <ul>\n" +
62 "<li> <code>ContactName</code>: the contact's name </li>\n " +
63 "<li> <code>EmailAddress</code>: the contact's primary email address </li>\n " +
64 "<li> <code>ContactUri</code>: the contact's URI on the device </li>\n"+
65 "<li> <code>EmailAddressList</code>: a list of the contact's email addresses </li>\n " +
66 "<li> <code>PhoneNumber</code>: the contact's primary phone number (on Later Android Verisons)</li>\n " +
67 "<li> <code>PhoneNumberList</code>: a list of the contact's phone numbers (on Later Android Versions)</li>\n " +
68 "<li> <code>Picture</code>: the name of the file containing the contact's " +
69 "image, which can be used as a <code>Picture</code> property value for " +
70 "the <code>Image</code> or <code>ImageSprite</code> component.</li></ul>\n" +
71 "</p><p>Other properties affect the appearance of the button " +
72 "(<code>TextAlignment</code>, <code>BackgroundColor</code>, etc.) and " +
73 "whether it can be clicked on (<code>Enabled</code>).\n</p>" +
74 "<p>The ContactPicker component might not work on all phones. For " +
75 "example, on Android systems before system 3.0, it cannot pick phone " +
76 "numbers, and the list of email addresses will contain only one email.",
77 category = ComponentCategory.SOCIAL)
79 @UsesPermissions(permissionNames =
"android.permission.READ_CONTACTS")
82 private static String[] CONTACT_PROJECTION;
83 private static String[] DATA_PROJECTION;
84 private static final String[] PROJECTION = {
85 Contacts.PeopleColumns.NAME,
86 Contacts.People.PRIMARY_EMAIL_ID,
89 private static final int NAME_INDEX = 0;
90 private static final int EMAIL_INDEX = 1;
91 private static final int PHONE_INDEX = 2;
94 private final Uri intentUri;
105 private boolean havePermission =
false;
113 this(container, Contacts.People.CONTENT_URI);
118 activityContext = container.
$context();
125 this.intentUri = intentUri;
131 if (!havePermission) {
133 .askPermission(Manifest.permission.READ_CONTACTS,
136 public void HandlePermissionResponse(String permission,
boolean granted) {
141 container.$form().dispatchPermissionDeniedEvent(
ContactPicker.this,
142 "Click", Manifest.permission.READ_CONTACTS);
157 public String Picture() {
158 return ensureNotNull(contactPictureUri);
166 public String ContactName() {
167 return ensureNotNull(contactName);
176 public String EmailAddress() {
185 return ensureNotNull(emailAddress);
191 @
SimpleProperty(description =
"URI that specifies the location of the contact on the device.",
193 public String ContactUri() {
194 return ensureNotNull(contactUri);
202 public List EmailAddressList() {
203 return ensureNotNull(emailAddressList);
212 public String PhoneNumber() {
213 return ensureNotNull(phoneNumber);
221 public List PhoneNumberList() {
222 return ensureNotNull(phoneNumberList);
229 public
void ViewContact(String uri) {
230 if(contactUri !=
null){
231 Intent intent =
new Intent(Intent.ACTION_VIEW,Uri.parse(uri));
232 if (intent.resolveActivity(
this.activityContext.getPackageManager()) !=
null) {
233 this.activityContext.startActivity(intent);
240 return new Intent(Intent.ACTION_PICK, intentUri);
253 if (requestCode == this.requestCode && resultCode == Activity.RESULT_OK) {
254 Log.i(
"ContactPicker",
"received intent is " + data);
255 Uri receivedContactUri = data.getData();
258 String desiredContactUri =
"";
260 desiredContactUri =
"//com.android.contacts/contact";
262 desiredContactUri =
"//contacts/people";
265 if (checkContactUri(receivedContactUri, desiredContactUri)) {
266 Cursor contactCursor =
null;
267 Cursor dataCursor =
null;
271 contactCursor = activityContext.getContentResolver().query(receivedContactUri,
272 CONTACT_PROJECTION,
null,
null,
null);
274 String
id = postHoneycombGetContactNameAndPicture(contactCursor);
278 postHoneycombGetContactEmailAndPhone(dataCursor);
281 contactUri = receivedContactUri.toString();
283 contactCursor = activityContext.getContentResolver().query(receivedContactUri,
284 PROJECTION,
null,
null,
null);
285 preHoneycombGetContactInfo(contactCursor, receivedContactUri);
287 Log.i(
"ContactPicker",
288 "Contact name = " + contactName +
", email address = " + emailAddress +
",contact Uri = " + contactUri +
289 ", phone number = " + phoneNumber +
", contactPhotoUri = " + contactPictureUri);
290 }
catch (Exception e) {
294 Log.i(
"ContactPicker",
"checkContactUri failed: D");
297 if (contactCursor !=
null) {
298 contactCursor.close();
300 if (dataCursor !=
null) {
313 if (contactCursor.moveToFirst()) {
314 contactName = guardCursorGetString(contactCursor, NAME_INDEX);
315 String emailId = guardCursorGetString(contactCursor, EMAIL_INDEX);
316 emailAddress = getEmailAddress(emailId);
317 contactUri = theContactUri.toString();
318 contactPictureUri = theContactUri.toString();
319 emailAddressList = emailAddress.equals(
"") ?
new ArrayList() : Arrays.asList(emailAddress);
329 if (contactCursor.moveToFirst()) {
334 id = guardCursorGetString(contactCursor, ID_INDEX);
335 contactName = guardCursorGetString(contactCursor, NAME_INDEX);
336 contactPictureUri = guardCursorGetString(contactCursor, THUMBNAIL_INDEX);
338 Log.i(
"ContactPicker",
"photo_uri=" + guardCursorGetString(contactCursor, PHOTO_INDEX));
350 List<String> phoneListToStore =
new ArrayList<String>();
351 List<String> emailListToStore =
new ArrayList<String>();
353 if (dataCursor.moveToFirst()) {
361 while (!dataCursor.isAfterLast()) {
362 String type = guardCursorGetString(dataCursor, MIME_INDEX);
363 if (type.contains(phoneType)) {
364 phoneListToStore.add(guardCursorGetString(dataCursor, PHONE_INDEX));
365 }
else if (type.contains(emailType)) {
366 emailListToStore.add(guardCursorGetString(dataCursor, EMAIL_INDEX));
368 Log.i(
"ContactPicker",
"Type mismatch: " + type +
369 " not " + phoneType +
372 dataCursor.moveToNext();
376 if (!phoneListToStore.isEmpty()) {
377 phoneNumber = phoneListToStore.get(0);
379 if (!emailListToStore.isEmpty()) {
380 emailAddress = emailListToStore.get(0);
382 phoneNumberList = phoneListToStore;
383 emailAddressList = emailListToStore;
402 Log.i(
"ContactPicker",
"contactUri is " + suspectUri);
403 if (suspectUri ==
null || (!(
"content".equals(suspectUri.getScheme())))) {
404 Log.i(
"ContactPicker",
"checkContactUri failed: A");
405 puntContactSelection(
409 String UriSpecific = suspectUri.getSchemeSpecificPart();
410 if (!UriSpecific.startsWith(requiredPattern)) {
411 Log.i(
"ContactPicker",
"checkContactUri failed: C");
412 Log.i(
"ContactPicker", suspectUri.getPath());
425 contactPictureUri =
"";
426 container.$form().dispatchErrorOccurredEvent(
this,
"", errorNumber);
435 id = Integer.parseInt(emailId);
436 }
catch (NumberFormatException e) {
441 String where =
"contact_methods._id = " + id;
442 String[] projection = {
443 Contacts.ContactMethods.DATA
445 Cursor cursor = activityContext.getContentResolver().query(
446 Contacts.ContactMethods.CONTENT_EMAIL_URI,
447 projection, where,
null,
null);
449 if (cursor.moveToFirst()) {
450 data = guardCursorGetString(cursor, 0);
457 return ensureNotNull(data);
473 result = cursor.getString(index);
474 }
catch (Exception e) {
480 return ensureNotNull(result);
493 return new ArrayList();