diff --git a/library/src/main/java/pl/aprilapps/easyphotopicker/Constants.kt b/library/src/main/java/pl/aprilapps/easyphotopicker/Constants.kt index 0f1be6f..689d54b 100644 --- a/library/src/main/java/pl/aprilapps/easyphotopicker/Constants.kt +++ b/library/src/main/java/pl/aprilapps/easyphotopicker/Constants.kt @@ -17,4 +17,7 @@ internal object RequestCodes { const val PICK_PICTURE_FROM_CHOOSER = 34963 const val TAKE_PICTURE = 34964 const val CAPTURE_VIDEO = 34965 + const val PICK_VIDEO_FROM_DOCUMENTS = 34966 + const val PICK_VIDEO_FROM_GALLERY = 34967 + const val PICK_VIDEO_FROM_CHOOSER = 34968 } \ No newline at end of file diff --git a/library/src/main/java/pl/aprilapps/easyphotopicker/EasyImage.kt b/library/src/main/java/pl/aprilapps/easyphotopicker/EasyImage.kt index 0173919..459c054 100644 --- a/library/src/main/java/pl/aprilapps/easyphotopicker/EasyImage.kt +++ b/library/src/main/java/pl/aprilapps/easyphotopicker/EasyImage.kt @@ -83,6 +83,27 @@ class EasyImage private constructor( } } + private fun startVideoChooser(caller: Any) { + cleanup() + getCallerActivity(caller)?.let { activityCaller -> + try { + lastCameraFile = Files.createCameraVideoFile(context) + save() + val intent = Intents.createVideoChooserIntent( + context = activityCaller.context, + chooserTitle = chooserTitle, + chooserType = chooserType, + cameraFileUri = lastCameraFile!!.uri, + allowMultiple = allowMultiple + ) + activityCaller.startActivityForResult(intent, RequestCodes.PICK_VIDEO_FROM_CHOOSER) + } catch (error: IOException) { + error.printStackTrace() + cleanup() + } + } + } + private fun startDocuments(caller: Any) { cleanup() getCallerActivity(caller)?.let { activityCaller -> @@ -91,6 +112,14 @@ class EasyImage private constructor( } } + private fun startVideoDocuments(caller: Any) { + cleanup() + getCallerActivity(caller)?.let { activityCaller -> + val intent = Intents.createVideoDocumentsIntent(allowMultiple) + activityCaller.startActivityForResult(intent, RequestCodes.PICK_VIDEO_FROM_DOCUMENTS) + } + } + private fun startGallery(caller: Any) { cleanup() getCallerActivity(caller)?.let { activityCaller -> @@ -99,6 +128,14 @@ class EasyImage private constructor( } } + private fun startVideoGallery(caller: Any) { + cleanup() + getCallerActivity(caller)?.let { activityCaller -> + val intent = Intents.createVideoGalleryIntent(allowMultiple) + activityCaller.startActivityForResult(intent, RequestCodes.PICK_VIDEO_FROM_GALLERY) + } + } + private fun startCameraForImage(caller: Any) { cleanup() getCallerActivity(caller)?.let { activityCaller -> @@ -137,12 +174,21 @@ class EasyImage private constructor( fun openChooser(activity: Activity) = startChooser(activity) fun openChooser(fragment: Fragment) = startChooser(fragment) fun openChooser(fragment: android.app.Fragment) = startChooser(fragment) + fun openVideoChooser(activity: Activity) = startVideoChooser(activity) + fun openVideoChooser(fragment: Fragment) = startVideoChooser(fragment) + fun openVideoChooser(fragment: android.app.Fragment) = startVideoChooser(fragment) fun openDocuments(activity: Activity) = startDocuments(activity) fun openDocuments(fragment: Fragment) = startDocuments(fragment) fun openDocuments(fragment: android.app.Fragment) = startDocuments(fragment) + fun openVideoDocuments(activity: Activity) = startVideoDocuments(activity) + fun openVideoDocuments(fragment: Fragment) = startVideoDocuments(fragment) + fun openVideoDocuments(fragment: android.app.Fragment) = startVideoDocuments(fragment) fun openGallery(activity: Activity) = startGallery(activity) fun openGallery(fragment: Fragment) = startGallery(fragment) fun openGallery(fragment: android.app.Fragment) = startGallery(fragment) + fun openVideoGallery(activity: Activity) = startVideoGallery(activity) + fun openVideoGallery(fragment: Fragment) = startVideoGallery(fragment) + fun openVideoGallery(fragment: android.app.Fragment) = startVideoGallery(fragment) fun openCameraForImage(activity: Activity) = startCameraForImage(activity) fun openCameraForImage(fragment: Fragment) = startCameraForImage(fragment) fun openCameraForImage(fragment: android.app.Fragment) = startCameraForImage(fragment) @@ -152,13 +198,13 @@ class EasyImage private constructor( fun handleActivityResult(requestCode: Int, resultCode: Int, resultIntent: Intent?, activity: Activity, callbacks: Callbacks) { // EasyImage request codes are set to be between 374961 and 374965. - if (requestCode !in 34961..34965) return + if (requestCode !in 34961..34968) return restore() val mediaSource = when (requestCode) { - RequestCodes.PICK_PICTURE_FROM_DOCUMENTS -> MediaSource.DOCUMENTS - RequestCodes.PICK_PICTURE_FROM_GALLERY -> MediaSource.GALLERY + RequestCodes.PICK_PICTURE_FROM_DOCUMENTS, RequestCodes.PICK_VIDEO_FROM_DOCUMENTS -> MediaSource.DOCUMENTS + RequestCodes.PICK_PICTURE_FROM_GALLERY, RequestCodes.PICK_VIDEO_FROM_GALLERY -> MediaSource.GALLERY RequestCodes.TAKE_PICTURE -> MediaSource.CAMERA_IMAGE RequestCodes.CAPTURE_VIDEO -> MediaSource.CAMERA_VIDEO else -> MediaSource.CHOOSER @@ -175,7 +221,13 @@ class EasyImage private constructor( onPictureReturnedFromCamera(activity, callbacks) } else if (requestCode == RequestCodes.CAPTURE_VIDEO) { onVideoReturnedFromCamera(activity, callbacks) - } + } else if (requestCode == RequestCodes.PICK_VIDEO_FROM_DOCUMENTS && resultIntent != null) { + onPickedExistingPictures(resultIntent, activity, callbacks) + } else if (requestCode == RequestCodes.PICK_VIDEO_FROM_GALLERY && resultIntent != null) { + onPickedExistingPictures(resultIntent, activity, callbacks) + } else if (requestCode == RequestCodes.PICK_VIDEO_FROM_CHOOSER) { + onFileReturnedFromChooser(resultIntent, activity, callbacks) + } } else { removeCameraFileAndCleanup() callbacks.onCanceled(mediaSource) @@ -276,6 +328,10 @@ class EasyImage private constructor( return Intents.plainGalleryPickerIntent().resolveActivity(context.packageManager) != null } + fun canDeviceHandleVideoGallery(): Boolean { + return Intents.plainVideoGalleryPickerIntent().resolveActivity(context.packageManager) != null + } + private fun removeCameraFileAndCleanup() { lastCameraFile?.file?.let { file -> Log.d(EASYIMAGE_LOG_TAG, "Removing camera file of size: ${file.length()}") diff --git a/library/src/main/java/pl/aprilapps/easyphotopicker/Intents.kt b/library/src/main/java/pl/aprilapps/easyphotopicker/Intents.kt index 6593ac6..554b0c1 100644 --- a/library/src/main/java/pl/aprilapps/easyphotopicker/Intents.kt +++ b/library/src/main/java/pl/aprilapps/easyphotopicker/Intents.kt @@ -29,6 +29,10 @@ internal object Intents { return Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) } + internal fun plainVideoGalleryPickerIntent(): Intent { + return Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI) + } + internal fun createDocumentsIntent(allowMultiple: Boolean): Intent { val intent = Intent(Intent.ACTION_GET_CONTENT) intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple) @@ -36,12 +40,25 @@ internal object Intents { return intent } + internal fun createVideoDocumentsIntent(allowMultiple: Boolean): Intent { + val intent = Intent(Intent.ACTION_GET_CONTENT) + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple) + intent.type = "video/*" + return intent + } + internal fun createGalleryIntent(allowMultiple: Boolean): Intent { val intent = plainGalleryPickerIntent() if (Build.VERSION.SDK_INT >= 18) intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple) return intent } + internal fun createVideoGalleryIntent(allowMultiple: Boolean): Intent { + val intent = plainVideoGalleryPickerIntent() + if (Build.VERSION.SDK_INT >= 18) intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple) + return intent + } + internal fun createCameraForImageIntent(context: Context, fileUri: Uri): Intent { val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) try { @@ -96,6 +113,36 @@ internal object Intents { return chooserIntent } + @Throws(IOException::class) + internal fun createVideoChooserIntent(context: Context, chooserTitle: String, chooserType: ChooserType, cameraFileUri: Uri, allowMultiple: Boolean): Intent { + val cameraIntents = ArrayList() + val captureIntent = Intent(android.provider.MediaStore.ACTION_VIDEO_CAPTURE) + val packageManager = context.packageManager + val camList = packageManager.queryIntentActivities(captureIntent, 0) + for (resolveInfo in camList) { + val packageName = resolveInfo.activityInfo.packageName + val intent = Intent(captureIntent) + intent.component = ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name) + intent.setPackage(packageName) + intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraFileUri) + + //We have to explicitly grant the write permission since Intent.setFlag works only on API Level >=20 + grantWritePermission(context, intent, cameraFileUri) + + cameraIntents.add(intent) + } + + val storageIntent = when (chooserType) { + ChooserType.CAMERA_AND_GALLERY -> createVideoGalleryIntent(allowMultiple) + else -> createVideoDocumentsIntent(allowMultiple) + } + + val chooserIntent = Intent.createChooser(storageIntent, chooserTitle) + chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toTypedArray()) + + return chooserIntent + } + internal fun isTherePhotoTakenWithCameraInsideIntent(dataIntent: Intent): Boolean { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { dataIntent.data == null && dataIntent.clipData == null