Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: Start video recording on camera icon clicked when "OnlyVideo" is enabled #411

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ class ImagePickerActivity : AppCompatActivity(), ImagePickerInteractionListener

override fun onPrepareOptionsMenu(menu: Menu): Boolean {
if (!isCameraOnly) {
menu.findItem(R.id.menu_camera).isVisible = config?.isShowCamera ?: true
menu.findItem(R.id.menu_camera).isVisible =
config?.isShowCamera == true && config?.isOnlyVideo == false
menu.findItem(R.id.menu_video).isVisible = config?.isShowVideo ?: true
menu.findItem(R.id.menu_done).apply {
title = ConfigUtils.getDoneButtonText(this@ImagePickerActivity, config!!)
isVisible = imagePickerFragment.isShowDoneButton
Expand All @@ -113,6 +115,10 @@ class ImagePickerActivity : AppCompatActivity(), ImagePickerInteractionListener
imagePickerFragment.captureImage()
return true
}
if (id == R.id.menu_video) {
imagePickerFragment.captureVideo()
return true
}
return super.onOptionsItemSelected(item)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ interface ImagePickerComponents {
val imageLoader: ImageLoader
val imageFileLoader: ImageFileLoader
val cameraModule: CameraModule
val videoModule: CameraModule
esafirm marked this conversation as resolved.
Show resolved Hide resolved
esafirm marked this conversation as resolved.
Show resolved Hide resolved
}

open class DefaultImagePickerComponents(context: Context) : ImagePickerComponents {
override val appContext: Context = context.applicationContext
override val imageLoader: ImageLoader by lazy { DefaultImageLoader() }
override val imageFileLoader: ImageFileLoader by lazy { DefaultImageFileLoader(context.applicationContext) }
override val cameraModule: CameraModule by lazy { DefaultCameraModule() }
override val videoModule: CameraModule by lazy { DefaultCameraModule() }
}

object ImagePickerComponentsHolder : ImagePickerComponents {
Expand All @@ -38,6 +40,9 @@ object ImagePickerComponentsHolder : ImagePickerComponents {
override val cameraModule: CameraModule
get() = internalComponents.cameraModule

override val videoModule: CameraModule
get() = internalComponents.videoModule

fun setInternalComponent(components: ImagePickerComponents) {
internalComponents = components
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ class ImagePickerConfig(
var isOnlyVideo: Boolean = false,
var isIncludeAnimation: Boolean = false,
var isShowCamera: Boolean = true,
var isShowVideo: Boolean = true,
esafirm marked this conversation as resolved.
Show resolved Hide resolved
var selectedImages: List<Image> = emptyList(),
var excludedImages: List<File> = emptyList(),
override var savePath: ImagePickerSavePath = ImagePickerSavePath.DEFAULT,
override var returnMode: ReturnMode = ReturnMode.NONE,
override var isSaveImage: Boolean = true,
override var isSaveVideo: Boolean = true,
var showDoneButtonAlways: Boolean = false
) : BaseConfig(), Parcelable {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,18 @@ class ImagePickerFragment : Fragment() {
if (!checkCameraAvailability(requireActivity())) {
return
}
presenter.captureImage(this, config, RC_CAPTURE)
if (config.isOnlyVideo) {
presenter.captureVideo(this, config, RC_CAPTURE)
} else{
esafirm marked this conversation as resolved.
Show resolved Hide resolved
presenter.captureImage(this, config, RC_CAPTURE)
}
}

fun captureVideo() {
if (!checkCameraAvailability(requireActivity())) {
return
}
presenter.captureVideo(this, config, RC_CAPTURE)
}

override fun onDestroy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal class ImagePickerPresenter(
) : ImagePickerAction {

private val cameraModule: CameraModule = ImagePickerComponentsHolder.cameraModule

private val videoModule: CameraModule = ImagePickerComponentsHolder.videoModule
private val stateObs = LiveDataObservableState(
ImagePickerState(isLoading = true),
usePostValue = true
Expand Down Expand Up @@ -95,6 +95,20 @@ internal class ImagePickerPresenter(
fragment.startActivityForResult(intent, requestCode)
}

fun captureVideo(fragment: Fragment, config: BaseConfig, requestCode: Int) {
val context = fragment.requireContext().applicationContext
val intent = videoModule.getVideoIntent(fragment.requireContext(), config)
esafirm marked this conversation as resolved.
Show resolved Hide resolved
if (intent == null) {
Toast.makeText(
context,
context.getString(R.string.ef_error_create_image_file),
esafirm marked this conversation as resolved.
Show resolved Hide resolved
Toast.LENGTH_LONG
).show()
return
}
fragment.startActivityForResult(intent, requestCode)
}

fun finishCaptureImage(context: Context, data: Intent?, config: BaseConfig?) {
cameraModule.getImage(context, data) { images ->
if (ConfigUtils.shouldReturn(config!!, true)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ typealias OnImageReadyListener = (List<Image>?) -> Unit

interface CameraModule {
fun getCameraIntent(context: Context, config: BaseConfig): Intent?
fun getVideoIntent(context: Context, config: BaseConfig): Intent?
esafirm marked this conversation as resolved.
Show resolved Hide resolved
fun getImage(context: Context, intent: Intent?, imageReadyListener: OnImageReadyListener)
fun removeImage(context: Context)
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ class DefaultCameraModule : CameraModule {
return intent
}

override fun getVideoIntent(context: Context, config: BaseConfig): Intent? {
prepareForNewIntent()

val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
val imageFile = ImagePickerUtils.createVideoFile(config.savePath, context)

if (config.isSaveVideo && imageFile != null) {
val appContext = context.applicationContext
val uri = createVideoUri(appContext, imageFile)
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
ImagePickerUtils.grantAppPermission(context, intent, uri)
currentUri = uri.toString()
}
return intent
}

private fun prepareForNewIntent() {
currentImagePath = null
currentUri = null
Expand All @@ -55,6 +71,21 @@ class DefaultCameraModule : CameraModule {
return UriUtils.uriForFile(appContext, imageFile)
}

private fun createVideoUri(appContext: Context, videoFile: File): Uri? {
currentImagePath = "file:" + videoFile.absolutePath
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

val values = ContentValues().apply {
put(MediaStore.Video.Media.DISPLAY_NAME, videoFile.name)
put(MediaStore.Video.Media.MIME_TYPE, "video/mp4")
}
val collection =
MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
return appContext.contentResolver.insert(collection, values)
}
return UriUtils.uriForFile(appContext, videoFile)
}

override fun getImage(
context: Context,
intent: Intent?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ import kotlinx.android.parcel.Parcelize
class CameraOnlyConfig(
override var savePath: ImagePickerSavePath = ImagePickerSavePath.DEFAULT,
override var returnMode: ReturnMode = ReturnMode.ALL,
override var isSaveImage: Boolean = true
override var isSaveImage: Boolean = true,
override var isSaveVideo: Boolean = true
) : BaseConfig(), Parcelable
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ abstract class BaseConfig {
abstract var savePath: ImagePickerSavePath
abstract var returnMode: ReturnMode
abstract var isSaveImage: Boolean
abstract var isSaveVideo: Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,27 @@ object ImagePickerUtils {
return mediaStorageDir
}

private fun createFileInDirectoryVideo(savePath: ImagePickerSavePath, context: Context): File? {
val path = savePath.path
val mediaStorageDir: File = if (savePath.isRelative) {
val parent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
context.getExternalFilesDir(Environment.DIRECTORY_MOVIES)
} else {
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)
}
File(parent, path)
} else {
File(path)
}
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
d("Oops! Failed create $path")
return null
}
}
return mediaStorageDir
}

fun createImageFile(savePath: ImagePickerSavePath, context: Context): File? {
val mediaStorageDir = createFileInDirectory(savePath, context) ?: return null

Expand All @@ -62,6 +83,18 @@ object ImagePickerUtils {
return result
}

fun createVideoFile(savePath: ImagePickerSavePath, context: Context): File? {
val mediaStorageDir = createFileInDirectoryVideo(savePath, context) ?: return null
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss_SSS", Locale.getDefault()).format(Date())
var result = File(mediaStorageDir, "VID_$timeStamp.mp4")
var counter = 0
while (result.exists()) {
counter++
result = File(mediaStorageDir, "VID_$timeStamp($counter).mp4")
}
return result
}

fun getNameFromFilePath(path: String): String {
return if (path.contains(File.separator)) {
path.substring(path.lastIndexOf(File.separator) + 1)
Expand Down
12 changes: 12 additions & 0 deletions imagepicker/src/main/res/drawable/ef_video_placeholder.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#FFFFFF"
android:alpha="1.0">
<path
android:fillColor="#FFFFFF"
android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z"/>
</vector>
6 changes: 6 additions & 0 deletions imagepicker/src/main/res/menu/ef_image_picker_menu_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
app:showAsAction="always"
tools:ignore="AlwaysShowAction" />

<item
android:id="@+id/menu_video"
android:icon="@drawable/ef_video_placeholder"
android:title="@string/ef_video"
app:showAsAction="always"/>

<item
android:id="@+id/menu_done"
android:title="@string/ef_done"
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-ar/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="ef_ok">وافق</string>
<string name="ef_done">انهي</string>
<string name="ef_camera">كاميرا</string>
<string name="ef_video">فيديو</string>

<string name="ef_title_folder">دليل</string>
<string name="ef_title_select_image">أنقر لإختيار الصور</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-ca/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="ef_ok">OK</string>
<string name="ef_done">FET</string>
<string name="ef_camera">CÀMERA</string>
<string name="ef_video">VÍDEO</string>

<string name="ef_title_folder">Carpeta</string>
<string name="ef_title_select_image">Toqueu per seleccionar imatges</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-da/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="ef_ok">Ok</string>
<string name="ef_done">Færdig</string>
<string name="ef_camera">Kamera</string>
<string name="ef_video">VIDEO</string>

<string name="ef_title_folder">Mappe</string>
<string name="ef_title_select_image">Tryk for at vælge billeder</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="ef_ok">OK</string>
<string name="ef_done">FERTIG</string>
<string name="ef_camera">KAMERA</string>
<string name="ef_video">VIDEO</string>

<string name="ef_title_folder">Verzeichnis</string>
<string name="ef_title_select_image">Tippen um Bilder auszuwählen</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-es-rES/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="ef_ok">OK</string>
<string name="ef_done">HECHO</string>
<string name="ef_camera">CÁMARA</string>
<string name="ef_video">VIDEO</string>

<string name="ef_title_folder">Carpeta</string>
<string name="ef_title_select_image">Toque para seleccionar imágenes</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="ef_ok">OK</string>
<string name="ef_done">TERMINER</string>
<string name="ef_camera">CAMERA</string>
<string name="ef_video">VIDÉO</string>

<string name="ef_title_folder">Dossier</string>
<string name="ef_title_select_image">Toucher pour sélectionner des images</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-in/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="ef_ok">OK</string>
<string name="ef_done">SELESAI</string>
<string name="ef_camera">KAMERA</string>
<string name="ef_video">VIDEO</string>

<string name="ef_title_folder">Folder</string>
<string name="ef_title_select_image">Ketuk untuk memilih gambar</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-it/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="ef_ok">OK</string>
<string name="ef_done">FATTO</string>
<string name="ef_camera">CAMERA</string>
<string name="ef_video">VIDEO</string>

<string name="ef_title_folder">Cartella</string>
<string name="ef_title_select_image">Premi per selezionare l\'immagine</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-ja/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<string name="ef_ok">OK</string>
<string name="ef_done">完了</string>
<string name="ef_camera">カメラ</string>
<string name="ef_video">ビデオ</string>

<string name="ef_title_folder">フォルダ</string>
<string name="ef_title_select_image">画像を選択</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-ko/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="ef_ok">확인</string>
<string name="ef_done">완료</string>
<string name="ef_camera">카메라</string>
<string name="ef_video">동영상</string>

<string name="ef_title_folder">사진첩</string>
<string name="ef_title_select_image">이미지를 선택하세요</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-pt-rBR/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="ef_ok">OK</string>
<string name="ef_done">FEITO</string>
<string name="ef_camera">CAMERA</string>
<string name="ef_video">VÍDEO</string>

<string name="ef_title_folder">Pasta</string>
<string name="ef_title_select_image">Toque para selecionar as imagens</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-ro/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="ef_ok">OK</string>
<string name="ef_done">TERMINAT</string>
<string name="ef_camera">CAMERA</string>
<string name="ef_video">VIDEO</string>

<string name="ef_title_folder">Fișier</string>
<string name="ef_title_select_image">Atingeți pentru a selecta imagini</string>
Expand Down
2 changes: 2 additions & 0 deletions imagepicker/src/main/res/values-ru/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<string name="ef_ok">ОК</string>
<string name="ef_done">ГОТОВО</string>
<string name="ef_camera">КАМЕРА</string>
<string name="ef_video">ВИДЕО</string>

<string name="ef_title_folder">Папка</string>
<string name="ef_title_select_image">Коснитесь, чтобы выбрать</string>
<string name="ef_ltitle_permission_denied">Доступ запрещён</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-sv-rSE/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<string name="ef_ok">OK</string>
<string name="ef_done">KLAR</string>
<string name="ef_camera">KAMERA</string>
<string name="ef_video">VIDEO</string>

<string name="ef_title_folder">Mapp</string>
<string name="ef_title_select_image">Tryck för att välja bilder</string>
Expand Down
2 changes: 2 additions & 0 deletions imagepicker/src/main/res/values-tr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
<string name="ef_ok">TAMAM</string>
<string name="ef_done">BİTTİ</string>
<string name="ef_camera">KAMERA</string>
<string name="ef_video">VİDEO</string>

<string name="ef_permission_write_external_rationale">Görüntüleri seçmek için harici depolama alanına erişime izin ver</string>

<string name="ef_title_folder">Klasör</string>
Expand Down
2 changes: 2 additions & 0 deletions imagepicker/src/main/res/values-uk/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<string name="ef_ok">ОК</string>
<string name="ef_done">ГОТОВО</string>
<string name="ef_camera">КАМЕРА</string>
<string name="ef_video">ВІДЕО</string>

<string name="ef_title_folder">Папка</string>
<string name="ef_title_select_image">Торкніться, щоб обрати</string>
<string name="ef_ltitle_permission_denied">Доступ заборонено</string>
Expand Down
1 change: 1 addition & 0 deletions imagepicker/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<string name="ef_ok">好</string>
<string name="ef_done">完成</string>
<string name="ef_camera">相机</string>
<string name="ef_video">视频</string>

<string name="ef_title_folder">文件夹</string>
<string name="ef_title_select_image">选择照片</string>
Expand Down
Loading