diff --git a/CHANGELOG.md b/CHANGELOG.md index 811235cb..2b5edcd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## Changelog +**2.5.0** +- Add video capture functionality + **2.4.0** - Add `getUri()` for convenient [#285](https://github.com/esafirm/android-image-picker/pull/285) - Fixes for Android Q [#290](https://github.com/esafirm/android-image-picker/pull/290) [#293](https://github.com/esafirm/android-image-picker/pull/293) diff --git a/README.md b/README.md index d304fdc6..39188a2e 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ +# Forked from: https://github.com/esafirm/android-image-picker + A simple library to select images from the gallery and camera. # Support Me! @@ -23,7 +25,7 @@ Would you help me achieving this goals? src="https://raw.githubusercontent.com/esafirm/android-image-picker/master/art/ss.gif" height="460" width="284"/> -## Download [![](https://jitpack.io/v/esafirm/android-image-picker.svg)](https://jitpack.io/#esafirm/android-image-picker) +## Download [![](https://jitpack.io/v/AhmedDroid/android-image-picker.svg)](https://jitpack.io/#AhmedDroid/android-image-picker) Add this to your project's `build.gradle` @@ -39,7 +41,7 @@ And add this to your module's `build.gradle` ```groovy dependencies { - implementation 'com.github.esafirm.android-image-picker:imagepicker:x.y.z' + implementation 'com.github.AhmedDroid:android-image-picker:x.y.z' // for experimental rx picker implementation 'com.github.esafirm.android-image-picker:rximagepicker:x.y.z' // If you have a problem with Glide, please use the same Glide version or simply open an issue @@ -47,7 +49,7 @@ dependencies { } ``` -change `x.y.z` to version in the [release page](https://github.com/esafirm/android-image-picker/releases) +change `x.y.z` to version in the [release page](https://github.com/AhmedDroid/android-image-picker/releases/) # Usage diff --git a/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePicker.java b/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePicker.java index e0c80caf..2e4e502f 100644 --- a/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePicker.java +++ b/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePicker.java @@ -117,6 +117,11 @@ public ImagePicker showCamera(boolean show) { return this; } + public ImagePicker showCamcorder(boolean show) { + config.setShowCamcorder(show); + return this; + } + public ImagePicker toolbarArrowColor(@ColorInt int color) { config.setArrowColor(color); return this; diff --git a/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerActivity.java b/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerActivity.java index e8b3e76e..62ff473c 100644 --- a/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerActivity.java +++ b/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerActivity.java @@ -104,6 +104,12 @@ public boolean onPrepareOptionsMenu(Menu menu) { menuDone.setTitle(ConfigUtils.getDoneButtonText(this, config)); menuDone.setVisible(imagePickerFragment.isShowDoneButton()); } + + MenuItem menuCamcorder = menu.findItem(R.id.menu_camcorder); + if (menuCamcorder != null) { + if (config != null) + menuCamcorder.setVisible(config.isShowCamcorder()); + } return super.onPrepareOptionsMenu(menu); } @@ -126,6 +132,10 @@ public boolean onOptionsItemSelected(MenuItem item) { imagePickerFragment.captureImageWithPermission(); return true; } + if (id == R.id.menu_camcorder) { + imagePickerFragment.captureVideoWithPermission(); + return true; + } return super.onOptionsItemSelected(item); } diff --git a/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerConfig.java b/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerConfig.java index 4c036638..dc654333 100644 --- a/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerConfig.java +++ b/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerConfig.java @@ -34,6 +34,7 @@ public class ImagePickerConfig extends BaseConfig implements Parcelable { private boolean onlyVideo; private boolean includeAnimation; private boolean showCamera; + private boolean showCamcorder; private transient String language; @@ -72,6 +73,14 @@ public void setShowCamera(boolean showCamera) { this.showCamera = showCamera; } + public boolean isShowCamcorder() { + return showCamcorder; + } + + public void setShowCamcorder(boolean showCamcorder) { + this.showCamcorder = showCamcorder; + } + public boolean isIncludeVideo() { return includeVideo; } @@ -202,6 +211,7 @@ public void writeToParcel(Parcel dest, int flags) { dest.writeByte(this.onlyVideo ? (byte) 1 : (byte) 0); dest.writeByte(this.includeAnimation ? (byte) 1 : (byte) 0); dest.writeByte(this.showCamera ? (byte) 1 : (byte) 0); + dest.writeByte(this.showCamcorder ? (byte) 1 : (byte) 0); } protected ImagePickerConfig(Parcel in) { @@ -226,6 +236,7 @@ protected ImagePickerConfig(Parcel in) { this.onlyVideo = in.readByte() != 0; this.includeAnimation = in.readByte() != 0; this.showCamera = in.readByte() != 0; + this.showCamcorder = in.readByte() != 0; } public static final Creator CREATOR = new Creator() { diff --git a/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerFragment.java b/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerFragment.java index 9429958e..0e7e9c26 100644 --- a/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerFragment.java +++ b/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerFragment.java @@ -434,6 +434,26 @@ public void captureImageWithPermission() { } } + /** + * Request for camcorder permission + */ + public void captureVideoWithPermission() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + final boolean isCameraGranted = ActivityCompat + .checkSelfPermission(getActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED; + final boolean isWriteGranted = ActivityCompat + .checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; + if (isCameraGranted && isWriteGranted) { + captureVideo(); + } else { + logger.w("Camera permission is not granted. Requesting permission"); + requestCameraPermissions(); + } + } else { + captureVideo(); + } + } + /** * Start camera intent * Create a temporary file and pass file Uri to camera intent @@ -445,6 +465,17 @@ private void captureImage() { presenter.captureImage(this, getBaseConfig(), RC_CAPTURE); } + /** + * Start camcorder intent + * Create a temporary file and pass file Uri to camcorder intent + */ + private void captureVideo() { + if (!CameraHelper.checkCameraAvailability(getActivity())) { + return; + } + presenter.captureVideo(this, getBaseConfig(), RC_CAPTURE); + } + private void startContentObserver() { if (isCameraOnly) { return; diff --git a/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerPresenter.java b/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerPresenter.java index b6ca81c4..b21d57a1 100644 --- a/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerPresenter.java +++ b/imagepicker/src/main/java/com/esafirm/imagepicker/features/ImagePickerPresenter.java @@ -111,6 +111,16 @@ void captureImage(Fragment fragment, BaseConfig config, int requestCode) { fragment.startActivityForResult(intent, requestCode); } + void captureVideo(Fragment fragment, BaseConfig config, int requestCode) { + Context context = fragment.getActivity().getApplicationContext(); + Intent intent = getCameraModule().getCamcorderIntent(fragment.getActivity(), config); + if (intent == null) { + Toast.makeText(context, context.getString(R.string.ef_error_create_image_file), Toast.LENGTH_LONG).show(); + return; + } + fragment.startActivityForResult(intent, requestCode); + } + void finishCaptureImage(Context context, Intent data, final BaseConfig config) { getCameraModule().getImage(context, data, images -> { if (ConfigUtils.shouldReturn(config, true)) { diff --git a/imagepicker/src/main/java/com/esafirm/imagepicker/features/camera/CameraModule.kt b/imagepicker/src/main/java/com/esafirm/imagepicker/features/camera/CameraModule.kt index c72bf2fa..ea096c3d 100644 --- a/imagepicker/src/main/java/com/esafirm/imagepicker/features/camera/CameraModule.kt +++ b/imagepicker/src/main/java/com/esafirm/imagepicker/features/camera/CameraModule.kt @@ -6,6 +6,7 @@ import com.esafirm.imagepicker.features.common.BaseConfig interface CameraModule { fun getCameraIntent(context: Context, config: BaseConfig): Intent? + fun getCamcorderIntent(context: Context, config: BaseConfig): Intent? fun getImage(context: Context, intent: Intent?, imageReadyListener: OnImageReadyListener?) fun removeImage() } \ No newline at end of file diff --git a/imagepicker/src/main/java/com/esafirm/imagepicker/features/camera/DefaultCameraModule.kt b/imagepicker/src/main/java/com/esafirm/imagepicker/features/camera/DefaultCameraModule.kt index 77b1b704..1a266b2d 100644 --- a/imagepicker/src/main/java/com/esafirm/imagepicker/features/camera/DefaultCameraModule.kt +++ b/imagepicker/src/main/java/com/esafirm/imagepicker/features/camera/DefaultCameraModule.kt @@ -45,6 +45,23 @@ class DefaultCameraModule : CameraModule, Serializable { return null } + override fun getCamcorderIntent(context: Context, config: BaseConfig): Intent? { + prepareForNewIntent() + + val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE) + val imageFile = ImagePickerUtils.createVideoFile(config.imageDirectory, context) + + if (imageFile != null) { + val appContext = context.applicationContext + val uri = createCamCorderUri(appContext, imageFile) + intent.putExtra(MediaStore.EXTRA_OUTPUT, uri) + ImagePickerUtils.grantAppPermission(context, intent, uri) + currentUri = uri.toString() + return intent + } + return null + } + private fun prepareForNewIntent() { currentImagePath = null currentUri = null @@ -64,6 +81,20 @@ class DefaultCameraModule : CameraModule, Serializable { return UriUtils.uriForFile(appContext, imageFile) } + private fun createCamCorderUri(appContext: Context, imageFile: File): Uri? { + currentImagePath = "file:" + imageFile.absolutePath + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + + val values = ContentValues().apply { + put(MediaStore.Images.Media.DISPLAY_NAME, imageFile.name) + put(MediaStore.Images.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, imageFile) + } + override fun getImage(context: Context, intent: Intent?, imageReadyListener: OnImageReadyListener?) { checkNotNull(imageReadyListener) { "OnImageReadyListener must not be null" } diff --git a/imagepicker/src/main/java/com/esafirm/imagepicker/helper/ImagePickerUtils.java b/imagepicker/src/main/java/com/esafirm/imagepicker/helper/ImagePickerUtils.java index cb7a1e5e..af037138 100644 --- a/imagepicker/src/main/java/com/esafirm/imagepicker/helper/ImagePickerUtils.java +++ b/imagepicker/src/main/java/com/esafirm/imagepicker/helper/ImagePickerUtils.java @@ -69,6 +69,21 @@ public static File createImageFile(ImagePickerSavePath savePath, Context context return result; } + public static File createVideoFile(ImagePickerSavePath savePath, Context context) { + final File mediaStorageDir = createFileInDirectory(savePath, context); + if (mediaStorageDir == null) return null; + + // Create a media file name + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss_SSS", Locale.getDefault()).format(new Date()); + File result = new File(mediaStorageDir, "VID_" + timeStamp + ".mp4"); + int counter = 0; + while (result.exists()) { + counter++; + result = new File(mediaStorageDir, "VID_" + timeStamp + "(" + counter + ").mp4"); + } + return result; + } + public static String getNameFromFilePath(String path) { if (path.contains(File.separator)) { return path.substring(path.lastIndexOf(File.separator) + 1); diff --git a/imagepicker/src/main/res/drawable-anydpi/ef_ic_camcorder.xml b/imagepicker/src/main/res/drawable-anydpi/ef_ic_camcorder.xml new file mode 100644 index 00000000..a7ff5089 --- /dev/null +++ b/imagepicker/src/main/res/drawable-anydpi/ef_ic_camcorder.xml @@ -0,0 +1,11 @@ + + + diff --git a/imagepicker/src/main/res/drawable-hdpi/ef_ic_camcorder.png b/imagepicker/src/main/res/drawable-hdpi/ef_ic_camcorder.png new file mode 100644 index 00000000..836b53b4 Binary files /dev/null and b/imagepicker/src/main/res/drawable-hdpi/ef_ic_camcorder.png differ diff --git a/imagepicker/src/main/res/drawable-mdpi/ef_ic_camcorder.png b/imagepicker/src/main/res/drawable-mdpi/ef_ic_camcorder.png new file mode 100644 index 00000000..cd192cda Binary files /dev/null and b/imagepicker/src/main/res/drawable-mdpi/ef_ic_camcorder.png differ diff --git a/imagepicker/src/main/res/drawable-xhdpi/ef_ic_camcorder.png b/imagepicker/src/main/res/drawable-xhdpi/ef_ic_camcorder.png new file mode 100644 index 00000000..8a5f8e36 Binary files /dev/null and b/imagepicker/src/main/res/drawable-xhdpi/ef_ic_camcorder.png differ diff --git a/imagepicker/src/main/res/drawable-xxhdpi/ef_ic_camcorder.png b/imagepicker/src/main/res/drawable-xxhdpi/ef_ic_camcorder.png new file mode 100644 index 00000000..fdff1f3a Binary files /dev/null and b/imagepicker/src/main/res/drawable-xxhdpi/ef_ic_camcorder.png differ diff --git a/imagepicker/src/main/res/menu/ef_image_picker_menu_main.xml b/imagepicker/src/main/res/menu/ef_image_picker_menu_main.xml index f8b8aa31..c7da545f 100644 --- a/imagepicker/src/main/res/menu/ef_image_picker_menu_main.xml +++ b/imagepicker/src/main/res/menu/ef_image_picker_menu_main.xml @@ -9,6 +9,13 @@ app:showAsAction="always" tools:ignore="AlwaysShowAction"/> + + إخترت %d إخترت %1$d/%2$d - حدث خطأ في تسجيل الصوره + حدث خطأ في إنشاء الصوره + حدث خطأ في إنشاء الفيديو لا يوجد كاميرا عذراً، هناك خطأ ما! diff --git a/imagepicker/src/main/res/values-da/strings.xml b/imagepicker/src/main/res/values-da/strings.xml index 1955e0fd..96aea109 100644 --- a/imagepicker/src/main/res/values-da/strings.xml +++ b/imagepicker/src/main/res/values-da/strings.xml @@ -14,6 +14,7 @@ %1$d/%2$d valgt Fejl, kunne ikke oprette billedfilen + Failed to create Video file Kamera blev ikke fundet Beklager, der er sket en fejl! diff --git a/imagepicker/src/main/res/values-de/strings.xml b/imagepicker/src/main/res/values-de/strings.xml index f3d51ffc..e41e1b75 100644 --- a/imagepicker/src/main/res/values-de/strings.xml +++ b/imagepicker/src/main/res/values-de/strings.xml @@ -14,6 +14,7 @@ %1$d/%2$d ausgewählt Fehler beim Erstellen der Bilddatei + Failed to create Video file Keine Kamera gefunden Ups, da ist was schiefgegangen! diff --git a/imagepicker/src/main/res/values-fr/strings.xml b/imagepicker/src/main/res/values-fr/strings.xml index 90a7407a..9cbe3f5a 100644 --- a/imagepicker/src/main/res/values-fr/strings.xml +++ b/imagepicker/src/main/res/values-fr/strings.xml @@ -14,6 +14,7 @@ %1$d/%2$d sélectionnées Impossible de créer le fichier photo + Échec de la création du fichier vidéo Aucune caméra détectée Oups, quelque chose s\'est mal déroulé! diff --git a/imagepicker/src/main/res/values-in/strings.xml b/imagepicker/src/main/res/values-in/strings.xml index 5a4806fe..d60f0ca1 100644 --- a/imagepicker/src/main/res/values-in/strings.xml +++ b/imagepicker/src/main/res/values-in/strings.xml @@ -13,7 +13,8 @@ %d terpilih %1$d/%2$d terpilih - Gagal membuat berkas gambar + Gagal membuat file Gambar + Gagal membuat file Video Kamera tidak ditemukan Ups, ada yang tidak beres! diff --git a/imagepicker/src/main/res/values-it/strings.xml b/imagepicker/src/main/res/values-it/strings.xml index 6db39f2a..17497cef 100644 --- a/imagepicker/src/main/res/values-it/strings.xml +++ b/imagepicker/src/main/res/values-it/strings.xml @@ -13,6 +13,7 @@ %1$d/%2$d selezionate Si è verificato un problema nella creazione dell\'immagine + Si è verificato un problema nella creazione dell\'video Nessuna fotocamera trovata Oops, qualcosa è andato storto! diff --git a/imagepicker/src/main/res/values-ko/strings.xml b/imagepicker/src/main/res/values-ko/strings.xml index db37f48b..f9c65f86 100644 --- a/imagepicker/src/main/res/values-ko/strings.xml +++ b/imagepicker/src/main/res/values-ko/strings.xml @@ -14,6 +14,7 @@ %1$d/%2$d 선택됨 이미지 생성에 실패하였습니다. + 비디오 파일을 생성하지 못했습니다. 카메라를 찾을 수 없습니다. 알 수 없는 오류가 발생하였습니다. diff --git a/imagepicker/src/main/res/values-pt-rBR/strings.xml b/imagepicker/src/main/res/values-pt-rBR/strings.xml index 02860b5c..c5668aef 100644 --- a/imagepicker/src/main/res/values-pt-rBR/strings.xml +++ b/imagepicker/src/main/res/values-pt-rBR/strings.xml @@ -14,6 +14,7 @@ %1$d/%2$d selecionadas Erro ao criar arquivo de imagem + Falha ao criar arquivo de vídeo Câmera não encontrada Ops, algo deu errado! diff --git a/imagepicker/src/main/res/values-ro/strings.xml b/imagepicker/src/main/res/values-ro/strings.xml index 65a4e439..82a79070 100644 --- a/imagepicker/src/main/res/values-ro/strings.xml +++ b/imagepicker/src/main/res/values-ro/strings.xml @@ -13,6 +13,7 @@ %1$d/%2$d selectate Nu am putut crea imaginea + Nu s-a putut crea fișierul video Camera foto nu a fost găsită Hopa, ceva a mers prost! diff --git a/imagepicker/src/main/res/values-ru/strings.xml b/imagepicker/src/main/res/values-ru/strings.xml index c8039f46..173e2988 100644 --- a/imagepicker/src/main/res/values-ru/strings.xml +++ b/imagepicker/src/main/res/values-ru/strings.xml @@ -10,6 +10,7 @@ %d выбрано %1$d/%2$d выбрано Не удалось создать файл + Не удалось создать видео файл Камера недоступна Ой! Что-то пошло не так! Изображений не найдено diff --git a/imagepicker/src/main/res/values-tr/strings.xml b/imagepicker/src/main/res/values-tr/strings.xml index ae9aa89c..f9c5686e 100644 --- a/imagepicker/src/main/res/values-tr/strings.xml +++ b/imagepicker/src/main/res/values-tr/strings.xml @@ -13,6 +13,7 @@ %1$d/%2$d seçili Resim dosyası oluşturulamadı + Video dosyası oluşturulamadı Kamera bulunamadı Hoop! Birşeyler yanlış gitti! diff --git a/imagepicker/src/main/res/values-uk/strings.xml b/imagepicker/src/main/res/values-uk/strings.xml index a2a84e6c..55cf3417 100644 --- a/imagepicker/src/main/res/values-uk/strings.xml +++ b/imagepicker/src/main/res/values-uk/strings.xml @@ -10,6 +10,7 @@ %d обрано %1$d/%2$d обрано Не вдалося створити файл + Не вдалося створити відеофайл Камера недоступна Ой! Щось пішло не так! Зображень не знайдено diff --git a/imagepicker/src/main/res/values-zh-rCN/strings.xml b/imagepicker/src/main/res/values-zh-rCN/strings.xml index 950a7999..e9b3c13b 100644 --- a/imagepicker/src/main/res/values-zh-rCN/strings.xml +++ b/imagepicker/src/main/res/values-zh-rCN/strings.xml @@ -12,6 +12,7 @@ 已选择 %1$d/%2$d 建立照片文件失败 + 创建视频文件失败 找不到相机 啊哦,发生错误! diff --git a/imagepicker/src/main/res/values-zh-rTW/strings.xml b/imagepicker/src/main/res/values-zh-rTW/strings.xml index 2392a5ef..a6107361 100644 --- a/imagepicker/src/main/res/values-zh-rTW/strings.xml +++ b/imagepicker/src/main/res/values-zh-rTW/strings.xml @@ -12,6 +12,7 @@ 已選擇 %1$d/%2$d 建立相片檔案失敗 + 創建視頻文件失敗 找不到相機 噢,發生問題 diff --git a/imagepicker/src/main/res/values/strings.xml b/imagepicker/src/main/res/values/strings.xml index b8d66c80..9255a652 100644 --- a/imagepicker/src/main/res/values/strings.xml +++ b/imagepicker/src/main/res/values/strings.xml @@ -14,6 +14,7 @@ %1$d/%2$d selected Failed to create image file + Failed to create Video file No camera found Oops, something went wrong! diff --git a/sample/src/main/java/com/esafirm/sample/CustomUIActivity.kt b/sample/src/main/java/com/esafirm/sample/CustomUIActivity.kt index 876c7b9d..32ba2b45 100644 --- a/sample/src/main/java/com/esafirm/sample/CustomUIActivity.kt +++ b/sample/src/main/java/com/esafirm/sample/CustomUIActivity.kt @@ -113,6 +113,10 @@ class CustomUIActivity : AppCompatActivity() { imagePickerFragment.captureImageWithPermission() return true } + if (id == com.esafirm.imagepicker.R.id.menu_camcorder) { + imagePickerFragment.captureVideoWithPermission() + return true + } return super.onOptionsItemSelected(item) }