Android gallery & photo/video functionality simplified with RxJava2

Overview

RxGallery Android Arsenal

Android gallery & photo/video functionality simplified with RxJava2

Setup

To use this library your minSdkVersion must be >= 9.

Add it in your root build.gradle at the end of repositories:

allprojects {
  repositories {
    ...
    maven { url 'https://jitpack.io' }
  }
}

Add the dependency

dependencies {
  compile 'com.github.marchinram:RxGallery:0.6.6'
}

Usage

Picking items from the gallery

Maybe<List<Uri>> RxGallery.gallery(@NonNull Activity activity)
Maybe<List<Uri>> RxGallery.gallery(@NonNull Activity activity, boolean multiSelectEnabled)
Maybe<List<Uri>> RxGallery.gallery(@NonNull Activity activity, boolean multiSelectEnabled, @Nullable MimeType... mimeTypes)

Example - Picking multiple images/videos from the gallery:

RxGallery.gallery(this, true, RxGallery.MimeType.IMAGE, RxGallery.MimeType.VIDEO).subscribe(new Consumer<List<Uri>>() {
    @Override
    public void accept(List<Uri> uris) throws Exception {
        doStuffWithUris(uris);
    }
}, new Consumer<Throwable>() {
    @Override
    public void accept(Throwable throwable) throws Exception {
        Toast.makeText(SomeActivity.this, throwable.getMessage(), Toast.LENGTH_LONG).show();
    }
});

Taking photos with camera

Maybe<Uri> RxGallery.photoCapture(@NonNull Activity activity)
Maybe<Uri> RxGallery.photoCapture(@NonNull Activity activity, @Nullable Uri outputUri)

Example - Taking a photo with the camera and saving it to gallery:

RxGallery.photoCapture(this).subscribe(new Consumer<Uri>() {
    @Override
    public void accept(Uri uri) throws Exception {
        doStuffWithUri(uri);
    }
}, new Consumer<Throwable>() {
    @Override
    public void accept(Throwable throwable) throws Exception {
        Toast.makeText(SomeActivity.this, throwable.getMessage(), Toast.LENGTH_LONG).show();
    }
});

In 6.0+ you need to ask for WRITE_EXTERNAL_STORAGE permission to save to gallery, below is an example doing this with RxPermissions and flatMap:

Observable<Boolean> permissionObservable = Observable.just(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    permissionObservable = new RxPermissions(this).request(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}

permissionObservable.flatMap(new Function<Boolean, ObservableSource<Uri>>() {
    @Override
    public ObservableSource<Uri> apply(@NonNull Boolean granted) throws Exception {
        if (!granted) {
            return Observable.empty();
        }
        return RxGallery.photoCapture(SomeActivity.this).toObservable();
    }
}).subscribe(new Consumer<Uri>() {
    @Override
    public void accept(Uri uri) throws Exception {
        doStuffWithUri(uri);
    }
}, new Consumer<Throwable>() {
    @Override
    public void accept(Throwable throwable) throws Exception {
        Toast.makeText(SomeActivity.this, throwable.getMessage(), Toast.LENGTH_LONG).show();
    }
});

Taking videos with camera

Maybe<Uri> RxGallery.videoCapture(@NonNull Activity activity)

Example - Taking a video with the camera and saving it to gallery:

RxGallery.videoCapture(this).subscribe(new Consumer<Uri>() {
    @Override
    public void accept(Uri uri) throws Exception {
        doStuffWithUri(uri);
}, new Consumer<Throwable>() {
    @Override
    public void accept(Throwable throwable) throws Exception {
        Toast.makeText(MainActivity.this, throwable.getMessage(), Toast.LENGTH_LONG).show();
    }
});

Important

If you want the started Activity (gallery/photo/video) to be destroyed when the Activity which started it is destroyed you must keep a reference to the Disposable and call dispose as shown below:

public final class SomeActivity extends Activity {

    private Disposable disposable;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        
        disposable = RxGallery.gallery(this).subscribe(new Consumer<List<Uri>>() {
            @Override
            public void accept(List<Uri> uris) throws Exception {
                doStuffWithUris(uris);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        disposable.dispose();
    }
    
    ...
}

Alternatively you can use RxLifecycle

public final class SomeActivity extends RxActivity {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        
        RxGallery.gallery(this)
                .compose(this.<List<Uri>>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Consumer<List<Uri>>() {
                    @Override
                    public void accept(List<Uri> uris) throws Exception {
                        doStuffWithUris(uris);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {

                    }
                });
    }
    
    ...
}
Comments
  • Functions too tighly coupled to Activities.

    Functions too tighly coupled to Activities.

    Can we please pass a Context as a parameter, instead of passing Activity, only in the end to call Activity#getAppplicationContext(). This does not go well with ViewModels, for example. We should be able to use it, anywhere else, apart from Activities.

    opened by RowlandOti 5
  • Missing attributes from manifest for handling orientation change in Camera applications

    Missing attributes from manifest for handling orientation change in Camera applications

    Hi, Some camera application (Samsung's application) will force an orientation change in RxGalleryActivity when taking photos in landscape mode . Therefore the activity is recreated and the output uri si recreated too so the saved image will be overwritten resulting in a FileNotFoundException when trying to read the file from the resulted uri. A quick fix is to add this line in manifest:

    android:configChanges="orientation|keyboardHidden|screenSize"

    opened by andrevdk 2
  • No fixed number of selection of images from gallery there

    No fixed number of selection of images from gallery there

    If i want to restrict user to select a fixed number of images from gallery. i cant do that. please provide any specific solution for picking up fixed number of images selection from gallery

    opened by hiteshsarsava 2
  • Missing curly brace in first example

    Missing curly brace in first example

    Hello, Thanks for creating this great library. In your first example "Example - Picking multiple images/videos from the gallery:" You should add another closing curly brace after doStuffWithUris(uris); RxGallery.gallery(this, true, RxGallery.MimeType.IMAGE, RxGallery.MimeType.VIDEO).subscribe(new Consumer<List>() { @Override public void accept(List uris) throws Exception { doStuffWithUris(uris); }}, new Consumer() {

    Also, for other examples. regards.

    opened by a-fathian 1
  • NullPointer

    NullPointer

    Hello! I found this in crashlytics.

    Device Statistics 5.53 GiB FREE SPACE 916.00 MiB FREE RAM Devices> Xiaomi Redmi 4

    Operating Systems> 6.0.1

    Fatal Exception: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1000, result=-1, data=Intent { flg=0x43 }} to activity {*** /com.marchinram.rxgallery.RxGalleryActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.ClipData.getItemCount()' on a null object reference at android.app.ActivityThread.deliverResults(ActivityThread.java:3756) at android.app.ActivityThread.handleSendResult(ActivityThread.java:3799) at android.app.ActivityThread.access$1500(ActivityThread.java:154) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1430) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:157) at android.app.ActivityThread.main(ActivityThread.java:5555) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:635)

    opened by dmitriev-alexey 1
  • Unable to start activity ComponentInfo{/com.marchinram.rxgallery.RxGalleryActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'com.marchinram.rxgallery.RxGallery$Source com.marchinram.rxgallery.RxGallery$Request.getSource()' on a null object reference

    Unable to start activity ComponentInfo{/com.marchinram.rxgallery.RxGalleryActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'com.marchinram.rxgallery.RxGallery$Source com.marchinram.rxgallery.RxGallery$Request.getSource()' on a null object reference

    Unable to start activity ComponentInfo{packageName/com.marchinram.rxgallery.RxGalleryActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'com.marchinram.rxgallery.RxGallery$Source com.marchinram.rxgallery.RxGallery$Request.getSource()' on a null object reference

    opened by dev-hussein 2
  • Doesn't save date/file size/other fields

    Doesn't save date/file size/other fields

    See getContentValues() in https://www.programcreek.com/java-api-examples/index.php?source_dir=nexus-camera-master/src/com/android/camera/crop/SaveImage.java

    help wanted 
    opened by marchinram 0
  • Captured photo is sideways on Samsung devices

    Captured photo is sideways on Samsung devices

    A client has reported me that when taking pictures with a Samsung device the photo is showing up rotated 90º.

    This seems to be a somewhat common problem with that brand of devices, is there a particular fix either built-in the library or advised to be used?

    opened by PedroBernils 1
Owner
Brian Rojas
Brian Rojas
It's finally easy to take photos/videos via camera or get photos/videos from gallery on Android.

Shutter-Android It's finally easy to take photos/videos via camera or get photos/videos from gallery on Android. What is Shutter? Shutter is an Androi

Levi Bostian 56 Oct 3, 2022
Android Shared preference wrapper than encrypts the values of Shared Preferences. It's not bullet proof security but rather a quick win for incrementally making your android app more secure.

Secure-preferences - Deprecated Please use EncryptedSharedPreferences from androidx.security in preferenced to secure-preference. (There are no active

Scott Alexander-Bown 1.5k Dec 24, 2022
Android library which makes it easy to handle the different obstacles while calling an API (Web Service) in Android App.

API Calling Flow API Calling Flow is a Android library which can help you to simplify handling different conditions while calling an API (Web Service)

Rohit Surwase 19 Nov 9, 2021
Gesture detector framework for multitouch handling on Android, based on Android's ScaleGestureDetector

Android Gesture Detectors Framework Introduction Since I was amazed Android has a ScaleGestureDetector since API level 8 but (still) no such thing as

null 1.1k Nov 30, 2022
Use Android as Rubber Ducky against another Android device

Use Android as Rubber Ducky against another Android device

null 1.4k Jan 9, 2023
Android Utilities Library build in kotlin Provide user 100 of pre defined method to create advanced native android app.

Android Utilities Library build in kotlin Provide user 100 of pre defined method to create advanced native android app.

Shahid Iqbal 4 Nov 29, 2022
A util for setting status bar style on Android App.

StatusBarUtil A util for setting status bar style on Android App. It can work above API 19(KitKat 4.4). 中文版点我 Sample Download StatusBarUtil-Demo Chang

Jaeger 8.8k Jan 6, 2023
A logger with a small, extensible API which provides utility on top of Android's normal Log class.

This is a logger with a small, extensible API which provides utility on top of Android's normal Log class. I copy this class into all the little apps

Jake Wharton 9.8k Dec 30, 2022
Java implementation of a Disk-based LRU cache which specifically targets Android compatibility.

Disk LRU Cache A cache that uses a bounded amount of space on a filesystem. Each cache entry has a string key and a fixed number of values. Each key m

Jake Wharton 5.7k Dec 31, 2022
a simple cache for android and java

ASimpleCache ASimpleCache 是一个为android制定的 轻量级的 开源缓存框架。轻量到只有一个java文件(由十几个类精简而来)。 1、它可以缓存什么东西? 普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 b

Michael Yang 3.7k Dec 14, 2022
gRPC and protocol buffers for Android, Kotlin, and Java.

Wire “A man got to have a code!” - Omar Little See the project website for documentation and APIs. As our teams and programs grow, the variety and vol

Square 3.9k Dec 31, 2022
✔️ Secure, simple key-value storage for Android

Hawk 2.0 Secure, simple key-value storage for android Important Note This version has no backward compatibility with Hawk 1+ versions. If you still wa

Orhan Obut 3.9k Dec 20, 2022
A robust native library loader for Android.

ReLinker A robust native library loader for Android. More information can be found in our blog post Min SDK: 9 JavaDoc Overview The Android PackageMan

Keepsafe 2.9k Dec 27, 2022
A lightning fast, transactional, file-based FIFO for Android and Java.

Tape by Square, Inc. Tape is a collection of queue-related classes for Android and Java. QueueFile is a lightning-fast, transactional, file-based FIFO

Square 2.4k Dec 30, 2022
Joda-Time library with Android specialization

joda-time-android This library is a version of Joda-Time built with Android in mind. Why Joda-Time? Android has built-in date and time handling - why

Daniel Lew 2.6k Dec 9, 2022
a SharedPreferences replacement for Android with multiprocess support

DEPRECATED - no longer actively maintained Tray - a SharedPreferences replacement for Android If you have read the documentation of the SharedPreferen

HCI @ gcx 2.3k Nov 17, 2022
OpenKeychain is an OpenPGP implementation for Android.

OpenKeychain (for Android) OpenKeychain is an OpenPGP implementation for Android. For a more detailed description and installation instructions go to

OpenKeychain 1.8k Jan 3, 2023
UPnP/DLNA library for Java and Android

Cling EOL: This project is no longer actively maintained, code may be outdated. If you are interested in maintaining and developing this project, comm

4th Line 1.6k Jan 4, 2023
WebSocket & WAMP in Java for Android and Java 8

Autobahn|Java Client library providing WAMP on Java 8 (Netty) and Android, plus (secure) WebSocket for Android. Autobahn|Java is a subproject of the A

Crossbar.io 1.5k Dec 9, 2022