Как загрузить URI с префиксом «content: //» с помощью Glide Android?

Я пытаюсь загрузить фотографию контакта с URI «content: //com.android.contacts/contacts/295» с помощью Glide.

Когда я использую

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) 

Очевидно, Глид пытается получить изображение с неправильного места.

Я был бы признателен, если бы кто-нибудь сказал мне, как загрузить фотографию с помощью URI «content: //».

Вам необходимо создать пользовательский загрузчик, который использует 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);