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/#esafirm/android-image-picker)
+## Download [](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)
}