Android - 如何从PHOTO_THUMBNAIL_URI获取联系人照片

时间:2017-10-05 08:20:27

标签: android photo android-contacts

在我的Android应用程序(Android 4+)中,我想从联系人中选择一个电话号码和相应的个人资料照片。通过文档和SO问题后,如果尝试了许多建议和不同的方法。我唯一能够可靠地工作的是下面的草图。

我的问题是关于方法 getContactPhoto 。为什么有必要从列 ContactsContract.Contacts.PHOTO_THUMBNAIL_URI 中存储的字符串值中删除 " / photo" ?如果我不这样做,应用程序将崩溃(如果我没有抓住异常)。我没有看到任何文件记录" / phone" 必须被删除(只是试错),并且可以想象返回的URI不需要手动修补。它似乎在某些Android 4,5和7设备上运行正常,但我想了解为什么这是必需的。

    private void selectPhoneContact() {
        Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
        intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
        if (intent.resolveActivity(getPackageManager()) != null)
            startActivityForResult(intent, usePhone ? ACTIVITY_RESULT_PICK_PHONE_CONTACT : ACTIVITY_RESULT_PICK_EMAIL_CONTACT);
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        case ACTIVITY_RESULT_PICK_PHONE_CONTACT:
            Uri contactUri = data.getData();
            if (contactUri != null) {
                try {
                    String[] projection = new String[]{ContactsContract.Contacts._ID, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.Contacts.PHOTO_THUMBNAIL_URI};
                    Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null);
                    if (cursor != null) {
                        try {
                            if (cursor.moveToFirst()) {
                                String phoneNumber = cursor.getString(cursor.getColumnIndexOrThrow(valueColumn));
                                Bitmap profileImage = getContactPhoto(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI)));
                            }
                        }
                        finally {
                            cursor.close();
                        }
                    }
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
            break;
        }
    }

    private Bitmap getContactPhoto(String thumbnailUri) throw IOException {
        if (thumbnailUri == null)
            return null;
        if (thumbnailUri.endsWith("/photo"))
            thumbnailUri = thumbnailUri.substring(0, thumbnailUri.length() - 6); // remove "/photo"
        Uri photoUri = Uri.parse(thumbnailUri);
        InputStream inputStream = ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(), photoUri);
        if (inputStream == null) 
            return null;
        try {
            return BitmapFactory.decodeStream(inputStream);
        }
        finally {
            inputStream.close();
        }
    }

正如pskink所建议的,我根据SimpleCursorAdapter如何在ImageView中加载位图创建了一个替代方法。这基本上归结为getContactPhoto2,如下所示。这也行得通,我会改用它。

private Bitmap getContactPhoto2(String thumbnailUri) throws Exception {
    InputStream stream = null;
    try {
        stream = getContentResolver().openInputStream(Uri.parse(thumbnailUri));
        Bitmap  bm = BitmapFactory.decodeResourceStream(getResources(), null, stream, null, null);
        if (bm != null)
            Log.d("Contacts photo", String.format("Bitmap: %d x %d", bm.getWidth(), bm.getHeight()));
        return bm;
    } finally {
        if (stream != null)
            stream.close();
    }
}

0 个答案:

没有答案