How to load URI with the prefix "content: //" using Glide Android?

I am trying to upload a contact photo with the URI "content: //com.android.contacts/contacts/295" using Glide.

When i use

Glide.with(context).load(Uri.parse(contactPhoto).into(imageview) 

Glide gives me a 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) 

Obviously, Glide is trying to get the image from the wrong place.

I would appreciate if someone would tell me how to upload a photo using URI content: //.

+5
source share
4 answers

You need to create a custom loader that uses ContentResolver. For example, in Picasso, this works because it is already a user request handler that uses ContentResolver.

I created one custom Glide loader for contacts for my internal use , which you can take as a link.

+2
source

Glide doesn't seem to process Uri content photos automatically.

So, I solved the problem using the RxJava approach.

Here is a method that emits a bitmap (pay attention to the scheduler, as it is important to keep up with scroll performance)

 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()); } 

And here is the client code that uses this method (pay attention to unsubscribing, since this is important when disposing).

  if (holder.bitmapSubscription != null) { holder.bitmapSubscription.unsubscribe(); } holder.bitmapSubscription = _getConvertInputStreamToBitmapObservable(context.getContentResolver(), contactUri) .subscribe(holder.userImg::setImageBitmap); 
+1
source

For this you need to use 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); } 

Try it. That should work.

0
source
  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); 
-1
source

All Articles