mirror of
https://github.com/element-hq/element-android
synced 2024-12-18 07:12:47 +03:00
CameraPicker & incoming share implementation.
This commit is contained in:
parent
6db0de321c
commit
5b875e0571
13 changed files with 227 additions and 138 deletions
135
.gitignore
vendored
135
.gitignore
vendored
|
@ -14,137 +14,4 @@
|
||||||
/tmp
|
/tmp
|
||||||
|
|
||||||
ktlint
|
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
|
|
||||||
|
|
|
@ -1,2 +1,16 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="im.vector.riotx.multipicker" />
|
package="im.vector.riotx.multipicker">
|
||||||
|
|
||||||
|
<application>
|
||||||
|
<provider
|
||||||
|
android:name=".MultiPickerFileProvider"
|
||||||
|
android:authorities="${applicationId}.multipicker.fileprovider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/multipicker_provider_paths" />
|
||||||
|
</provider>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
|
|
|
@ -52,6 +52,13 @@ class AudioPicker(override val requestCode: Int) : Picker<MultiPickerAudioType>(
|
||||||
}
|
}
|
||||||
} else if (dataUri != null) {
|
} else if (dataUri != null) {
|
||||||
selectedUriList.add(dataUri)
|
selectedUriList.add(dataUri)
|
||||||
|
} else {
|
||||||
|
data?.extras?.get(Intent.EXTRA_STREAM)?.let {
|
||||||
|
when (it) {
|
||||||
|
is List<*> -> selectedUriList.addAll(it as List<Uri>)
|
||||||
|
else -> selectedUriList.add(it as Uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedUriList.forEach { selectedUri ->
|
selectedUriList.forEach { selectedUri ->
|
||||||
|
|
|
@ -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 */
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,6 +51,13 @@ class FilePicker(override val requestCode: Int) : Picker<MultiPickerFileType>(re
|
||||||
}
|
}
|
||||||
} else if (dataUri != null) {
|
} else if (dataUri != null) {
|
||||||
selectedUriList.add(dataUri)
|
selectedUriList.add(dataUri)
|
||||||
|
} else {
|
||||||
|
data?.extras?.get(Intent.EXTRA_STREAM)?.let {
|
||||||
|
when (it) {
|
||||||
|
is List<*> -> selectedUriList.addAll(it as List<Uri>)
|
||||||
|
else -> selectedUriList.add(it as Uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedUriList.forEach { selectedUri ->
|
selectedUriList.forEach { selectedUri ->
|
||||||
|
|
|
@ -55,6 +55,13 @@ class ImagePicker(override val requestCode: Int) : Picker<MultiPickerImageType>(
|
||||||
}
|
}
|
||||||
} else if (dataUri != null) {
|
} else if (dataUri != null) {
|
||||||
selectedUriList.add(dataUri)
|
selectedUriList.add(dataUri)
|
||||||
|
} else {
|
||||||
|
data?.extras?.get(Intent.EXTRA_STREAM)?.let {
|
||||||
|
when (it) {
|
||||||
|
is List<*> -> selectedUriList.addAll(it as List<Uri>)
|
||||||
|
else -> selectedUriList.add(it as Uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedUriList.forEach { selectedUri ->
|
selectedUriList.forEach { selectedUri ->
|
||||||
|
|
|
@ -24,12 +24,14 @@ class MultiPicker<T> {
|
||||||
val VIDEO by lazy { MultiPicker<VideoPicker>() }
|
val VIDEO by lazy { MultiPicker<VideoPicker>() }
|
||||||
val AUDIO by lazy { MultiPicker<AudioPicker>() }
|
val AUDIO by lazy { MultiPicker<AudioPicker>() }
|
||||||
val CONTACT by lazy { MultiPicker<ContactPicker>() }
|
val CONTACT by lazy { MultiPicker<ContactPicker>() }
|
||||||
|
val CAMERA by lazy { MultiPicker<CameraPicker>() }
|
||||||
|
|
||||||
const val REQUEST_CODE_PICK_IMAGE = 5000
|
const val REQUEST_CODE_PICK_IMAGE = 5000
|
||||||
const val REQUEST_CODE_PICK_VIDEO = 5001
|
const val REQUEST_CODE_PICK_VIDEO = 5001
|
||||||
const val REQUEST_CODE_PICK_FILE = 5002
|
const val REQUEST_CODE_PICK_FILE = 5002
|
||||||
const val REQUEST_CODE_PICK_AUDIO = 5003
|
const val REQUEST_CODE_PICK_AUDIO = 5003
|
||||||
const val REQUEST_CODE_PICK_CONTACT = 5004
|
const val REQUEST_CODE_PICK_CONTACT = 5004
|
||||||
|
const val REQUEST_CODE_TAKE_PHOTO = 5005
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun <T> get(type: MultiPicker<T>): T {
|
fun <T> get(type: MultiPicker<T>): T {
|
||||||
|
@ -39,6 +41,7 @@ class MultiPicker<T> {
|
||||||
FILE -> FilePicker(REQUEST_CODE_PICK_FILE) as T
|
FILE -> FilePicker(REQUEST_CODE_PICK_FILE) as T
|
||||||
AUDIO -> AudioPicker(REQUEST_CODE_PICK_AUDIO) as T
|
AUDIO -> AudioPicker(REQUEST_CODE_PICK_AUDIO) as T
|
||||||
CONTACT -> ContactPicker(REQUEST_CODE_PICK_CONTACT) as T
|
CONTACT -> ContactPicker(REQUEST_CODE_PICK_CONTACT) as T
|
||||||
|
CAMERA -> CameraPicker(REQUEST_CODE_TAKE_PHOTO) as T
|
||||||
else -> throw IllegalArgumentException("Unsupported type $type")
|
else -> throw IllegalArgumentException("Unsupported type $type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ package im.vector.riotx.multipicker
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
|
||||||
abstract class Picker<T>(open val requestCode: Int) {
|
abstract class Picker<T>(open val requestCode: Int) {
|
||||||
|
@ -29,8 +30,16 @@ abstract class Picker<T>(open val requestCode: Int) {
|
||||||
|
|
||||||
abstract fun startWith(fragment: Fragment)
|
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<T>
|
abstract fun getSelectedFiles(context: Context, requestCode: Int, resultCode: Int, data: Intent?): List<T>
|
||||||
|
|
||||||
|
fun getIncomingFiles(context: Context, data: Intent?): List<T> {
|
||||||
|
return getSelectedFiles(context, requestCode, Activity.RESULT_OK, data)
|
||||||
|
}
|
||||||
|
|
||||||
fun single(): Picker<T> {
|
fun single(): Picker<T> {
|
||||||
single = true
|
single = true
|
||||||
return this
|
return this
|
||||||
|
|
|
@ -52,6 +52,13 @@ class VideoPicker(override val requestCode: Int) : Picker<MultiPickerVideoType>(
|
||||||
}
|
}
|
||||||
} else if (dataUri != null) {
|
} else if (dataUri != null) {
|
||||||
selectedUriList.add(dataUri)
|
selectedUriList.add(dataUri)
|
||||||
|
} else {
|
||||||
|
data?.extras?.get(Intent.EXTRA_STREAM)?.let {
|
||||||
|
when (it) {
|
||||||
|
is List<*> -> selectedUriList.addAll(it as List<Uri>)
|
||||||
|
else -> selectedUriList.add(it as Uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedUriList.forEach { selectedUri ->
|
selectedUriList.forEach { selectedUri ->
|
||||||
|
|
|
@ -22,11 +22,11 @@ data class MultiPickerContactType(
|
||||||
val phoneNumberList: List<String>,
|
val phoneNumberList: List<String>,
|
||||||
val emailList: List<String>
|
val emailList: List<String>
|
||||||
) {
|
) {
|
||||||
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 {
|
override fun toString(): String {
|
||||||
val phoneNumberString = phoneNumberList.joinToString(separator = ", ", prefix = "[", postfix = "]")
|
val phoneNumberString = phoneNumberList.joinToString(separator = ", ", prefix = "[", postfix = "]")
|
||||||
val emailString = emailList.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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths>
|
||||||
|
<files-path
|
||||||
|
name="external_files"
|
||||||
|
path="." />
|
||||||
|
</paths>
|
|
@ -533,6 +533,11 @@ class RoomDetailFragment @Inject constructor(
|
||||||
MultiPicker.REQUEST_CODE_PICK_CONTACT -> {
|
MultiPicker.REQUEST_CODE_PICK_CONTACT -> {
|
||||||
MultiPicker.get(MultiPicker.CONTACT).getSelectedFiles(requireContext(), requestCode, resultCode, data)
|
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)
|
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) {
|
private fun launchAttachmentProcess(type: AttachmentTypeSelectorView.Type) {
|
||||||
when (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.FILE -> MultiPicker.get(MultiPicker.FILE).startWith(this)
|
||||||
AttachmentTypeSelectorView.Type.GALLERY -> MultiPicker.get(MultiPicker.IMAGE).startWith(this)
|
AttachmentTypeSelectorView.Type.GALLERY -> MultiPicker.get(MultiPicker.IMAGE).startWith(this)
|
||||||
AttachmentTypeSelectorView.Type.AUDIO -> MultiPicker.get(MultiPicker.AUDIO).startWith(this)
|
AttachmentTypeSelectorView.Type.AUDIO -> MultiPicker.get(MultiPicker.AUDIO).startWith(this)
|
||||||
|
|
Loading…
Reference in a new issue