OSDN Git Service

Pulled in ContactsAsyncHelper as part of unbundling. Longer term, that part of the...
authorMichael Chan <mchan@android.com>
Tue, 9 Feb 2010 21:32:22 +0000 (13:32 -0800)
committerMichael Chan <mchan@android.com>
Tue, 9 Feb 2010 21:32:22 +0000 (13:32 -0800)
Change-Id: I58555e3a1299b5cac60c56b6731cf57401dc0f1c

Android.mk
src/com/android/calendar/ContactsAsyncHelper.java [new file with mode: 0644]
src/com/android/calendar/EventInfoActivity.java

index bff72b2..73fafbe 100644 (file)
@@ -5,12 +5,18 @@ LOCAL_MODULE_TAGS := optional
 
 LOCAL_SRC_FILES := $(call all-java-files-under,src)
 
+#LOCAL_SDK_VERSION := current
+
 # TODO: Remove dependency of application on the test runner (android.test.runner)
 # library.
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
+# TODO Remove this once LaunchActivity is cleaned up
 LOCAL_STATIC_JAVA_LIBRARIES := gsf-client
 
+LOCAL_STATIC_JAVA_LIBRARIES += android-common
+LOCAL_STATIC_JAVA_LIBRARIES += calendar # Shared calendar code
+
 LOCAL_PACKAGE_NAME := Calendar
 
 include $(BUILD_PACKAGE)
diff --git a/src/com/android/calendar/ContactsAsyncHelper.java b/src/com/android/calendar/ContactsAsyncHelper.java
new file mode 100644 (file)
index 0000000..dfccd37
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.calendar;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.ContactsContract.Contacts;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+
+import java.io.InputStream;
+
+/**
+ * Helper class for async access of images.
+ */
+public class ContactsAsyncHelper extends Handler {
+
+    private static final boolean DBG = false;
+    private static final String LOG_TAG = "ContactsAsyncHelper";
+
+    /**
+     * Interface for a WorkerHandler result return.
+     */
+    public interface OnImageLoadCompleteListener {
+        /**
+         * Called when the image load is complete.
+         *
+         * @param imagePresent true if an image was found
+         */
+        public void onImageLoadComplete(int token, Object cookie, ImageView iView,
+                boolean imagePresent);
+    }
+
+    // constants
+    private static final int EVENT_LOAD_IMAGE = 1;
+    private static final int DEFAULT_TOKEN = -1;
+
+    // static objects
+    private static Handler sThreadHandler;
+    private static ContactsAsyncHelper sInstance;
+
+    static {
+        sInstance = new ContactsAsyncHelper();
+    }
+
+    private static final class WorkerArgs {
+        public Context context;
+        public ImageView view;
+        public Uri uri;
+        public int defaultResource;
+        public Object result;
+    }
+
+    /**
+     * Thread worker class that handles the task of opening the stream and loading
+     * the images.
+     */
+    private class WorkerHandler extends Handler {
+        public WorkerHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            WorkerArgs args = (WorkerArgs) msg.obj;
+
+            switch (msg.arg1) {
+                case EVENT_LOAD_IMAGE:
+                    InputStream inputStream = null;
+                    try {
+                        inputStream = Contacts.openContactPhotoInputStream(
+                                args.context.getContentResolver(), args.uri);
+                    } catch (Exception e) {
+                        Log.e(LOG_TAG, "Error opening photo input stream", e);
+                    }
+
+                    if (inputStream != null) {
+                        args.result = Drawable.createFromStream(inputStream, args.uri.toString());
+
+                        if (DBG) Log.d(LOG_TAG, "Loading image: " + msg.arg1 +
+                                " token: " + msg.what + " image URI: " + args.uri);
+                    } else {
+                        args.result = null;
+                        if (DBG) Log.d(LOG_TAG, "Problem with image: " + msg.arg1 +
+                                " token: " + msg.what + " image URI: " + args.uri +
+                                ", using default image.");
+                    }
+                    break;
+                default:
+            }
+
+            // send the reply to the enclosing class.
+            Message reply = ContactsAsyncHelper.this.obtainMessage(msg.what);
+            reply.arg1 = msg.arg1;
+            reply.obj = msg.obj;
+            reply.sendToTarget();
+        }
+    }
+
+    /**
+     * Private constructor for static class
+     */
+    private ContactsAsyncHelper() {
+        HandlerThread thread = new HandlerThread("ContactsAsyncWorker");
+        thread.start();
+        sThreadHandler = new WorkerHandler(thread.getLooper());
+    }
+
+    /**
+     * Start an image load, attach the result to the specified CallerInfo object.
+     * Note, when the query is started, we make the ImageView INVISIBLE if the
+     * placeholderImageResource value is -1.  When we're given a valid (!= -1)
+     * placeholderImageResource value, we make sure the image is visible.
+     */
+    public static final void updateImageViewWithContactPhotoAsync(Context context,
+            ImageView imageView, Uri person, int placeholderImageResource) {
+
+        // in case the source caller info is null, the URI will be null as well.
+        // just update using the placeholder image in this case.
+        if (person == null) {
+            if (DBG) Log.d(LOG_TAG, "target image is null, just display placeholder.");
+            imageView.setVisibility(View.VISIBLE);
+            imageView.setImageResource(placeholderImageResource);
+            return;
+        }
+
+        // Added additional Cookie field in the callee to handle arguments
+        // sent to the callback function.
+
+        // setup arguments
+        WorkerArgs args = new WorkerArgs();
+        args.context = context;
+        args.view = imageView;
+        args.uri = person;
+        args.defaultResource = placeholderImageResource;
+
+        // setup message arguments
+        Message msg = sThreadHandler.obtainMessage(DEFAULT_TOKEN);
+        msg.arg1 = EVENT_LOAD_IMAGE;
+        msg.obj = args;
+
+        if (DBG) Log.d(LOG_TAG, "Begin loading image: " + args.uri +
+                ", displaying default image for now.");
+
+        // set the default image first, when the query is complete, we will
+        // replace the image with the correct one.
+        if (placeholderImageResource != -1) {
+            imageView.setVisibility(View.VISIBLE);
+            imageView.setImageResource(placeholderImageResource);
+        } else {
+            imageView.setVisibility(View.INVISIBLE);
+        }
+
+        // notify the thread to begin working
+        sThreadHandler.sendMessage(msg);
+    }
+
+    /**
+     * Called when loading is done.
+     */
+    @Override
+    public void handleMessage(Message msg) {
+        WorkerArgs args = (WorkerArgs) msg.obj;
+        switch (msg.arg1) {
+            case EVENT_LOAD_IMAGE:
+                boolean imagePresent = false;
+
+                // if the image has been loaded then display it, otherwise set default.
+                // in either case, make sure the image is visible.
+                if (args.result != null) {
+                    args.view.setVisibility(View.VISIBLE);
+                    args.view.setImageDrawable((Drawable) args.result);
+                    imagePresent = true;
+                } else if (args.defaultResource != -1) {
+                    args.view.setVisibility(View.VISIBLE);
+                    args.view.setImageResource(args.defaultResource);
+                }
+                break;
+            default:
+        }
+    }
+}
index 1d18b10..c108afc 100644 (file)
@@ -38,7 +38,6 @@ import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
-import android.pim.ContactsAsyncHelper;
 import android.pim.EventRecurrence;
 import android.preference.PreferenceManager;
 import android.provider.Calendar;
@@ -50,9 +49,9 @@ import android.provider.Calendar.Reminders;
 import android.provider.ContactsContract.CommonDataKinds;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.QuickContact;
 import android.provider.ContactsContract.Intents;
 import android.provider.ContactsContract.Presence;
+import android.provider.ContactsContract.QuickContact;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
@@ -70,10 +69,10 @@ import android.view.View;
 import android.view.View.OnTouchListener;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
-import android.widget.QuickContactBadge;
 import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
+import android.widget.QuickContactBadge;
 import android.widget.Spinner;
 import android.widget.TextView;
 import android.widget.Toast;
@@ -1000,6 +999,8 @@ public class EventInfoActivity extends Activity implements View.OnClickListener,
                     if (photoId > 0 && vh.updateCounts < queryIndex) {
                         vh.updateCounts = queryIndex;
                         Uri personUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
+
+                        // TODO, modify to batch queries together
                         ContactsAsyncHelper.updateImageViewWithContactPhotoAsync(mContext, vh.badge,
                                 personUri, R.drawable.ic_contact_picture);
                     }