The api which Android SDK exposes to retrieve the data from a 'returning system call' (camera, gallery, email...) just does not give a shit about Don't break the chain leitmotiv. Indeed, the OnActivityResult approach will break entirely your observable chaining.
I did this library to not have to deal with this OnActivityResult
pattern. Never. Ever.
- Launch the intent from any class, as long as you supply a valid
Activity
orFragment
instance. - Get the
Intent
back with the data encapsulated in anobservable
and keep going crazy chaining operators.
Add the JitPack repository in your build.gradle (top level module):
allprojects {
repositories {
jcenter()
maven { url "https://jitpack.io" }
}
}
And add next dependencies in the build.gradle of the module:
dependencies {
compile 'com.github.VictorAlbertos:RxActivityResult:0.4.5-2.x'
compile 'io.reactivex.rxjava2:rxjava:2.0.5'
}
Call RxActivityResult.register
in your Android Application
class, supplying as parameter the current instance.
public class SampleApp extends Application {
@Override public void onCreate() {
super.onCreate();
RxActivityResult.register(this);
}
}
You can call RxActivityResult.on(this).startIntent(intent)
supplying both, an Activity
instance or a Fragment
instance.
Observe the emitted Result item to know the resultCode and retrieve the associated data if appropriate.
Limitation:: Your fragments need to extend from android.support.v4.app.Fragment
instead of android.app.Fragment
, otherwise they won't be notified.
Intent takePhoto = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
RxActivityResult.on(this).startIntent(takePhoto)
.subscribe(result -> {
Intent data = result.data();
int resultCode = result.resultCode();
// the requestCode using which the activity is started can be received here.
int requestCode = result.requestCode();
if(requestCode == YourActivity.YOUR_REQUEST_CODE)
{
// Do Something
}
if (resultCode == RESULT_OK) {
result.targetUI().showImage(data);
} else {
result.targetUI().printUserCanceled();
}
});
Please pay attention to the targetUI()
method in the Result
object emitted.
This method returns a safety instance of the current Activity
/Fragment
. Because the original one may be recreated (due to configuration changes or some other system events) it would be unsafe calling it.
Instead, you must call any method/variable of your Activity
/Fragment
from this instance encapsulated in the Result
object.
RxActivityResult supports startIntentSenderForResult too, by calling RxActivityResult.on(this).startIntentSender
and supplying the proper arguments. As follows:
RxActivityResult.on(this).startIntentSender(pendingIntent.getIntentSender(), new Intent(), 0, 0, 0)
.subscribe(result -> {
});
There is an example of RxActivityResult using both activity and fragment in the app module
Víctor Albertos
- https://twitter.com/_victorAlbertos
- https://linkedin.com/in/victoralbertos
- https://github.com/VictorAlbertos
- RxCache: Reactive caching library for Android and Java.
- RxPaparazzo: RxJava extension for Android to take images using camera and gallery.
- RxFcm: RxJava extension for Android Firebase Cloud Messaging (aka fcm).