android-multipicker-library icon indicating copy to clipboard operation
android-multipicker-library copied to clipboard

Get Intent

Open CristianMG opened this issue 8 years ago • 8 comments

Hi, I’ve been trying to use this library alongside with RxPermission and RxActivityResult. For that you need to obtain the Intent to run and that’s currently not possible, you can only launch it directly.

For now what I’ve done is to create my own camera and gallery intent and then attach the bundle to the imagepicker.

What could be the best approach to obtain the intent from the imagepicker?

Thank you

new RxPermissions(getActivity()).request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                            .flatMap(new Function<Boolean, ObservableSource<Result<VendaStepPhotosFragment>>>() {
                                @Override
                                public ObservableSource<Result<VendaStepPhotosFragment>> apply(Boolean aBoolean) throws Exception {
                                    if (aBoolean) {
                                        Intent intent = new Intent("android.intent.action.GET_CONTENT");
                                        intent.setType("image/*");
                                        return RxActivityResult.on(VendaStepPhotosFragment.this).startIntentSender(PendingIntent.getActivity(getActivity(), Picker.PICK_IMAGE_CAMERA, intent, 0).getIntentSender(), new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));
                                    } else {
                                        return Observable.error(new PermissionException());
                                    }
                                }
                            })
                            .subscribe(new Consumer<Result<VendaStepPhotosFragment>>() {
                                @Override
                                public void accept(Result<VendaStepPhotosFragment> result) throws Exception {
                                    if (result.resultCode() != Activity.RESULT_OK) {
                                        Toast.makeText(getContext(), "Cancel!", Toast.LENGTH_SHORT).show();
                                    } else {
                                        imagePicker.submit(result.data());
                                    }
                                }
                            });

CristianMG avatar Feb 17 '17 13:02 CristianMG

I can write a helper method to provide you with the proper intents when you need. Would that work?

coomar2841 avatar Feb 17 '17 18:02 coomar2841

Yes, I need the intent with parameters.

Thank you.

CristianMG avatar Feb 20 '17 08:02 CristianMG

Hi! I got the crash:

java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{3e20b1a7 21902:com.nostrostudio.carbraxx/u0a144} (pid=21902, uid=10144) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS
                                                       at android.os.Parcel.readException(Parcel.java:1546)
                                                       at android.os.Parcel.readException(Parcel.java:1499)
                                                       at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:4018)
                                                       at android.app.ActivityThread.acquireProvider(ActivityThread.java:6100)
                                                       at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:3118)
                                                       at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1495)
                                                       at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1115)
                                                       at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:970)
                                                       at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:827)
                                                       at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:782)
                                                       at com.kbeanie.multipicker.core.threads.FileProcessorThread.getFromContentProvider(FileProcessorThread.java:249)
                                                       at com.kbeanie.multipicker.core.threads.FileProcessorThread.processFile(FileProcessorThread.java:174)
                                                       at com.kbeanie.multipicker.core.threads.FileProcessorThread.processFiles(FileProcessorThread.java:105)
                                                       at com.kbeanie.multipicker.core.threads.FileProcessorThread.run(FileProcessorThread.java:79)
                                                       at com.kbeanie.multipicker.core.threads.ImageProcessorThread.run(ImageProcessorThread.java:41)

I have implemented an internal class inheriting from ImagePickerImpl so that I can get the Intent temporarily. I build the Intent similarly pickLocalImage method in ImagePickerImpl class, so I don't understand the bug...

Thanks!

public class GetGalleryImageCase extends UseCase<List<ChosenImage>> {

    private Fragment fragment;
    private final MyImagePickerImpl imagePicker;

    public GetGalleryImageCase(Context context, Fragment fragment) {
        super(context);
        this.fragment = fragment;
        imagePicker = new MyImagePickerImpl(fragment);
    }

    @Override
    public Observable<List<ChosenImage>> getObservable() {
        return new RxPermissions(fragment.getActivity()).request(Manifest.permission.MANAGE_DOCUMENTS, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
                .flatMap(new Function<Boolean, ObservableSource<Result<Fragment>>>() {
                    @Override
                    public ObservableSource<Result<Fragment>> apply(Boolean aBoolean) throws Exception {
                        if (aBoolean) {
                            return RxActivityResult.on(fragment).startIntent(imagePicker.getIntent());
                        } else {
                            return Observable.error(new PermissionException());
                        }
                    }
                })
                .flatMap(new Function<Result<Fragment>, ObservableSource<List<ChosenImage>>>() {
                    @Override
                    public ObservableSource<List<ChosenImage>> apply(final Result<Fragment> result) throws Exception {
                        if (result.resultCode() != Activity.RESULT_OK) {
                            return Observable.error(new CaptureImageCanceledException());
                        } else {
                            return Observable.create(new ObservableOnSubscribe<List<ChosenImage>>() {
                                @Override
                                public void subscribe(final ObservableEmitter<List<ChosenImage>> e) throws Exception {
                                    imagePicker.setImagePickerCallback(new ImagePickerCallback() {
                                        @Override
                                        public void onImagesChosen(List<ChosenImage> list) {
                                            e.onNext(list);
                                            e.onComplete();
                                        }
                                        @Override
                                        public void onError(String s) {
                                            e.onError(new CaptureImageErrorException(s));
                                        }
                                    });
                                    imagePicker.submit(result.data());
                                }
                            });
                        }
                    }
                });
    }

    private static class MyImagePickerImpl extends ImagePickerImpl {

        public MyImagePickerImpl(Fragment fragment) {
            super(fragment, Picker.PICK_IMAGE_DEVICE);
        }

        protected Intent getIntent() throws PickerException {
            Intent intent = new Intent("android.intent.action.GET_CONTENT");
            intent.setType("image/*");
            if(this.extras != null) {
                intent.putExtras(this.extras);
            }

            if(this.allowMultiple && Build.VERSION.SDK_INT >= 18) {
                intent.putExtra("android.intent.extra.ALLOW_MULTIPLE", true);
            }

            return intent;
        }
    }
}

CristianMG avatar Feb 20 '17 17:02 CristianMG

From where you are choosing the image? Also, can you provide a sample app for me to debug the issue?

coomar2841 avatar Feb 22 '17 09:02 coomar2841

Hi! Here you have a sample project to debug the issue: https://github.com/CristianMG/MultipickerRxJavaSample

Thanks!

CristianMG avatar Feb 22 '17 10:02 CristianMG

No clue yet.

coomar2841 avatar Feb 23 '17 06:02 coomar2841

if treatment URI with this line the function is correctly, I think that the bug comes from RxResult library because URI don't have permissions. fragment.getContext().grantUriPermission(fragment.getActivity().getPackageName(), result.data().getData(), Intent.FLAG_GRANT_READ_URI_PERMISSION);

CristianMG avatar Feb 24 '17 11:02 CristianMG

Hi, I also got the same crash, while pick image from gallery in android 5.1.1

Fatal Exception: java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.docs.storagebackend.StorageBackendContentProvider from ProcessRecord{57a3f39 22020:com.optimumbrewlab.cpbackgroundchanger/u0a142} (pid=22020, uid=10142) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS
       at android.os.Parcel.readException(Parcel.java:1546)
       at android.os.Parcel.readException(Parcel.java:1499)
       at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:3449)
       at android.app.ActivityThread.acquireProvider(ActivityThread.java:4778)
       at android.app.ContextImpl$ApplicationContentResolver.acquireProvider(ContextImpl.java:2495)
       at android.content.ContentResolver.acquireProvider(ContentResolver.java:1395)
       at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1091)
       at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:921)
       at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:778)
       at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:733)
       at com.kbeanie.multipicker.core.threads.FileProcessorThread.getFromContentProvider(FileProcessorThread.java:249)
       at com.kbeanie.multipicker.core.threads.FileProcessorThread.processFile(FileProcessorThread.java:174)
       at com.kbeanie.multipicker.core.threads.FileProcessorThread.run(FileProcessorThread.java:1105)
       at com.kbeanie.multipicker.core.threads.ImageProcessorThread.run(ImageProcessorThread.java:41)

kishu1993 avatar Jul 26 '17 07:07 kishu1993