Coder Social home page Coder Social logo

miguelbcr / rxpaparazzo Goto Github PK

View Code? Open in Web Editor NEW
466.0 14.0 54.0 597 KB

RxJava extension for Android to take images using camera and gallery and pick files up

License: Apache License 2.0

Java 100.00%
android gallery photos camera file-picker picker crop rxjava

rxpaparazzo's Introduction

Android Arsenal

RxJava extension for Android to take photos using the camera, select files or photos from the device and optionally crop or rotate any selected images.

RxPaparazzo

What is RX?

Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.

What is a Paparazzo?

A freelance photographer who aggressively pursues celebrities for the purpose of taking candid photographs.

This library does that (well not really). But it is a cool name.

Features:

  • Runtime permissions. Not worries about the tricky Android runtime permissions system. RxPaparazzo relies on RxPermissions to deal with that.
  • Takes a photo using the built-in camera.
  • Access to gallery and other sources of photos.
  • Access to files and documents stored locally and on the cloud.
  • Crop and rotate images. RxPaparazzo relies on UCrop to perform beautiful cuts to any face, body or place.
  • Honors the observable chain (it means you can go crazy chaining operators). RxOnActivityResult allows RxPaparazzo to transform every intent into an observable for a wonderful chaining process.

Setup RxJava2

Add the JitPack repository in your build.gradle (top level module):

allprojects {
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
    }
}

Add dependencies in the build.gradle of the module:

dependencies {
    compile "com.github.miguelbcr:RxPaparazzo:0.6.1-2.x"
    compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
}

Usage

Because RxPaparazzo uses RxActivityResult to deal with intent calls, all its requirements and features are inherited too.

Before attempting to use RxPaparazzo, you need to call RxPaparazzo.register in your Android Application's onCreate supplying the current Application instance.

public class SampleApp extends Application {

    @Override public void onCreate() {
        super.onCreate();
        RxPaparazzo.register(this);
    }
}

You will need to also add a FileProvider named android.support.v4.content.FileProvider to your AndroidManifest.xml and create a paths xml file in your src/main/res/xml directory.

 <provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.file_provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_provider_paths"/>
</provider>

If you set the provider android:authorities attribute to a value other than ${applicationId}.file_provider name you must set the configuration it using RxPaparazzo.Builder.setFileProviderAuthority(String authority)

Example: file_provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
  <files-path name="RxPaparazzoImages" path="RxPaparazzo/"/>
</paths>

The file_provider_paths.xml is where files are exposed in the FileProvider. If you set the files-path path attribute to a value other than RxPaparazzo/ you must set the configuration using RxPaparazzo.Builder.setFileProviderPath(String path)

All features RxPaparazzo exposes can be accessed from both, an activity or a fragment instance.

Limitation:: Your fragments need to extend from androidx.core.app.Fragment instead of android.app.Fragment, otherwise they won't be notified.

The generic type of the observable returned by RxPaparazzo when subscribing to any of its features is always an instance of Response class.

This instance holds a reference to the current Activity/Fragment, accessible calling targetUI() method. Because the original one may be recreated it would be unsafe calling it. Instead, you must call any method/variable of your Activity/Fragment from this instance encapsulated in the response instance.

Also, this instance holds a reference to the data as the appropriate response, as such as the result code of the specific operation.

Saving files

By default, the image / file is saved in a directory the same as the app name on the root of the external storage. You can choose to save the images in internal storage by using .useInternalStorage()

The response in the callback function supplied to the subscribe() method holds a reference to the path where the image was persisted.

Calling built-in camera to take a photo.

RxPaparazzo.single(activityOrFragment)
        .usingCamera()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(response -> {
            // See response.resultCode() doc
            if (response.resultCode() != RESULT_OK) {
                response.targetUI().showUserCanceled();
                return;
            }

            response.targetUI().loadImage(response.data());
        });

Calling the file picker to retrieve a file.

RxPaparazzo.single(activityOrFragment)
        .usingFile()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(response -> {        
            // See response.resultCode() doc
            if (response.resultCode() != RESULT_OK) {
                response.targetUI().showUserCanceled();
                return;
            }

            response.targetUI().loadImage(response.data());
        });

Calling the file picker to retrieve multiple files

RxPaparazzo.multiple(activityOrFragment)
        .usingFiles()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(response -> {
            // See response.resultCode() doc
            if (response.resultCode() != RESULT_OK) {
                response.targetUI().showUserCanceled();
                return;
            }

            if (response.data().size() == 1) response.targetUI().loadImage(response.data().get(0));
            else response.targetUI().loadImages(response.data());
        });

Calling the gallery to retrieve an image.

RxPaparazzo.single(activityOrFragment)
        .usingGallery()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(response -> {
            // See response.resultCode() doc
            if (response.resultCode() != RESULT_OK) {
                response.targetUI().showUserCanceled();
                return;
            }

            response.targetUI().loadImage(response.data());
        });

Calling the gallery to retrieve multiple image

RxPaparazzo.multiple(activityOrFragment)
        .usingGallery()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(response -> {
            // See response.resultCode() doc
            if (response.resultCode() != RESULT_OK) {
                response.targetUI().showUserCanceled();
                return;
            }

            if (response.data().size() == 1) response.targetUI().loadImage(response.data().get(0));
            else response.targetUI().loadImages(response.data());
        });

Note: if the level Android api device is minor than 18, only one image will be retrieved.

Customizations

When asking RxPaparazzo for an photo / image / file it's possible to apply some configurations to the action.

Size options

Size values can be used to set the size of the image to retrieve. There are 4 options:

  • SmallSize: 1/8 aprox. of the screen resolution
  • ScreenSize: The size image matches aprox. the screen resolution.
  • OriginalSize: The original size of the image.
  • CustomMaxSize: Yot can specify max size you want and image will be scaled proportionally.

ScreenSize value will be set as default.

RxPaparazzo.multiple(activityOrFragment)
                .size(new ScreenSize())
                .usingGallery()

Cropping support for image.

This feature is available thanks to the amazing library uCrop authored by Yalantis group.

RxPaparazzo.multiple(activityOrFragment)
                .crop()

By calling crop() method when building the observable instance, all they images retrieved will be able to be cropped, regardless if the images were retrieved using the built-in camera or gallery, even if multiple images were requested in a single call using single() approach. Because uCrop Yalantis library exposes some configuration in order to customize the crop screen, RxPaparazzo exposes an overloaded method of crop(UCrop.Options) which allow to pass an instance of UCrop.Options. If you need to configure the aspect ratio, the max result size or using the source image aspect ratio, you must pass an instance of Options class, which extends from UCrop.Options and adds the three missing properties.

UCrop.Options options = new UCrop.Options();
options.setToolbarColor(ContextCompat.getColor(getActivity(), R.color.colorPrimaryDark));

RxPaparazzo.single(activityOrFragment).crop(options)
Options options = new Options();
options.setToolbarColor(ContextCompat.getColor(getActivity(), R.color.colorPrimaryDark));
options.setAspectRatio(25, 50); 

RxPaparazzo.single(activityOrFragment)
         .crop(options)

Media scanning

To send files to the media scanner so that they can be indexed and available in applications such as the Gallery use sendToMediaScanner(). If you are using useInternalStorage() then the media scanner will not be able to access the file.

Picking files

If you wish to limit the type of images or files then use setMimeType(String mimeType) to specify a specific mime type for the Intent. You can also use .setMultipleMimeType(String... mimeType) to specify multiple mime types. By default Intent.ACTION_GET_CONTENT is used to request images and files. If you wish to edit the original file call useDocumentPicker(), this will allow greater, possiblty persistent access to the source file.

Proguard

# Rxjava rules
-dontwarn rx.internal.util.**

-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
    long producerIndex;
    long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
    long producerNode;
    long consumerNode;
}

Testing

Testing has been done using the following Genymotion devices:

  • Genymotion - Google Nexus 5 5.0.0 API 21 1080x1920 480dpi
  • Genymotion - Google Nexus 7 5.1.0 API 22 800x1280 213dpi

Credits

Authors

Víctor Albertos

Miguel García

James McIntosh

Another author's libraries using RxJava:

  • RxCache: Reactive caching library for Android and Java.
  • RxGcm: RxJava extension for Gcm which acts as an architectural approach to easily satisfy the requirements of an android app when dealing with push notifications.
  • RxActivityResult: A tiny reactive library to break with the OnActivityResult implementation as it breaks the observables chain.

rxpaparazzo's People

Contributors

bryant1410 avatar franciscoe-hudl avatar jm-agrimap avatar miguelbcr avatar omegasoft7 avatar ramanbranavitski avatar victoralbertos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rxpaparazzo's Issues

Using Camera and Gallery at the same time

Is there any way to make this library working with camera and gallery at the same time? So the user can choose whether to use camera or gallery, without having me to create the condition if the user want to use camera, or want to use gallery.

Thanks, your library really helps me.

java.lang.AbstractMethodError: abstract method "io.reactivex.Observable rx_activity_result2.OnPreResult.response(int, int, android.content.Intent)"

When I run Example code

        RxPaparazzo.single(this)
                .usingGallery()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Response<ChatActivity, FileData>>() {
                    @Override
                    public void accept(Response<ChatActivity, FileData> response) throws Exception {
                        // See response.resultCode() doc
                    /*if (response.resultCode() != RESULT_OK) {
                        response.targetUI().showUserCanceled();
                        return;
                    }

                    response.targetUI().loadImage(response.data());*/
                    }
                });

then get this exception
looks like the RxAtivityResult2 has update something but here is outdated.

crashes everytime on returning from gallery/camera intent

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.withdirect.mobile/rx_activity_result.HolderActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2198)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)
at android.app.ActivityThread.access$800(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at rx_activity_result.HolderActivity.onCreate(HolderActivity.java:33)
at android.app.Activity.performCreate(Activity.java:5248)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257) 
at android.app.ActivityThread.access$800(ActivityThread.java:139) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:136) 
at android.app.ActivityThread.main(ActivityThread.java:5086) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
at dalvik.system.NativeStart.main(Native Method) 

Hope to hear from you sooon! :)

Resize image to custom size.

It will be very fine if you add possibility to resize image to any custom size. Now, you have such possibility. The most suitable size now is Screen, but if we use app on tablets and phones this size type is not exactly what users of this library want. I create pull request for this feature.

Request is null after calling camera intent

I get following exception:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'rx_activity_result.OnResult rx_activity_result.Request.onResult()' on a null object reference
at rx_activity_result.HolderActivity.onCreate(HolderActivity.java:33)
at android.app.Activity.performCreate(Activity.java:6374)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2743)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2855) 
at android.app.ActivityThread.access$900(ActivityThread.java:181) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1474) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:145) 
at android.app.ActivityThread.main(ActivityThread.java:6117) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 

This is how I use it:

@Override
public boolean onMenuItemClick(MenuItem item)
{
    switch (item.getItemId())
    {
        case R.id.action_camera:
        {
            // does take care of camera permission!!!
            RxPaparazzo.takeImage(getActivity())
                    .usingCamera()
                    .subscribe(response -> {
                        if (response.resultCode() != Activity.RESULT_OK)
                            return;
                        onImageTaken(response.targetUI(), response.data());
                    });
            break;
        }
}

Any idea why this happens? In my Application I do call RxPaparazzo.register(this);...

Some sideeffect is, that the image is not even saved...

how can we use UCrop features?

Hi

There are some features in UCrop lib that i need to use it on my project.
Features like:

UCrop.of(sourceUri, destinationUri)
.withAspectRatio(16, 9)
.withMaxResultSize(maxWidth, maxHeight)
.start(context);

Can we make more options like Size that we have and pass these parameters as well?

Do we really need to provide an activity or a fragment?

Hey Miguel, quick question over here: Is it truly needed to provide an activity or a fragment to RxPaparazzo? Shouldn't it suffice to provide an application context or a context itself? I understand you use the activity/fragment in the subscription, but as an example, If someone tries to use RxPaparazzo on a presenter (MVP), then the presenter would need to be aware of the Activity, thus breaking the whole MVP concept (Activity and Presenter should only communicate through the View the Activity implements, thus not be aware of each other). I guess a context overload should be available for this purposes where the developer doesn't care about the TargetUI at all because it already has a view (MVP).

Thanks for the awesome library an effort you put on it.

Doesn't work with facebook sdk on API 19

If you include facebook sdk in project on android API 19 you get the following stacktrace while trying to perform register(this):

0-12 17:20:34.161 16729-16729/com.zeroger.application E/dalvikvm: Could not find class 'rx_activity_result.RxActivityResult$Builder', referenced from method rx_activity_result.RxActivityResult.on 10-12 17:20:34.171 16729-16729/com.zeroger.application E/dalvikvm: Could not find class 'rx_activity_result.RxActivityResult$Builder', referenced from method rx_activity_result.RxActivityResult.on 10-12 17:20:34.171 16729-16729/com.zeroger.application E/dalvikvm: Could not find class 'rx_activity_result.ActivitiesLifecycleCallbacks', referenced from method rx_activity_result.RxActivityResult.register 10-12 17:20:34.171 16729-16729/com.zeroger.application E/AndroidRuntime: FATAL EXCEPTION: main Process: com.zeroger.application, PID: 16729 java.lang.NoClassDefFoundError: rx_activity_result.ActivitiesLifecycleCallbacks at rx_activity_result.RxActivityResult.register(RxActivityResult.java:37) at com.fuck_boilerplate.rx_paparazzo.RxPaparazzo.register(RxPaparazzo.java:39) at com.zerogerc.application.model.ExperimentsApplication.onCreate(ExperimentsApplication.java:21)....

This is occured not only on RxPaparzzo. RxActivityResult have the same issue.
Could you propose possible fix?

Missing onError handling while dealing with java.io.FileNotFoundException

RxPaparazzo version 0.4.3

Fatal Exception: java.lang.IllegalStateException: Exception thrown on Scheduler.Worker thread. Add `onError` handling.
       at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:57)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
       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:841)
Caused by rx.exceptions.OnErrorNotImplementedException: Failed opening content provider: content://media/external/images/media/1367
       at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:386)
       at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:383)
       at rx.internal.util.ActionSubscriber.onError(ActionSubscriber.java:44)
       at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:153)
       at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:115)
       at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
       at rx.internal.operators.OnSubscribeMap$MapSubscriber.onError(OnSubscribeMap.java:88)
       at rx.internal.operators.OperatorSubscribeOn$1$1.onError(OperatorSubscribeOn.java:59)
       at rx.internal.operators.OperatorSubscribeOn$1$1.onError(OperatorSubscribeOn.java:59)
       at com.miguelbcr.ui.rx_paparazzo.interactors.DownloadImage$1.call(DownloadImage.java:61)
       at com.miguelbcr.ui.rx_paparazzo.interactors.DownloadImage$1.call(DownloadImage.java:50)
       at rx.Observable.unsafeSubscribe(Observable.java:10140)
       at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
       at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:228)
       at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
       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:841)
Caused by java.io.FileNotFoundException: Failed opening content provider: content://media/external/images/media/1367
       at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1102)
       at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:904)
       at android.content.ContentResolver.openInputStream(ContentResolver.java:629)
       at com.miguelbcr.ui.rx_paparazzo.interactors.DownloadImage.getContent(DownloadImage.java:80)
       at com.miguelbcr.ui.rx_paparazzo.interactors.DownloadImage.access$100(DownloadImage.java:30)
       at com.miguelbcr.ui.rx_paparazzo.interactors.DownloadImage$1.call(DownloadImage.java:54)
       at com.miguelbcr.ui.rx_paparazzo.interactors.DownloadImage$1.call(DownloadImage.java:50)
       at rx.Observable.unsafeSubscribe(Observable.java:10140)
       at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94)
       at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:228)
       at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
       at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
       at java.util.concurrent.FutureTask.run(FutureTask.java:237)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
       at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
       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:841)

Example on FileProvider

On the RxJava 2 branch the FileProvider is being used. When adding a custom file_provider there is no clear documentation how to obtain the file_provider

Using this in the builder object is not working:
.setFileProviderAuthority((BuildConfig.APPLICATION_ID + ".file_provider")

Failed to find configured root that contains /data/data/com.globyworks.citykey.debug/files/RxPaparazzo/PHOTO-20170302_1048_30638.jpg

<paths> <files-path name="CityKeyImages" path="CityKey/" /> </paths>

NullPointerException when uri in Intent is null

Hello!
Recently I've noticed such issue:

java.lang.NullPointerException at
com.miguelbcr.ui.rx_paparazzo.interactors.PickImage$2.response (PickImage.java:63)
rx_activity_result.HolderActivity.onActivityResult (HolderActivity.java:86)

Seems like sometimes image picker can return RESULT_OK, but not return actual data in intent.

Fragment doesn't receive result of image pick

I'm trying to pick an image from gallery. I successfully launch gallery intent with this code but nothing happens after I select an image. None of "subscibe" callbacks get called.

public class PhotosFragment extends Fragment {
...
    private void loadFromGallery() {
        RxPaparazzo.takeImage(this)
                .crop()
                .usingGallery()
                .subscribe(new Subscriber<Response<PhotosFragment, String>>() {
                @Override
                public void onCompleted() {
                    Log.d("PhotosFragmentD", "On photo pick completed");
                }

                @Override
                public void onError(Throwable e) {
                    e.printStackTrace();
                }

                @Override
                public void onNext(Response<PhotosFragment, String> response) {
                    currentImagePath = response.data();
                    response.targetUI().displayCaptionDialog();
                }
        });
    }

What's wrong with my code? How can I debug this issue?

Proguard rules

I am using proguard in my project. What kind of proguard rules should I add in my proguard file to avoid all the warnings and crashes? Can you include description in library readme file?

Currently I am getting such crash when using RxPaparazzo with proguard:

Crashed: main: 0 0 0x0000000000000000
       at rx.internal.util.unsafe.UnsafeAccess.addressOf(UnsafeAccess.java:109)
       at rx.internal.util.unsafe.MpmcArrayQueueProducerField.(MpmcArrayQueue.java:31)
       at rx.internal.util.ObjectPool.initialize(ObjectPool.java:153)
       at rx.internal.util.ObjectPool.(ObjectPool.java:57)
       at rx.internal.util.ObjectPool.(ObjectPool.java:36)
       at rx.internal.util.RxRingBuffer$1.(RxRingBuffer.java:280)
       at rx.internal.util.RxRingBuffer.(RxRingBuffer.java:280)

Builder has private access

Hey, I'm trying to change the file provider name, and the docs say to use RxPaparazzo.Builder.setFileProviderAuthority(String authority), which has private access in the RxPaparazzo class. How can I do this?

NullPointerException in GetPath

Hi!
Seems like sometimes we can miss reference to target activity or fragment (i think when we are trying to pass result to detached fragment, for example)

Caused by java.lang.NullPointerException
android.provider.DocumentsContract.isDocumentsProvider (DocumentsContract.java:750)
android.provider.DocumentsContract.isDocumentUri (DocumentsContract.java:733)
com.miguelbcr.ui.rx_paparazzo.interactors.GetPath.getPath (GetPath.java:59)
com.miguelbcr.ui.rx_paparazzo.interactors.GetPath.react (GetPath.java:47)
com.miguelbcr.ui.rx_paparazzo.interactors.PickImage$2.response (PickImage.java:62)
rx_activity_result.HolderActivity.onActivityResult (HolderActivity.java:86)

How to pick photo from gallery without making copy of it?

1.I want to choose pick a image from gallery and display it without cropping and that is why I'm passing null for options pickSingle(null, OriginalSize())
but I see it saves the copy of existing file as I try to pick a new one I see the copied version of my original photo , I mean if I want to display existing photo I don't want to have the copied version.

2 When I'm want to change the photo as a result of picking a photo (it opens the Recent folder) navigating to Photos and to the RxPaparazzo folder it displays the count 5 photos (the copied versions as well ),but when I navigate inside the folder only the original ones,not copied photos

Different error codes for denied permissions.

It would be great if you add different resultCode when user denied permission with checked "Do not ask again" or not. I know that it issue most suitable for RxPaparazzo, but may be you can add this feature locally.

Losing data with horizontal camera

I've just tested RxPaparazzo on Samsung Galaxy Note 2 and found an issue on activity orientation change. When device starts camera in horizontal orientation my activity also turns and destroys. When callback returns it leads to the destroyed activity. I decided to keep my activity alive on orientation change and used dirty hack android:configChanges="keyboardHidden|orientation|screenSize" because I don't have different resources for different orientation of screen.

@VictorAlbertos @miguelbcr do you think this bug related with samsung specific devices or all devices which has horizontal camera?

App crash (pick image/images from GDrive without Crop option)

App crash after pick images from Google Drive (or any remote storage) without cropping
Logs:
java.lang.RuntimeException: Unable to destroy activity {com.fuck_boilerplate.rx_paparazzo.sample/rx_activity_result.HolderActivity}: rx.exceptions.OnErrorNotImplementedException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3831) at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3849) at android.app.ActivityThread.-wrap5(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: rx.exceptions.OnErrorNotImplementedException: Attempt to invoke virtual method 'char[] java.lang.String.toCharArray()' on a null object reference at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:374) at rx.internal.util.InternalObservableUtils$ErrorNotImplementedAction.call(InternalObservableUtils.java:371) at rx.internal.util.ActionSubscriber.onError(ActionSubscriber.java:44) at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:157) at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120) at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:204) at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:143) at rx.internal.operators.OperatorMap$MapSubscriber.onError(OperatorMap.java:85) at rx.internal.operators.OperatorMerge$MergeSubscriber.reportError(OperatorMerge.java:266) at rx.internal.operators.OperatorMerge$MergeSubscriber.checkTerminate(OperatorMerge.java:810) at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:571) at rx.internal.operators.OperatorMerge$MergeSubscriber.emit(OperatorMerge.java:560) at rx.internal.operators.OperatorMerge$InnerSubscriber.onError(OperatorMerge.java:844) at rx.observers.Subscribers$5.onError(Subscribers.java:224) at rx.exceptions.Exceptions.throwOrReport(Exceptions.java:192) at rx.internal.operators.OperatorZip$Zip.tick(OperatorZip.java:269) at rx.internal.operators.OperatorZip$Zip$InnerSubscriber.onNext(OperatorZip.java:335) at rx.internal.operators.OperatorMap$MapSubscriber.onNext(OperatorMap.java:74) at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:268) at rx.Subscriber.setProducer(Subscriber.java:211) at rx.internal.operators.OperatorMap$MapSubscriber.setProducer(OperatorMap.java:99) at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:79) at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:75) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:50) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) at rx.Observable.unsafeSubscribe(Observable.java:8460) at rx.internal.operators.OperatorZip$Zip.start(OperatorZip.java:214) at rx.internal.operators.OperatorZip$ZipSubscriber.onNext(OperatorZip.java:156) at rx.internal.operators.OperatorZip$ZipSubscriber.onNext(OperatorZip.java:122) at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:268) at rx.Subscriber.setProducer(Subscriber.java:209) at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:79) at rx.internal.util.ScalarSynchronousObservable$1.call(ScalarSynchronousObservable.java:75) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:50) at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) at rx.Observable.unsafe

RxPaparazzo duplicate images when it selects from gallery

Hi guys,

I would like to know why paparazzo is creating new images when I select images from the gallery. Check the last question to find the stackoverflow's link to see the update. I uploaded a video that shows the duplication.

Thank for fixing the other issue so fast.

Incompatible with Dagger 1

The library uses Dagger 2 and annotation processing for DI. Our main app doesn't use either, rather going for a Dagger 1 and no apt approach. This causes conflicts when compiling because the Transform API detects two instances of Dagger.

While I value the cleanliness provided by DI it may be too opinionated to include it on a library. Given the small scope of the classes I would opt for manual constructor injection instead.

When I just include library to gradle I get TintManager error

05-05 13:49:21.336 14924-14924/com.example.someapp E/AndroidRuntime: FATAL EXCEPTION: main
   Process: com.example.someapp, PID: 14924
   java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/widget/TintManager;
       at android.support.design.widget.TabLayout$TabView.<init>(TabLayout.java:1185)
       at android.support.design.widget.TabLayout.createTabView(TabLayout.java:656)
       at android.support.design.widget.TabLayout.addTabView(TabLayout.java:695)
       at android.support.design.widget.TabLayout.addTab(TabLayout.java:386)
       at android.support.design.widget.TabLayout.addTab(TabLayout.java:361)
       at android.support.design.widget.TabLayout.setTabsFromPagerAdapter(TabLayout.java:645)
       at android.support.design.widget.TabLayout.setupWithViewPager(TabLayout.java:616)
       at com.example.someapp.ui.navigation.trade.TradeFragment.onViewCreated(TradeFragment.kt:201)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
       at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
       at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
       at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:339)
       at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:602)
       at com.trello.navi.component.support.NaviAppCompatActivity.onStart(NaviAppCompatActivity.java:41)
       at com.example.someapp.api.messaging.NetActivity.onStart(NetActivity.java:70)
       at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1237)
       at android.app.Activity.performStart(Activity.java:6268)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
       at android.app.ActivityThread.-wrap11(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5417)
       at java.lang.reflect.Method.invoke(Native Method)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
    Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v7.widget.TintManager" on path: DexPathList[[zip file "/data/app/com.example.someapp-2/base.apk"],nativeLibraryDirectories=[/data/app/com.example.someapp-2/lib/arm, /data/app/com.example.someapp-2/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]
       at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
       at android.support.design.widget.TabLayout$TabView.<init>(TabLayout.java:1185) 
       at android.support.design.widget.TabLayout.createTabView(TabLayout.java:656) 
       at android.support.design.widget.TabLayout.addTabView(TabLayout.java:695) 
       at android.support.design.widget.TabLayout.addTab(TabLayout.java:386) 
       at android.support.design.widget.TabLayout.addTab(TabLayout.java:361) 
       at android.support.design.widget.TabLayout.setTabsFromPagerAdapter(TabLayout.java:645) 
       at android.support.design.widget.TabLayout.setupWithViewPager(TabLayout.java:616) 
       at com.example.someapp.ui.navigation.trade.TradeFragment.onViewCreated(TradeFragment.kt:201) 
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086) 
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) 
       at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738) 
       at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) 
       at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:339) 
       at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:602) 
       at com.trello.navi.component.support.NaviAppCompatActivity.onStart(NaviAppCompatActivity.java:41) 
       at com.example.someapp.api.messaging.NetActivity.onStart(NetActivity.java:70) 
       at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1237) 
       at android.app.Activity.performStart(Activity.java:6268) 
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379) 
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
       at android.app.ActivityThread.-wrap11(ActivityThread.java) 
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
       at android.os.Handler.dispatchMessage(Handler.java:102) 
       at android.os.Looper.loop(Looper.java:148) 
       at android.app.ActivityThread.main(ActivityThread.java:5417) 
       at java.lang.reflect.Method.invoke(Native Method) 
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
    Suppressed: java.lang.ClassNotFoundException: android.support.v7.widget.TintManager
       at java.lang.Class.classForName(Native Method)
       at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
       at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
            ... 29 more
    Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

Could not change the path for saving files

I want to change the path



and put my application name, but adding RxPaparazzo.Builder.setFileProviderPath(String path)
doesn't work as RxPaparazzo doesn't have Builder
and I'm using
compile "com.github.miguelbcr:RxPaparazzo:0.5.4-2.x"

NoClassDefFoundError Size

I got this error message when i was trying to pick an image from gallery.
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/fuck_boilerplate/rx_paparazzo/entities/Size;
Please HELP
Thanks!

My code :

        Size size = Size.Small;
        RxPaparazzo.takeImages(fragment)
                   .crop()
                   .size(size)
                   .usingGallery()
                   .subscribe(
                           new Action1<com.fuck_boilerplate.rx_paparazzo.entities.Response<GenericFragment, List<String>>>() {
                               @Override
                               public void call(
                                       com.fuck_boilerplate.rx_paparazzo.entities.Response<GenericFragment, List<String>> response) {
                                   if (response.resultCode() != Activity.RESULT_OK) {
                                       response.targetUI().imagePickFail();
                                       return;
                                   }
                                   for (int i = 0; i < response.data().size(); i++) {
                                       File imageFile = new File(response.data().get(i));
                                       Picasso.with(fragment.getActivity()).setLoggingEnabled(true);
                                       Picasso.with(fragment.getActivity())
                                              .invalidate(new File(response.data().get(i)));
                                       Picasso.with(fragment.getActivity()).load(imageFile).into(imageView);
                                   }
                               }
                           }

                   );

Memory Leak Media Scanner Connection

Has anybody encountered that LeakCanary is complaining about memory leaks? This happens when rxPaparazzo is used on an Activity, when used on fragment I don't see any leaks. Below is what I am using the take either a picture or retrieve from gallery.

compositeSubscription.add(RxPaparazzo.takeImage(this)
                   .size(new CustomMaxSize(900))
                   .usingGallery()
                   .subscribeOn(Schedulers.io())
                   .observeOn(AndroidSchedulers.mainThread())
                   .doOnError(Timber::d)
                   .subscribe(response -> {
                       if (response.resultCode() != RESULT_OK) {
                           response.targetUI()
                                   .showUserCanceled();
                           return;
                       }
                       response.targetUI()
                               .loadPicture(response.data());
                   }));

Allow to use gallery without Intent.CATEGORY_OPENABLE

Hi there,

great work on the library guys. I ran into an issue though where would like to access images from my photos.google.com linked to my android account. They appear in the documents intent but just not with this library.

As i understand this does not work because you add the flag Intent.CATEGORY_OPENABLE in PickImages.java

`

    private Intent getFileChooserIntent() {
            Intent intent = new Intent();
            intent.setType("image/*");

            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                intent.setAction(Intent.ACTION_GET_CONTENT);
            } else {
                intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
                intent.addCategory(Intent.CATEGORY_OPENABLE);
            }

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
            }

            return intent;
        }

`

Is this limitation there for a reason? Could the feature be added to allow fetching documents from sources for instance http:// ?

Thanks
Tobias

Fatal exception when I try to take pickture

Here is my code
RxPaparazzo.single(activity) .usingCamera() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ response -> // Do smth })

And stcktrace
06-12 11:25:51.531 32762-32762/com.ezlo.tracker.debug E/AndroidRuntime: FATAL EXCEPTION: main Process: com.ezlo.tracker.debug, PID: 32762 io.reactivex.exceptions.OnErrorNotImplementedException: 1 exceptions occurred. at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704) at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701) at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:74) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.checkTerminated(ObservableObserveOn.java:276) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:172) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252) at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) Caused by: io.reactivex.exceptions.CompositeException: 1 exceptions occurred. at io.reactivex.internal.operators.observable.ObservableOnErrorNext$OnErrorNextObserver.onError(ObservableOnErrorNext.java:94) at io.reactivex.internal.observers.BasicFuseableObserver.onError(BasicFuseableObserver.java:100) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onError(ObservableFlatMap.java:288) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onError(ObservableFlatMap.java:288) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:125) at io.reactivex.internal.operators.single.SingleToObservable$SingleToObservableObserver.onSuccess(SingleToObservable.java:59) at io.reactivex.internal.operators.single.SingleFlatMap$SingleFlatMapCallback$FlatMapSingleObserver.onSuccess(SingleFlatMap.java:111) at io.reactivex.internal.operators.single.SingleJust.subscribeActual(SingleJust.java:30) at io.reactivex.Single.subscribe(Single.java:2703) at io.reactivex.internal.operators.single.SingleFlatMap$SingleFlatMapCallback.onSuccess(SingleFlatMap.java:84) at io.reactivex.internal.operators.observable.ObservableToListSingle$ToListObserver.onComplete(ObservableToListSingle.java:113) at io.reactivex.observers.SerializedObserver.onComplete(SerializedObserver.java:181) at io.reactivex.internal.operators.observable.ObservableConcatMap$SourceObserver.drain(ObservableConcatMap.java:205) at io.reactivex.internal.operators.observable.ObservableConcatMap$SourceObserver.onComplete(ObservableConcatMap.java:148) at io.reactivex.internal.operators.observable.ObservableFlattenIterable$FlattenIterableObserver.onComplete(ObservableFlattenIterable.java:134) at io.reactivex.internal.operators.observable.ObservableBuffer$BufferExactObserver.onComplete(ObservableBuffer.java:134) 06-12 11:25:51.532 32762-32762/com.ezlo.tracker.debug E/AndroidRuntime: at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:367) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onComplete(ObservableFlatMap.java:300) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:367) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onComplete(ObservableFlatMap.java:300) at io.reactivex.internal.operators.observable.ObservableFromArray$FromArrayDisposable.run(ObservableFromArray.java:110) at io.reactivex.internal.operators.observable.ObservableFromArray.subscribeActual(ObservableFromArray.java:36) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableBuffer.subscribeActual(ObservableBuffer.java:44) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableFlattenIterable.subscribeActual(ObservableFlattenIterable.java:44) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableConcatMap.subscribeActual(ObservableConcatMap.java:52) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableToListSingle.subscribeActual(ObservableToListSingle.java:58) at io.reactivex.Single.subscribe(Single.java:2703) at io.reactivex.internal.operators.single.SingleFlatMap.subscribeActual(SingleFlatMap.java:36) at io.reactivex.Single.subscribe(Single.java:2703) at io.reactivex.internal.operators.single.SingleToObservable.subscribeActual(SingleToObservable.java:34) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:33) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableOnErrorNext.subscribeActual(ObservableOnErrorNext.java:38) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96) at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:452) at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61) at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:761) Caused by: io.reactivex.exceptions.CompositeException$CompositeExceptionCausalChain: Chain of Causes for CompositeException In Order Received => at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:364) 06-12 11:25:51.532 32762-32762/com.ezlo.tracker.debug E/AndroidRuntime: at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704) at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701) at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:74) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.checkTerminated(ObservableObserveOn.java:276) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:172) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252) at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference at android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:583) at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:557) at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:399) at com.miguelbcr.ui.rx_paparazzo2.interactors.TakePhoto.getUri(TakePhoto.java:84) at com.miguelbcr.ui.rx_paparazzo2.interactors.TakePhoto.react(TakePhoto.java:53) at com.miguelbcr.ui.rx_paparazzo2.workers.Camera$3.apply(Camera.java:65) at com.miguelbcr.ui.rx_paparazzo2.workers.Camera$3.apply(Camera.java:63) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:121) at io.reactivex.internal.operators.single.SingleToObservable$SingleToObservableObserver.onSuccess(SingleToObservable.java:59) at io.reactivex.internal.operators.single.SingleFlatMap$SingleFlatMapCallback$FlatMapSingleObserver.onSuccess(SingleFlatMap.java:111) at io.reactivex.internal.operators.single.SingleJust.subscribeActual(SingleJust.java:30) at io.reactivex.Single.subscribe(Single.java:2703) at io.reactivex.internal.operators.single.SingleFlatMap$SingleFlatMapCallback.onSuccess(SingleFlatMap.java:84) at io.reactivex.internal.operators.observable.ObservableToListSingle$ToListObserver.onComplete(ObservableToListSingle.java:113) at io.reactivex.observers.SerializedObserver.onComplete(SerializedObserver.java:181) at io.reactivex.internal.operators.observable.ObservableConcatMap$SourceObserver.drain(ObservableConcatMap.java:205) at io.reactivex.internal.operators.observable.ObservableConcatMap$SourceObserver.onComplete(ObservableConcatMap.java:148) at io.reactivex.internal.operators.observable.ObservableFlattenIterable$FlattenIterableObserver.onComplete(ObservableFlattenIterable.java:134) at io.reactivex.internal.operators.observable.ObservableBuffer$BufferExactObserver.onComplete(ObservableBuffer.java:134) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:367) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onComplete(ObservableFlatMap.java:300) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:367) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323) 06-12 11:25:51.532 32762-32762/com.ezlo.tracker.debug E/AndroidRuntime: at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onComplete(ObservableFlatMap.java:300) at io.reactivex.internal.operators.observable.ObservableFromArray$FromArrayDisposable.run(ObservableFromArray.java:110) at io.reactivex.internal.operators.observable.ObservableFromArray.subscribeActual(ObservableFromArray.java:36) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableBuffer.subscribeActual(ObservableBuffer.java:44) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableFlattenIterable.subscribeActual(ObservableFlattenIterable.java:44) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableConcatMap.subscribeActual(ObservableConcatMap.java:52) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableToListSingle.subscribeActual(ObservableToListSingle.java:58) at io.reactivex.Single.subscribe(Single.java:2703) at io.reactivex.internal.operators.single.SingleFlatMap.subscribeActual(SingleFlatMap.java:36) at io.reactivex.Single.subscribe(Single.java:2703) at io.reactivex.internal.operators.single.SingleToObservable.subscribeActual(SingleToObservable.java:34) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:33) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableOnErrorNext.subscribeActual(ObservableOnErrorNext.java:38) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96) at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:452) at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:61) at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:52) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:761) 06-12 11:25:51.533 32762-32762/com.ezlo.tracker.debug D/Error: ERR: exClass=java.lang.NullPointerException 06-12 11:25:51.533 32762-32762/com.ezlo.tracker.debug D/Error: ERR: exMsg=Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference 06-12 11:25:51.533 32762-32762/com.ezlo.tracker.debug D/Error: ERR: file=FileProvider.java 06-12 11:25:51.533 32762-32762/com.ezlo.tracker.debug D/Error: ERR: class=android.support.v4.content.FileProvider 06-12 11:25:51.533 32762-32762/com.ezlo.tracker.debug D/Error: ERR: method=parsePathStrategy line=583 06-12 11:25:51.533 32762-32762/com.ezlo.tracker.debug D/Error: ERR: stack=io.reactivex.exceptions.OnErrorNotImplementedException: 1 exceptions occurred. at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704) at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701) at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:74) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.checkTerminated(ObservableObserveOn.java:276) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:172) at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252) at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) Caused by: io.reactivex.exceptions.CompositeException: 1 exceptions occurred. at io.reactivex.internal.operators.observable.ObservableOnErrorNext$OnErrorNextObserver.onError(ObservableOnErrorNext.java:94) at io.reactivex.internal.observers.BasicFuseableObserver.onError(BasicFuseableObserver.java:100) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onError(ObservableFlatMap.java:288) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:495) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:331) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onError(ObservableFlatMap.java:288) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onNext(ObservableFlatMap.java:125) at io.reactivex.internal.operators.single.SingleToObservable$SingleToObservableObserver.onSuccess(SingleToObservable.java:59) at io.reactivex.internal.operators.single.SingleFlatMap$SingleFlatMapCallback$FlatMapSingleObserver.onSuccess(SingleFlatMap.java:111) at io.reactivex.internal.operators.single.SingleJust.subscribeActual(SingleJust.java:30) at io.reactivex.Single.subscribe(Single.java:2703) at io.reactivex.internal.operators.single.SingleFlatMap$SingleFlatMapCallback.onSuccess(SingleFlatMap.java:84) at io.reactivex.internal.operators.observable.ObservableToListSingle$ToListObserver.onComplete(ObservableToListSingle.java:113) at io.reactivex.observers.SerializedObserver.onComplete(SerializedObserver.java:181) at io.reactivex.internal.operators.observable.ObservableConcatMap$SourceObserver.drain(ObservableConcatMap.java:205) at io.reactivex.internal.operators.observable.ObservableConcatMap$SourceObserver.onComplete(ObservableConcatMap.java:148) at io.reactivex.internal.operators.observable.ObservableFlattenIterable$FlattenIterableObserver.onComplete(ObservableFlattenIterable.java:134) at io.reactivex.internal.operators.observable.ObservableBuffer$BufferExactObserver.onComplete(ObservableBuffer.java:134) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:367) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(Obse

How to save Image in internal storage instead of external storage

I am using library for selecting user profile image and crop. It's work pretty well for me. But I do not want to take external storage permission from user for saving selected/cropped image.

I just need to save image on temporary basis so if I can save temporary image in internal storage then it would be best for me. As doing this way I can avoid external Storage permission.

Query: Can we have provision in library so that we can save image in internal storage instead or external.

Waiting for your earliest reply.

Crash/exception when using size option

When picking an image from the gallery, some images throw an IOException when using the size option, e.g. RxPaparazzo.takeImage(activity).usingGallery().size(new CustomMaxSize(500));

java.lang.RuntimeException: java.io.IOException: Invalid marker
    at rx.exceptions.Exceptions.propagate(Exceptions.java:58)
    at com.fuck_boilerplate.rx_paparazzo.interactors.ImageUtils.copyExifRotation(ImageUtils.java:260)
    ...
Caused by: java.io.IOException: Invalid marker
    at android.media.ExifInterface.saveJpegAttributes(ExifInterface.java:1961)
    at android.media.ExifInterface.saveAttributes(ExifInterface.java:1604)
   at com.fuck_boilerplate.rx_paparazzo.interactors.ImageUtils.copyExifRotation(ImageUtils.java:256)

Looks like they had the same problem in the uCrop library. Yalantis/uCrop#184

Dependency free version (no uCrop)

Is it possible to split the library into two parts, one with crop support (and the corresponding dependency to uCrop) and one without?

So that we end up with a usage like following:

compile "com.github.FuckBoilerplate:RxPaparazzo:0.1.0"
compile "com.github.FuckBoilerplate:RxPaparazzo-crop:0.1.0"

so that someone who does not want to include uCrop can still use your library?

Using normal onActivityResult in fragment

 Options options = new Options();
    options.setToolbarColor(ContextCompat.getColor(getActivity(), R.color.colorAccent));
    options.setAspectRatio(500, 500);

RxPaparazzo.register(this);

Firstly, thanks for perfect library. But, i have a problem with using onActivityResult. I know you dont like this but, my project gives some error with your solution. So how can i get path of image when photo cropped? Thank you

`public void onActivityResult(int requestCode, int resultCode, Intent data) {

if (requestCode == REQUEST_GALLERY && resultCode == Activity.RESULT_OK&& null != data) {

    return;
}

}`
i want to both of camera and gallery code for my project. Thanks

By the way i'm using for choose photo and crop, with this code:
size = Size.Original; RxPaparazzo.takeImage(this) .size(size) .crop(options) .usingCamera() .subscribe();

is this true?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.