Android Sdk ≥ 14
Minimum Dependencies
Simple reactive library for pick image or video. There are Rx Java 1, 2, 3 and Coroutines implementation.
Usage such a simple. Next example returns Observable<Uri>
(RxJava1), Maybe<Uri>
(RxJava2), Maybe<Uri>
(RxJava3), Flow<Uri>
(Coroutines)
MediaPicker.builder()
.pick(Purpose.Pick.Image)
.take(Purpose.Take.Video)
.build()
Under the hood purposes combines into available Intents list and user see chooser (or doesn't see if there is only one app available). After finishing stream emits result or completes.
Pick means that you will get media from storage. Available Pick.Image
and Pick.Video
options
Take means that you will capture media with camera. Available Take.Photo
and Take.Video
options
If there needs a kind of customization you can pass options to builder
<builder>
.setTakeVideoOptions(<VideoOptions>)
.setImageOptions(<ImageOptions>)
VideoOptions
and PhotoOptions
are data classes to customize camera Intent
data class VideoOptions @JvmOverloads constructor(
val maxDuration: Duration = (-1).milliseconds,
val maxSize: MemorySize = MemorySize(size = -1, unit = SizeUnit.BYTE),
val quality: VideoQuality = VideoQuality.HIGH
)
data class PhotoOptions @JvmOverloads constructor(
val maxResolution: Resolution = Resolution(width = -1 /* px */, height = -1 /* px */),
val maxSize: MemorySize = MemorySize(size = -1, unit = SizeUnit.BYTE)
)
You can leave default values for any parameter or pass nothing to builder. Then this parameters just won't be applied in processing.
Note that ImageOptions
applies for both Pick
and Take
purposes, but VideoOptions applies only to Take.Video
purpose. Pick.Video
not customizable. Maybe later it will be changed.
If there are few options to get media then will be shown BottomSheet chooser for app. Default title is "Choose an application"
, but you can override it (for l10n, for example) with
<builder>.setChooserTitle(R.string.whatever_title_you_want)
When you pass to builder both Take.Photo
and Take.Video
purposes, you can see title "Camera" twice. Its weird, but it is correct, because it is different intents. To avoid this added possibility to customize these titles.
<builder>
.setTakePhotoAppChooserTitle(R.string.whatever_title_you_want)
.setTakeVideoAppChooserTitle(R.string.whatever_title_you_want_2)
Every title can be set as a String
or as a resource. If you want to see camera app title, you must pass null
as title.
There are provides two callbacks
- When user dismissed picker activity
<builder>.onDismissPick(<OnDismissListener>)
- When user dismissed select app chooser
<builder>.onDismissAppSelect(<OnDismissListener>)
Both are OnDismissListener
which are functional interface with only one method void onDismiss()
. It can be helpful (for example) if you show ProgressBar
to user, but he just closes picker activity without completes his choice.
3. On permissions result (If you need add reaction wnen permissions granted or denied)
<builder>.setPermissionResultHandler(<PermissionsHandler>)
interface PermissionsHandler {
fun onRequestPermissionsResult(result: PermissionResult) = Unit
fun onRequestPermissionsFailed(throwable: Throwable) = Unit
}
data class PermissionResult(
val granted: List<String> = emptyList(),
val notGranted: List<String> = emptyList(),
val foreverDenied: List<String> = emptyList()
)
For streams also provided transformers
file() // Converts Uri to File
filepath() // Converts Uri to String (file location)
bitmap() // Converts Uri to Bitmap
All of these realized as global functions. In Java can be used as static functions of class UriTransformers
MediaPicker.builder()
.setImageOptions(
ImageOptions(
maxResolution = Resolution(3000, 3000),
maxSize = MemorySize(size = 3, unit = SizeUnit.MEGABYTE)
))
.pick(Purpose.Take.Image)
.build()
.request(this /* context */ )
.compose(file())
.subscribe { file : File -> }
--- OR ---
MediaPicker.builder()
.setChooserTitle("Select video source")
.setTakeVideoOptions(VideoOptions(duration = 10.toSeconds(), quality = VideoQuality.HIGH))
.take(Purpose.Take.Video)
.request(this /* context */ )
.subscribe { uri : Uri -> showVideo(uri) }
Also examples available in demo application Code
Since Android N (Api 24) needs fileprovider
for correct saving and using photo. setup your project you must to do next:
- Add file with {name of file provider descriptor file} (for example
my_paths.xml
) inres/xml
folder. Note than in manifest this filename uses without extension ".xml", just like@xml/my_paths
File contains next:
<paths>
<external-path
name="my_images"
path="Android/data/{name of package of your app}/files/Pictures" />
</paths>
- Add provider to your
AndroidManifest.xml
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="{name of package of your app}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/**{name of file provider descriptor file}**" />
</provider>
Add core (each case)
implementation "io.github.iamthevoid.mediapicker:core:1.1.2"
And then:
RxJava 1
implementation "io.github.iamthevoid.mediapicker:rx1:1.1.2"
RxJava 2
implementation "io.github.iamthevoid.mediapicker:rx2:1.1.2"
RxJava 3
implementation "io.github.iamthevoid.mediapicker:rx3:1.1.2"
Coroutines
implementation "io.github.iamthevoid.mediapicker:coroutines:1.1.2"