![](/img/trans.png)
[英]How to get contact URI from user phone and load using glide in android
[英]How to load a URI with “content://” prefix using Glide Android?
我正在嘗試使用 Glide 加載帶有 URI“content://com.android.contacts/contacts/295”的聯系人照片。
當我使用
Glide.with(context).load(Uri.parse(contactPhoto).into(imageview)
Glide 給了我一個 FileNotFoundException
java.io.FileNotFoundException: File does not exist; URI: content://com.android.contacts/contacts/264, calling user: android.uid.shared:10006, calling package is one of: [com.android.providers.contacts, com.android.contacts, com.android.providers.userdictionary]
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:146)
at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:689)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1080)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:921)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:848)
at com.bumptech.glide.load.data.FileDescriptorLocalUriFetcher.loadResource(FileDescriptorLocalUriFetcher.java:21)
at com.bumptech.glide.load.data.FileDescriptorLocalUriFetcher.loadResource(FileDescriptorLocalUriFetcher.java:14)
at com.bumptech.glide.load.data.LocalUriFetcher.loadData(LocalUriFetcher.java:44)
at com.bumptech.glide.load.model.ImageVideoModelLoader$ImageVideoFetcher.loadData(ImageVideoModelLoader.java:83)
at com.bumptech.glide.load.model.ImageVideoModelLoader$ImageVideoFetcher.loadData(ImageVideoModelLoader.java:53)
at com.bumptech.glide.load.engine.DecodeJob.decodeSource(DecodeJob.java:170)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromSource(DecodeJob.java:128)
at com.bumptech.glide.load.engine.EngineRunnable.decodeFromSource(EngineRunnable.java:122)
at com.bumptech.glide.load.engine.EngineRunnable.decode(EngineRunnable.java:101)
at com.bumptech.glide.load.engine.EngineRunnable.run(EngineRunnable.java:58)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
at com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor$DefaultThreadFactory$1.run(FifoPriorityThreadPoolExecutor.java:52)
顯然 Glide 試圖從錯誤的地方獲取圖像。
如果有人指出我如何使用“content://” URI 加載照片,我將不勝感激。
您需要創建一個使用 ContentResolver 的自定義加載器。 例如,在 Picasso 中,這是有效的,因為已經有一個使用 ContentResolver 的自定義請求處理程序。
我 為我內部使用的聯系人創建了一個自定義Glide 加載器,您可以將其作為參考。
似乎 Glide 不會自動處理內容照片 Uri。
所以我使用 RxJava 方法解決了我的問題。
這是一個發出位圖的方法(請注意調度程序,因為不延遲滾動性能很重要)
private Observable<Bitmap> _getConvertInputStreamToBitmapObservable(ContentResolver cr,
Uri contactUri) {
return Observable.create(new Observable.OnSubscribe<Bitmap>() {
@Override
public void call(Subscriber<? super Bitmap> subscriber) {
InputStream inputStream =
ContactsContract.Contacts.openContactPhotoInputStream(cr, contactUri);
if (inputStream != null) {
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
subscriber.onNext(bitmap);
}
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
}
這是使用該方法的客戶端代碼(請注意取消訂閱,因為它在回收中很重要)。
if (holder.bitmapSubscription != null) {
holder.bitmapSubscription.unsubscribe();
}
holder.bitmapSubscription = _getConvertInputStreamToBitmapObservable(context.getContentResolver(),
contactUri)
.subscribe(holder.userImg::setImageBitmap);
為此,您需要使用ContentResolver
。
ContentResolver contextResolver = context.getContentResolver();
Uri uri = Uri.parse("content://com.android.contacts/contacts/295");
Bitmap thumbnail = null;
Cursor cursor = contentResolver.query(uri, new String[] {ContactsContract.CommonDataKinds.Photo.PHOTO}, null, null, null);
try {
if (cursor.moveToFirst()) {
final byte[] thumbnailBytes = cursor.getBlob(0);
if (thumbnailBytes != null) {
thumbnail = BitmapFactory.decodeByteArray(thumbnailBytes, 0, thumbnailBytes.length);
}
}
}
finally {
cursor.close();
}
if (thumbnail != null) {
imageView.setImageBitmap(thumbnail);
}
嘗試這個。 這應該有效。
Uri uri =
ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, new
Long(contactsPojo.getId()));
final Uri displayPhotoUri = Uri.withAppendedPath(uri,
ContactsContract.Contacts.Photo.DISPLAY_PHOTO);
Glide.with(context)
.load(displayPhotoUri)
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.fallback(R.mipmap.ic_launcher)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(holder.image);
我正在使用此代碼然后成功工作
Glide.with(context)
.load(uri)
.addListener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
Log.i(TAG, "onLoadFailed: ");
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
Log.i(TAG, "onResourceReady: ");
return false;
}
})
.into(holder.imgProfile);
最快和最簡單的方法是首先找出CONTACT_ID
。 然后將此CONTACT_ID
與PHOTO_URI
匹配。
//first create a cursor
val photoCursor = contentResolver.query(
ContactsContract.Contacts.CONTENT_URI,
photoProjection,
ContactsContract.Contacts._ID + "=?",
arrayOf(contactId),
null
)
//where photoProjection is like so
val photoProjection: Array<String> = arrayOf(
ContactsContract.Contacts.Photo.PHOTO_URI,
ContactsContract.Contacts._ID
)
//now grab the PHOTO_URI, this will only exist if there is a photo
val photo = if (photoCursor?.moveToFirst() == true) {
photoCursor.getString(photoCursor.getColumnIndex(ContactsContract.Contacts.PHOTO_URI))
} else {
null
}
//In Glide now you can load the URI directly
Glide.with(this)
.load(uri)
.apply(imageTransform)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.into(image)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.