OSDN Git Service

Allow EditContactActivity to use a picker
authorNeel Parekh <neel@google.com>
Wed, 16 Sep 2009 22:31:22 +0000 (15:31 -0700)
committerNeel Parekh <neel@google.com>
Fri, 18 Sep 2009 17:42:59 +0000 (10:42 -0700)
Few fixes... when creating a contact, it returns to the List.  The list converts
the raw_contact into a contact and returns that (same as if you selected a contact).

Then changed AttachImage to use the new style of contacts.

Bug: 2092559

AndroidManifest.xml
res/values/strings.xml
src/com/android/contacts/AttachImage.java
src/com/android/contacts/ContactsListActivity.java
src/com/android/contacts/model/EntitySet.java
src/com/android/contacts/ui/EditContactActivity.java

index 68e66ba..6f6e3cd 100644 (file)
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
                 <data android:mimeType="vnd.android.cursor.dir/contact" />
                 <data android:mimeType="vnd.android.cursor.dir/raw_contact" />
             </intent-filter>
+
         </activity>
 
         <!-- Stub service used to keep our process alive long enough for
         <!-- Views the details of a single contact -->
         <activity android:name="ContactOptionsActivity"
             android:label="@string/contactOptionsTitle"
-        >   
+        >
             <intent-filter>
                 <action android:name="android.intent.action.EDIT" />
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
             />
-        </activity>        
+        </activity>
 
         <!-- Makes .ContactsListActivity the search target for any activity in Contacts -->
-        <meta-data android:name="android.app.default_searchable" 
+        <meta-data android:name="android.app.default_searchable"
                    android:value=".ContactsListActivity" />
 
 
index fcb6d1e..43c1c82 100644 (file)
     <!-- The group type that displays "Starred in Android" contacts -->
     <string name="starredInAndroid">Starred in Android</string>
 
+    <!-- Displayed in a spinner dialog after the user creates a contact and it's being saved to the database -->
+    <string name="savingContact">Saving contact...</string>
+
     <!-- Toast displayed when a contact is created -->
     <string name="contactCreatedToast">Contact created.</string>
 
index 8c91722..fd820e2 100644 (file)
 package com.android.contacts;
 
 import android.app.Activity;
+import android.content.ContentUris;
+import android.content.ContentValues;
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Bundle;
-import android.provider.Contacts;
-import android.provider.Contacts.People;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.widget.Toast;
 
 import java.io.ByteArrayOutputStream;
 
@@ -42,6 +46,9 @@ public class AttachImage extends Activity {
 
     }
 
+    /**
+     * Is the raw_contact uri for the contact the user selected
+     */
     Uri mContactUri;
 
     @Override
@@ -52,7 +59,7 @@ public class AttachImage extends Activity {
             mContactUri = icicle.getParcelable(CONTACT_URI_KEY);
         } else {
             Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
-            intent.setType(People.CONTENT_ITEM_TYPE);
+            intent.setType(Contacts.CONTENT_ITEM_TYPE);
             startActivityForResult(intent, REQUEST_PICK_CONTACT);
         }
     }
@@ -74,7 +81,6 @@ public class AttachImage extends Activity {
         }
 
         if (requestCode == REQUEST_PICK_CONTACT) {
-            mContactUri = result.getData();
             // A contact was picked. Launch the cropper to get face detection, the right size, etc.
             // TODO: get these values from constants somewhere
             Intent myIntent = getIntent();
@@ -89,6 +95,20 @@ public class AttachImage extends Activity {
             intent.putExtra("outputY", 96);
             intent.putExtra("return-data", true);
             startActivityForResult(intent, REQUEST_CROP_PHOTO);
+
+            // while they're cropping, convert the contact into a raw_contact
+            final long contactId = ContentUris.parseId(result.getData());
+            final long rawContactId = ContactsUtils.queryForRawContactId(getContentResolver(),
+                    contactId);
+
+            if (rawContactId == -1) {
+                Toast.makeText(this, R.string.contactSavedErrorToast, Toast.LENGTH_LONG).show();
+            }
+
+            mContactUri = Uri.withAppendedPath(
+                    ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
+                    RawContacts.Data.CONTENT_DIRECTORY);
+
         } else if (requestCode == REQUEST_CROP_PHOTO) {
             final Bundle extras = result.getExtras();
             if (extras != null) {
@@ -96,8 +116,12 @@ public class AttachImage extends Activity {
                 if (photo != null) {
                     ByteArrayOutputStream stream = new ByteArrayOutputStream();
                     photo.compress(Bitmap.CompressFormat.JPEG, 75, stream);
-                    Contacts.People.setPhotoData(getContentResolver(), mContactUri,
-                            stream.toByteArray());
+
+                    final ContentValues imageValues = new ContentValues();
+                    imageValues.put(Photo.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
+                    imageValues.put(Photo.PHOTO, stream.toByteArray());
+                    imageValues.put(RawContacts.Data.IS_SUPER_PRIMARY, 1);
+                    getContentResolver().insert(mContactUri, imageValues);
                 }
             }
             finish();
index 5e8519e..52470a3 100644 (file)
@@ -294,6 +294,8 @@ public final class ContactsListActivity extends ListActivity implements
 
     private static final int QUERY_TOKEN = 42;
 
+    static final String KEY_PICKER_MODE = "picker_mode";
+
     private ContactItemListAdapter mAdapter;
 
     int mMode = MODE_DEFAULT;
@@ -878,7 +880,6 @@ public final class ContactsListActivity extends ListActivity implements
         switch (requestCode) {
             case SUBACTIVITY_NEW_CONTACT:
                 if (resultCode == RESULT_OK) {
-                    // Contact was created, pass it back
                     returnPickerResult(null, data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME),
                             data.getData(), 0);
                 }
@@ -1040,7 +1041,6 @@ public final class ContactsListActivity extends ListActivity implements
         if (mMode == MODE_INSERT_OR_EDIT_CONTACT) {
             Intent intent;
             if (position == 0) {
-                // Insert
                 intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
             } else {
                 // Edit
@@ -1048,10 +1048,14 @@ public final class ContactsListActivity extends ListActivity implements
                 intent = new Intent(Intent.ACTION_EDIT, uri);
             }
             intent.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
-            final Bundle extras = getIntent().getExtras();
-            if (extras != null) {
-                intent.putExtras(extras);
+            Bundle extras = getIntent().getExtras();
+
+            if (extras == null) {
+                extras = new Bundle();
             }
+            intent.putExtras(extras);
+            extras.putBoolean(KEY_PICKER_MODE, (mMode & MODE_MASK_PICKER) == MODE_MASK_PICKER);
+
             startActivity(intent);
             finish();
         } else if (id != -1) {
@@ -1094,9 +1098,8 @@ public final class ContactsListActivity extends ListActivity implements
             }
         } else if ((mMode & MODE_MASK_CREATE_NEW) == MODE_MASK_CREATE_NEW
                 && position == 0) {
-            // TODO: Hook this up to new edit contact activity (bug 2092559)
-            /*Intent newContact = new Intent(Intents.Insert.ACTION, People.CONTENT_URI);
-            startActivityForResult(newContact, SUBACTIVITY_NEW_CONTACT);*/
+            Intent newContact = new Intent(Intents.Insert.ACTION, Contacts.CONTENT_URI);
+            startActivityForResult(newContact, SUBACTIVITY_NEW_CONTACT);
         } else {
             signalError();
         }
index 18afd2b..75c9dc3 100644 (file)
@@ -160,7 +160,7 @@ public class EntitySet extends ArrayList<EntityDelta> implements Parcelable {
      * existing {@link RawContacts#_ID} value. Usually used when creating
      * {@link AggregationExceptions} during an update.
      */
-    protected long findRawContactId() {
+    public long findRawContactId() {
         for (EntityDelta delta : this) {
             final Long rawContactId = delta.getValues().getAsLong(RawContacts._ID);
             if (rawContactId != null && rawContactId >= 0) {
index d9ae717..843615a 100644 (file)
 
 package com.android.contacts.ui;
 
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.ScrollingTabWidget;
-import com.android.contacts.ViewContactActivity;
-import com.android.contacts.model.ContactsSource;
-import com.android.contacts.model.Editor;
-import com.android.contacts.model.EntityDelta;
-import com.android.contacts.model.EntityModifier;
-import com.android.contacts.model.EntitySet;
-import com.android.contacts.model.HardCodedSources;
-import com.android.contacts.model.Sources;
-import com.android.contacts.model.Editor.EditorListener;
-import com.android.contacts.model.EntityDelta.ValuesDelta;
-import com.android.contacts.ui.widget.ContactEditorView;
-import com.android.contacts.util.EmptyService;
-import com.android.contacts.util.WeakAsyncTask;
-import com.android.internal.widget.ContactHeaderWidget;
-import com.google.android.collect.Lists;
-
 import android.accounts.Account;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
+import android.app.ProgressDialog;
 import android.content.ActivityNotFoundException;
 import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
@@ -74,10 +57,27 @@ import android.widget.ListAdapter;
 import android.widget.TextView;
 import android.widget.Toast;
 
+import com.google.android.collect.Lists;
+
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.ScrollingTabWidget;
+import com.android.contacts.model.ContactsSource;
+import com.android.contacts.model.Editor;
+import com.android.contacts.model.EntityDelta;
+import com.android.contacts.model.EntityModifier;
+import com.android.contacts.model.EntitySet;
+import com.android.contacts.model.HardCodedSources;
+import com.android.contacts.model.Sources;
+import com.android.contacts.model.Editor.EditorListener;
+import com.android.contacts.model.EntityDelta.ValuesDelta;
+import com.android.contacts.ui.widget.ContactEditorView;
+import com.android.contacts.util.EmptyService;
+import com.android.contacts.util.WeakAsyncTask;
+import com.android.internal.widget.ContactHeaderWidget;
+
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 
 /**
  * Activity for editing or inserting a contact.
@@ -493,19 +493,6 @@ public final class EditContactActivity extends Activity implements View.OnClickL
         return false;
     }
 
-
-
-
-
-
-
-
-
-
-
-
-
-
     /**
      * Background task for persisting edited contact data, using the changes
      * defined by a set of {@link EntityDelta}. This task starts
@@ -520,6 +507,10 @@ public final class EditContactActivity extends Activity implements View.OnClickL
         private static final int RESULT_SUCCESS = 1;
         private static final int RESULT_FAILURE = 2;
 
+        private long mSavedId;
+
+        private WeakReference<ProgressDialog> progress;
+
         public PersistTask(EditContactActivity target) {
             super(target);
         }
@@ -527,6 +518,9 @@ public final class EditContactActivity extends Activity implements View.OnClickL
         /** {@inheritDoc} */
         @Override
         protected void onPreExecute(EditContactActivity target) {
+            this.progress = new WeakReference<ProgressDialog>(ProgressDialog.show(target, null,
+                    target.getText(R.string.savingContact)));
+
             // Before starting this task, start an empty service to protect our
             // process from being reclaimed by the system.
             final Context context = target;
@@ -552,7 +546,21 @@ public final class EditContactActivity extends Activity implements View.OnClickL
                 try {
                     // Build operations and try applying
                     final ArrayList<ContentProviderOperation> diff = state.buildDiff();
-                    resolver.applyBatch(ContactsContract.AUTHORITY, diff);
+                    ContentProviderResult[] results;
+                    if (!diff.isEmpty()) {
+                         results = resolver.applyBatch(ContactsContract.AUTHORITY, diff);
+                         Intent intent = new Intent();
+                         final long rawContactId = getRawContactId(state, diff, results);
+                         final Uri rawContactUri = ContentUris.withAppendedId(
+                                 RawContacts.CONTENT_URI, rawContactId);
+
+                         // convert the raw contact URI to a contact URI
+                         final Uri contactLookupUri = RawContacts.getContactLookupUri(resolver,
+                                 rawContactUri);
+                         intent.setData(contactLookupUri);
+                         target.setResult(RESULT_OK, intent);
+                         target.finish();
+                    }
                     result = (diff.size() > 0) ? RESULT_SUCCESS : RESULT_UNCHANGED;
                     break;
 
@@ -574,6 +582,27 @@ public final class EditContactActivity extends Activity implements View.OnClickL
             return result;
         }
 
+        private long getRawContactId(EntitySet state,
+                final ArrayList<ContentProviderOperation> diff,
+                final ContentProviderResult[] results) {
+            long rawContactId = state.findRawContactId();
+            if (rawContactId != -1) {
+                return rawContactId;
+            }
+
+            // we gotta do some searching for the id
+            final int diffSize = diff.size();
+            for (int i = 0; i < diffSize; i++) {
+                ContentProviderOperation operation = diff.get(i);
+                if (operation.getType() == ContentProviderOperation.TYPE_INSERT
+                        && operation.getUri().getEncodedPath().contains(
+                                RawContacts.CONTENT_URI.getEncodedPath())) {
+                    return ContentUris.parseId(results[i].uri);
+                }
+            }
+            return -1;
+        }
+
         /** {@inheritDoc} */
         @Override
         protected void onPostExecute(EditContactActivity target, Integer result) {
@@ -585,48 +614,23 @@ public final class EditContactActivity extends Activity implements View.OnClickL
                 Toast.makeText(context, R.string.contactSavedErrorToast, Toast.LENGTH_LONG).show();
             }
 
+            progress.get().dismiss();
+            target.finish();
             // Stop the service that was protecting us
             context.stopService(new Intent(context, EmptyService.class));
         }
     }
 
     /**
-     * Timeout for a {@link PersistTask} running on a background thread. This is
-     * just shorter than the ANR timeout, so that we hold off user interaction
-     * as long as possible.
-     */
-    private static final long TIMEOUT_PERSIST = 4000;
-
-    /**
      * Saves or creates the contact based on the mode, and if successful
      * finishes the activity.
      */
     private boolean doSaveAction() {
         if (!hasValidState()) return false;
 
-        // Pass back last-selected contact
-        final Long rawContactId = this.getSelectedRawContactId();
-        if (rawContactId != null) {
-            final Intent intent = new Intent();
-            intent.putExtra(ViewContactActivity.RAW_CONTACT_ID_EXTRA, (long)rawContactId);
-            setResult(RESULT_OK, intent);
-        }
-
-        try {
-            final PersistTask task = new PersistTask(this);
-            task.execute(mState);
-            task.get(TIMEOUT_PERSIST, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            // Ignore when someone cancels the operation
-        } catch (TimeoutException e) {
-            // Ignore when task is taking too long
-        } catch (ExecutionException e) {
-            // Important exceptions are handled on remote thread
-        }
+        final PersistTask task = new PersistTask(this);
+        task.execute(mState);
 
-        // Persisting finished, or we timed out waiting on it. Either way,
-        // finish this activity, the background task will keep running.
-        this.finish();
         return true;
     }