Android 在自定义列表视图中显示带星号的联系人和图片

Android 在自定义列表视图中显示带星号的联系人和图片,android,contacts,photos,Android,Contacts,Photos,我正在尝试显示一个仅带有星号联系人的列表视图,带有自定义列表视图的图标和名称。到目前为止,我已经设法在没有照片的情况下正确显示了它们。当我尝试包含照片时,我会遇到一些错误(因为我尝试了很多不同的方法,在这里可以找到)。我的最后一次尝试是由安卓开发人员实施的“*显示Quick Contact Badg*e”课程的代码,以下是相关代码: Uri queryUri = ContactsContract.Contacts.CONTENT_URI; String[] projection = n

我正在尝试显示一个仅带有星号联系人的列表视图,带有自定义列表视图的图标和名称。到目前为止,我已经设法在没有照片的情况下正确显示了它们。当我尝试包含照片时,我会遇到一些错误(因为我尝试了很多不同的方法,在这里可以找到)。我的最后一次尝试是由安卓开发人员实施的“*显示Quick Contact Badg*e”课程的代码,以下是相关代码:

Uri queryUri = ContactsContract.Contacts.CONTENT_URI;

    String[] projection = new String[] {
            ContactsContract.Contacts._ID,
            ContactsContract.Contacts.DISPLAY_NAME,
            ContactsContract.Contacts.STARRED,
            ContactsContract.Contacts.LOOKUP_KEY,
            ContactsContract.Contacts.PHOTO_THUMBNAIL_URI};
    String selection =ContactsContract.Contacts.STARRED + "='1'";

    Cursor cursor = managedQuery(queryUri, projection, selection,null,null);

    int mIdColumn;
    int mLookupKeyColumn;
    Uri mContactUri;

    mIdColumn = cursor.getColumnIndex(ContactsContract.Contacts._ID);
    // Gets the LOOKUP_KEY index
    mLookupKeyColumn = cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY);

    mContactUri =
            ContactsContract.Contacts.getLookupUri(
                    cursor.getLong(mIdColumn),
                    cursor.getString(mLookupKeyColumn)
            );


    favIcon.assignContactUri(mContactUri);

    // The column in which to find the thumbnail ID
    int mThumbnailColumn;
/*
 * The thumbnail URI, expressed as a String.
 * Contacts Provider stores URIs as String values.
 */
    String mThumbnailUri;

/*
 * Gets the photo thumbnail column index if
 * platform version >= Honeycomb
 */
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        mThumbnailColumn =
                cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI);
        // Otherwise, sets the thumbnail column to the _ID column
    } else {
        mThumbnailColumn = mIdColumn;
    }
/*
 * Assuming the current Cursor position is the contact you want,
 * gets the thumbnail ID
 */
    mThumbnailUri = cursor.getString(mThumbnailColumn);

    Bitmap mThumbnail =
            loadContactPhotoThumbnail(mThumbnailUri);
    favIcon.setImageBitmap(mThumbnail);

    String[] from = {ContactsContract.Contacts.DISPLAY_NAME};
    int to[] = new int[]{
            R.id.ivDefContact,
            R.id.tvContactName
    };

    ListAdapter adapter = new SimpleCursorAdapter(
            this,
            R.layout.favs_list_item,
            cursor,
            from,
            to,
            CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);


    final ListView listStarred = (ListView) findViewById(R.id.lvFavs);

    listStarred.setAdapter(adapter);

}
我在上述代码中遇到的错误是:

Android.database.CursorIndexOutOfBoundsException:请求索引-1, 9号的 (9是我的星号联系人的号码)并将我指向第85行,即:

如果我对R.id.ivDefContact进行注释,请将该活动与listview对齐,并正确显示联系人名称。因此,问题在于照片实现。我读了一些相关的文章,但我不知道它是如何工作的

编辑: Logcat错误:

java.lang.RuntimeException:无法启动活动组件信息 android.database.CursorIndexOutOfBoundsException:请求索引-1,大小为6 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2307) 位于android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2357) 在android.app.ActivityThread.access上$600(ActivityThread.java:153) 在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247) 位于android.os.Handler.dispatchMessage(Handler.java:99) 位于android.os.Looper.loop(Looper.java:137) 位于android.app.ActivityThread.main(ActivityThread.java:5226) 位于java.lang.reflect.Method.Invokenactive(本机方法) 位于java.lang.reflect.Method.invoke(Method.java:511) 在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)上 位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562) 在dalvik.system.NativeStart.main(本机方法) 原因:android.database.CursorIndexOutOfBoundsException:请求索引-1,大小为6 在android.database.AbstractCursor.checkPosition(AbstractCursor.java:424)中 位于android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136) 位于android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:74) 位于android.database.CursorWrapper.getLong(CursorWrapper.java:106) 位于com.example.DialerActivity.onCreate(DialerActivity.java:85) 位于android.app.Activity.performCreate(Activity.java:5104) 位于android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2261)上 ... 还有11个

问题就在这里

String[] from = {ContactsContract.Contacts.DISPLAY_NAME};
    int to[] = new int[]{
            R.id.ivDefContact,
            R.id.tvContactName
    }; 
“从”和“到”中的项目数必须相同

因此,您可以将中的重写为

String[] from = {ContactsContract.Contacts.PHOTO_THUMBNAIL_URI, ContactsContract.Contacts.DISPLAY_NAME};

我已成功显示具有上述更改的照片:

Uri queryUri = ContactsContract.Contacts.CONTENT_URI;

    String[] projection = new String[] {
            ContactsContract.Contacts._ID,
            ContactsContract.Contacts.LOOKUP_KEY,
            ContactsContract.Contacts.PHOTO_THUMBNAIL_URI,
            ContactsContract.Contacts.DISPLAY_NAME,
            ContactsContract.Contacts.STARRED};

    String selection =ContactsContract.Contacts.STARRED + "='1'";

    Cursor cursor = managedQuery(queryUri, projection, selection,null,null);

    long id= cursor.getColumnIndex(ContactsContract.Contacts._ID);

    Bitmap bitmap = loadContactPhoto(getContentResolver(), id);
    if(bitmap!=null){
    favIcon.setImageBitmap(bitmap);
    }
    else{

    }

    String[] from = {ContactsContract.Contacts.PHOTO_THUMBNAIL_URI, ContactsContract.Contacts.DISPLAY_NAME};
    int to[] = new int[]{
            R.id.ivDefContact,
            R.id.tvContactName
    };

    ListAdapter adapter = new SimpleCursorAdapter(
            this,
            R.layout.favs_list_item,
            cursor,
            from,
            to,
            CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);


    final ListView listStarred = (ListView) findViewById(R.id.lvFavs);

    listStarred.setAdapter(adapter);

    public static Bitmap loadContactPhoto(ContentResolver cr, long  id) {
    Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
    InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
    if (input == null) {

        return null;
    }
    return BitmapFactory.decodeStream(input);
}

现在,对于有照片的联系人,照片显示正确。

我也会收到同样的错误。“android.database.CursorIndexOutOfBoundsException:请求索引-1,大小为6”。然后再次指向同一行代码嘿,你应该使用另一个适配器。。。。。我正在搜索你的bug,得到了许多与游标适配器相关的iSUUE。。
Uri queryUri = ContactsContract.Contacts.CONTENT_URI;

    String[] projection = new String[] {
            ContactsContract.Contacts._ID,
            ContactsContract.Contacts.LOOKUP_KEY,
            ContactsContract.Contacts.PHOTO_THUMBNAIL_URI,
            ContactsContract.Contacts.DISPLAY_NAME,
            ContactsContract.Contacts.STARRED};

    String selection =ContactsContract.Contacts.STARRED + "='1'";

    Cursor cursor = managedQuery(queryUri, projection, selection,null,null);

    long id= cursor.getColumnIndex(ContactsContract.Contacts._ID);

    Bitmap bitmap = loadContactPhoto(getContentResolver(), id);
    if(bitmap!=null){
    favIcon.setImageBitmap(bitmap);
    }
    else{

    }

    String[] from = {ContactsContract.Contacts.PHOTO_THUMBNAIL_URI, ContactsContract.Contacts.DISPLAY_NAME};
    int to[] = new int[]{
            R.id.ivDefContact,
            R.id.tvContactName
    };

    ListAdapter adapter = new SimpleCursorAdapter(
            this,
            R.layout.favs_list_item,
            cursor,
            from,
            to,
            CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);


    final ListView listStarred = (ListView) findViewById(R.id.lvFavs);

    listStarred.setAdapter(adapter);

    public static Bitmap loadContactPhoto(ContentResolver cr, long  id) {
    Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
    InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
    if (input == null) {

        return null;
    }
    return BitmapFactory.decodeStream(input);
}