diff --git a/.gitignore b/.gitignore index ecfdcb7510..ab97ec340a 100644 --- a/.gitignore +++ b/.gitignore @@ -14,137 +14,4 @@ /tmp ktlint -multipicker/build/.transforms/3e0e90edbb388b6989e862c9faf75e87.bin -multipicker/build/.transforms/55ef863ef687bb455ca3376fbf042ba5.bin -multipicker/build/.transforms/3e0e90edbb388b6989e862c9faf75e87/classes/classes.dex -multipicker/build/.transforms/55ef863ef687bb455ca3376fbf042ba5/classes/classes.dex -multipicker/build/generated/source/buildConfig/debug/im/vector/riotx/multipicker/BuildConfig.java -multipicker/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml -multipicker/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output.json -multipicker/build/intermediates/annotation_processor_list/debug/annotationProcessors.json -multipicker/build/intermediates/annotations_typedef_file/debug/extractDebugAnnotations/typedefs.txt -multipicker/build/intermediates/compile_library_classes/debug/classes.jar -multipicker/build/intermediates/compile_only_not_namespaced_r_class_jar/debug/R.jar -multipicker/build/intermediates/consumer_proguard_file/debug/proguard.txt -multipicker/build/intermediates/incremental/debug-mergeJavaRes/merge-state -multipicker/build/intermediates/incremental/debug-mergeNativeLibs/merge-state -multipicker/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml -multipicker/build/intermediates/incremental/mergeDebugShaders/merger.xml -multipicker/build/intermediates/incremental/packageDebugAssets/merger.xml -multipicker/build/intermediates/incremental/packageDebugResources/compile-file-map.properties -multipicker/build/intermediates/incremental/packageDebugResources/merger.xml -multipicker/build/intermediates/javac/debug/classes/im/vector/riotx/multipicker/BuildConfig.class -multipicker/build/intermediates/library_java_res/debug/res.jar -multipicker/build/intermediates/library_manifest/debug/AndroidManifest.xml -multipicker/build/intermediates/local_only_symbol_list/debug/parseDebugLibraryResources/R-def.txt -multipicker/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt -multipicker/build/intermediates/merged_java_res/debug/out.jar -multipicker/build/intermediates/merged_manifests/debug/output.json -multipicker/build/intermediates/packaged-classes/debug/classes.jar -multipicker/build/intermediates/res/symbol-table-with-package/debug/package-aware-r.txt -multipicker/build/intermediates/runtime_library_classes/debug/classes.jar -multipicker/build/intermediates/symbols/debug/R.txt -multipicker/build/kotlin/compileDebugKotlin/build-history.bin -multipicker/build/kotlin/compileDebugKotlin/last-build.bin -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/inputs/source-to-output.tab -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/inputs/source-to-output.tab.keystream -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/inputs/source-to-output.tab.keystream.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/inputs/source-to-output.tab.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/inputs/source-to-output.tab.values.at -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/inputs/source-to-output.tab_i -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/inputs/source-to-output.tab_i.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/constants.tab -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/constants.tab.keystream -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/constants.tab.keystream.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/constants.tab.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/constants.tab.values.at -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/constants.tab_i -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/constants.tab_i.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/proto.tab -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/proto.tab.keystream -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/proto.tab.keystream.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/proto.tab.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/proto.tab.values.at -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/proto.tab_i -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/proto.tab_i.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab_i -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/subtypes.tab -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/subtypes.tab.keystream -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/subtypes.tab.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/subtypes.tab.values.at -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/subtypes.tab_i -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/subtypes.tab_i.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/supertypes.tab -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/supertypes.tab.keystream -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/supertypes.tab.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/supertypes.tab.values.at -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/supertypes.tab_i -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/jvm/kotlin/supertypes.tab_i.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/counters.tab -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/file-to-id.tab -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/file-to-id.tab.keystream -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/file-to-id.tab.keystream.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/file-to-id.tab.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/file-to-id.tab.values.at -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/file-to-id.tab_i -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/file-to-id.tab_i.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/id-to-file.tab -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/id-to-file.tab.keystream -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/id-to-file.tab.keystream.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/id-to-file.tab.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/id-to-file.tab.values.at -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/id-to-file.tab_i -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/id-to-file.tab_i.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/lookups.tab -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/lookups.tab.keystream -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/lookups.tab.keystream.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/lookups.tab.len -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/lookups.tab.values -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/lookups.tab.values.at -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/lookups.tab.values.s -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/lookups.tab_i -multipicker/build/kotlin/compileDebugKotlin/caches-jvm/lookups/lookups.tab_i.len -multipicker/build/outputs/aar/multipicker-debug.aar -multipicker/build/outputs/logs/manifest-merger-debug-report.txt -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/AudioPicker.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/ContactPicker.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/FilePicker.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/ImagePicker.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/MultiPicker$Type$AUDIO$2.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/MultiPicker$Type$CONTACT$2.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/MultiPicker$Type$FILE$2.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/MultiPicker$Type$IMAGE$2.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/MultiPicker$Type$VIDEO$2.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/MultiPicker$Type.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/MultiPicker.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/Picker.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/VideoPicker.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/entity/MultiPickerAudioType.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/entity/MultiPickerBaseType.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/entity/MultiPickerContactType.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/entity/MultiPickerFileType.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/entity/MultiPickerImageType.class -multipicker/build/tmp/kotlin-classes/debug/im/vector/riotx/multipicker/entity/MultiPickerVideoType.class -multipicker/build/tmp/kotlin-classes/debug/META-INF/multipicker_debug.kotlin_module + diff --git a/multipicker/src/main/AndroidManifest.xml b/multipicker/src/main/AndroidManifest.xml index 068a7c9a19..6f714ab388 100644 --- a/multipicker/src/main/AndroidManifest.xml +++ b/multipicker/src/main/AndroidManifest.xml @@ -1,2 +1,16 @@ + package="im.vector.riotx.multipicker"> + + + + + + + + diff --git a/multipicker/src/main/java/im/vector/riotx/multipicker/AudioPicker.kt b/multipicker/src/main/java/im/vector/riotx/multipicker/AudioPicker.kt index 19aba7bf1a..8fb23ec49d 100644 --- a/multipicker/src/main/java/im/vector/riotx/multipicker/AudioPicker.kt +++ b/multipicker/src/main/java/im/vector/riotx/multipicker/AudioPicker.kt @@ -52,6 +52,13 @@ class AudioPicker(override val requestCode: Int) : Picker( } } else if (dataUri != null) { selectedUriList.add(dataUri) + } else { + data?.extras?.get(Intent.EXTRA_STREAM)?.let { + when (it) { + is List<*> -> selectedUriList.addAll(it as List) + else -> selectedUriList.add(it as Uri) + } + } } selectedUriList.forEach { selectedUri -> diff --git a/multipicker/src/main/java/im/vector/riotx/multipicker/CameraPicker.kt b/multipicker/src/main/java/im/vector/riotx/multipicker/CameraPicker.kt new file mode 100644 index 0000000000..6962f2098a --- /dev/null +++ b/multipicker/src/main/java/im/vector/riotx/multipicker/CameraPicker.kt @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.multipicker + +import android.app.Activity +import android.content.Context +import android.content.Intent +import android.graphics.BitmapFactory +import android.graphics.ImageDecoder +import android.net.Uri +import android.os.Build +import android.os.Environment +import android.provider.MediaStore +import androidx.core.content.FileProvider +import androidx.exifinterface.media.ExifInterface +import androidx.fragment.app.Fragment +import im.vector.riotx.multipicker.entity.MultiPickerImageType +import java.io.File +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +class CameraPicker(val requestCode: Int) { + + fun startWithExpectingFile(activity: Activity): Uri? { + val photoUri = createPhotoUri(activity) + val intent = createIntent().apply { + putExtra(MediaStore.EXTRA_OUTPUT, photoUri) + } + activity.startActivityForResult(intent, requestCode) + return photoUri + } + + fun startWithExpectingFile(fragment: Fragment): Uri? { + val photoUri = createPhotoUri(fragment.requireContext()) + val intent = createIntent().apply { + putExtra(MediaStore.EXTRA_OUTPUT, photoUri) + } + fragment.startActivityForResult(intent, requestCode) + return photoUri + } + + fun getTakenPhoto(context: Context, requestCode: Int, resultCode: Int, photoUri: Uri): MultiPickerImageType? { + if (requestCode == this.requestCode && resultCode == Activity.RESULT_OK) { + val projection = arrayOf( + MediaStore.Images.Media.DISPLAY_NAME, + MediaStore.Images.Media.SIZE + ) + + context.contentResolver.query( + photoUri, + projection, + null, + null, + null + )?.use { cursor -> + val nameColumn = cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME) + val sizeColumn = cursor.getColumnIndex(MediaStore.Images.Media.SIZE) + + if (cursor.moveToNext()) { + val name = cursor.getString(nameColumn) + val size = cursor.getLong(sizeColumn) + + var orientation = 0 + + val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + ImageDecoder.decodeBitmap(ImageDecoder.createSource(context.contentResolver, photoUri)) + } else { + context.contentResolver.openInputStream(photoUri)?.use { inputStream -> + BitmapFactory.decodeStream(inputStream) + } + } + + context.contentResolver.openInputStream(photoUri)?.use { inputStream -> + try { + ExifInterface(inputStream).let { + orientation = it.rotationDegrees + } + } catch (e: Exception) { + e.printStackTrace() + } + } + + return MultiPickerImageType( + name, + size, + context.contentResolver.getType(photoUri), + photoUri, + bitmap?.width ?: 0, + bitmap?.height ?: 0, + orientation + ) + } + } + } + return null + } + + private fun createIntent(): Intent { + return Intent(MediaStore.ACTION_IMAGE_CAPTURE) + } + + private fun createPhotoUri(context: Context): Uri { + val file = createImageFile(context) + val authority = context.packageName + ".multipicker.fileprovider" + return FileProvider.getUriForFile(context, authority, file) + } + + private fun createImageFile(context: Context): File { + val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date()) + val storageDir: File = context.filesDir + return File.createTempFile( + "JPEG_${timeStamp}_", /* prefix */ + ".jpg", /* suffix */ + storageDir /* directory */ + ) + } +} diff --git a/multipicker/src/main/java/im/vector/riotx/multipicker/FilePicker.kt b/multipicker/src/main/java/im/vector/riotx/multipicker/FilePicker.kt index cf6b74c62d..9d3292c115 100644 --- a/multipicker/src/main/java/im/vector/riotx/multipicker/FilePicker.kt +++ b/multipicker/src/main/java/im/vector/riotx/multipicker/FilePicker.kt @@ -51,6 +51,13 @@ class FilePicker(override val requestCode: Int) : Picker(re } } else if (dataUri != null) { selectedUriList.add(dataUri) + } else { + data?.extras?.get(Intent.EXTRA_STREAM)?.let { + when (it) { + is List<*> -> selectedUriList.addAll(it as List) + else -> selectedUriList.add(it as Uri) + } + } } selectedUriList.forEach { selectedUri -> diff --git a/multipicker/src/main/java/im/vector/riotx/multipicker/ImagePicker.kt b/multipicker/src/main/java/im/vector/riotx/multipicker/ImagePicker.kt index 79832a2ad1..f33ceb816c 100644 --- a/multipicker/src/main/java/im/vector/riotx/multipicker/ImagePicker.kt +++ b/multipicker/src/main/java/im/vector/riotx/multipicker/ImagePicker.kt @@ -55,6 +55,13 @@ class ImagePicker(override val requestCode: Int) : Picker( } } else if (dataUri != null) { selectedUriList.add(dataUri) + } else { + data?.extras?.get(Intent.EXTRA_STREAM)?.let { + when (it) { + is List<*> -> selectedUriList.addAll(it as List) + else -> selectedUriList.add(it as Uri) + } + } } selectedUriList.forEach { selectedUri -> diff --git a/multipicker/src/main/java/im/vector/riotx/multipicker/MultiPicker.kt b/multipicker/src/main/java/im/vector/riotx/multipicker/MultiPicker.kt index d10346c903..24769e11c3 100644 --- a/multipicker/src/main/java/im/vector/riotx/multipicker/MultiPicker.kt +++ b/multipicker/src/main/java/im/vector/riotx/multipicker/MultiPicker.kt @@ -24,12 +24,14 @@ class MultiPicker { val VIDEO by lazy { MultiPicker() } val AUDIO by lazy { MultiPicker() } val CONTACT by lazy { MultiPicker() } + val CAMERA by lazy { MultiPicker() } const val REQUEST_CODE_PICK_IMAGE = 5000 const val REQUEST_CODE_PICK_VIDEO = 5001 const val REQUEST_CODE_PICK_FILE = 5002 const val REQUEST_CODE_PICK_AUDIO = 5003 const val REQUEST_CODE_PICK_CONTACT = 5004 + const val REQUEST_CODE_TAKE_PHOTO = 5005 @Suppress("UNCHECKED_CAST") fun get(type: MultiPicker): T { @@ -39,6 +41,7 @@ class MultiPicker { FILE -> FilePicker(REQUEST_CODE_PICK_FILE) as T AUDIO -> AudioPicker(REQUEST_CODE_PICK_AUDIO) as T CONTACT -> ContactPicker(REQUEST_CODE_PICK_CONTACT) as T + CAMERA -> CameraPicker(REQUEST_CODE_TAKE_PHOTO) as T else -> throw IllegalArgumentException("Unsupported type $type") } } diff --git a/multipicker/src/main/java/im/vector/riotx/multipicker/MultiPickerFileProvider.kt b/multipicker/src/main/java/im/vector/riotx/multipicker/MultiPickerFileProvider.kt new file mode 100644 index 0000000000..832d721eef --- /dev/null +++ b/multipicker/src/main/java/im/vector/riotx/multipicker/MultiPickerFileProvider.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.multipicker + +import androidx.core.content.FileProvider + +class MultiPickerFileProvider : FileProvider() { +} diff --git a/multipicker/src/main/java/im/vector/riotx/multipicker/Picker.kt b/multipicker/src/main/java/im/vector/riotx/multipicker/Picker.kt index 62dff35062..f162dd7608 100644 --- a/multipicker/src/main/java/im/vector/riotx/multipicker/Picker.kt +++ b/multipicker/src/main/java/im/vector/riotx/multipicker/Picker.kt @@ -19,6 +19,7 @@ package im.vector.riotx.multipicker import android.app.Activity import android.content.Context import android.content.Intent +import android.net.Uri import androidx.fragment.app.Fragment abstract class Picker(open val requestCode: Int) { @@ -29,8 +30,16 @@ abstract class Picker(open val requestCode: Int) { abstract fun startWith(fragment: Fragment) + open fun startWithExpectingFile(activity: Activity): Uri? = null + + open fun startWithExpectingFile(fragment: Fragment): Uri? = null + abstract fun getSelectedFiles(context: Context, requestCode: Int, resultCode: Int, data: Intent?): List + fun getIncomingFiles(context: Context, data: Intent?): List { + return getSelectedFiles(context, requestCode, Activity.RESULT_OK, data) + } + fun single(): Picker { single = true return this diff --git a/multipicker/src/main/java/im/vector/riotx/multipicker/VideoPicker.kt b/multipicker/src/main/java/im/vector/riotx/multipicker/VideoPicker.kt index 8066c0b43e..92d1e9c240 100644 --- a/multipicker/src/main/java/im/vector/riotx/multipicker/VideoPicker.kt +++ b/multipicker/src/main/java/im/vector/riotx/multipicker/VideoPicker.kt @@ -52,6 +52,13 @@ class VideoPicker(override val requestCode: Int) : Picker( } } else if (dataUri != null) { selectedUriList.add(dataUri) + } else { + data?.extras?.get(Intent.EXTRA_STREAM)?.let { + when (it) { + is List<*> -> selectedUriList.addAll(it as List) + else -> selectedUriList.add(it as Uri) + } + } } selectedUriList.forEach { selectedUri -> diff --git a/multipicker/src/main/java/im/vector/riotx/multipicker/entity/MultiPickerContactType.kt b/multipicker/src/main/java/im/vector/riotx/multipicker/entity/MultiPickerContactType.kt index 565304a546..5a9c064867 100644 --- a/multipicker/src/main/java/im/vector/riotx/multipicker/entity/MultiPickerContactType.kt +++ b/multipicker/src/main/java/im/vector/riotx/multipicker/entity/MultiPickerContactType.kt @@ -22,11 +22,11 @@ data class MultiPickerContactType( val phoneNumberList: List, val emailList: List ) { - private val FORMAT_CONTACT = "Name: %s, Photo: %s, Phones: %s, Emails: %s" + private val CONTACT_FORMAT = "Name: %s, Photo: %s, Phones: %s, Emails: %s" override fun toString(): String { val phoneNumberString = phoneNumberList.joinToString(separator = ", ", prefix = "[", postfix = "]") val emailString = emailList.joinToString(separator = ", ", prefix = "[", postfix = "]") - return String.format(FORMAT_CONTACT, displayName, photoUri, phoneNumberString, emailString) + return String.format(CONTACT_FORMAT, displayName, photoUri, phoneNumberString, emailString) } } diff --git a/multipicker/src/main/res/xml/multipicker_provider_paths.xml b/multipicker/src/main/res/xml/multipicker_provider_paths.xml new file mode 100644 index 0000000000..ff9b81ce98 --- /dev/null +++ b/multipicker/src/main/res/xml/multipicker_provider_paths.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index 30f9551612..13de137e8f 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -533,6 +533,11 @@ class RoomDetailFragment @Inject constructor( MultiPicker.REQUEST_CODE_PICK_CONTACT -> { MultiPicker.get(MultiPicker.CONTACT).getSelectedFiles(requireContext(), requestCode, resultCode, data) } + MultiPicker.REQUEST_CODE_TAKE_PHOTO -> { + cameraPhotoUri?.let { + MultiPicker.get(MultiPicker.CAMERA).getTakenPhoto(requireContext(), requestCode, resultCode, it) + } + } } val hasBeenHandled = attachmentsHelper.onActivityResult(requestCode, resultCode, data) @@ -1367,9 +1372,12 @@ class RoomDetailFragment @Inject constructor( } } + private var cameraPhotoUri: Uri? = null private fun launchAttachmentProcess(type: AttachmentTypeSelectorView.Type) { when (type) { - AttachmentTypeSelectorView.Type.CAMERA -> attachmentsHelper.openCamera() + AttachmentTypeSelectorView.Type.CAMERA -> { + cameraPhotoUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(this) + } AttachmentTypeSelectorView.Type.FILE -> MultiPicker.get(MultiPicker.FILE).startWith(this) AttachmentTypeSelectorView.Type.GALLERY -> MultiPicker.get(MultiPicker.IMAGE).startWith(this) AttachmentTypeSelectorView.Type.AUDIO -> MultiPicker.get(MultiPicker.AUDIO).startWith(this)