I've followed the android documentation on photos (https://developer.android.com/training/camera/photobasics#kotlin) to try and take a photo and save it.
If I don't use EXTRA_OUTPUT I can successfully get the small image from data.extra, but I need a bigger picture.
Using extra_output the same way they do in that link, I never get an actual photo saved, only 0 byte files.
So something is going wrong with my extra_output, but I have no idea what. Any ideas?
I did find other people with similar issues, but no actual solution
class CameraFragment2 : Fragment() {
private lateinit var binding: CameraFragment2FragmentBinding
private lateinit var textRecognizer: TextRecognizer
private lateinit var photoFile: File
private lateinit var photoUri: Uri
companion object {
fun newInstance() = CameraFragment2()
}
private lateinit var viewModel: CameraFragment2ViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = CameraFragment2FragmentBinding.inflate(inflater)
textRecognizer = TextRecognizer.Builder(context).build()
dispatchTakePictureIntent()
return binding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(CameraFragment2ViewModel::class.java)
// TODO: Use the ViewModel
}
private fun dispatchTakePictureIntent() {
val packageManager = context!!.packageManager
Intent(Intents.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
// Ensure that there's a camera activity to handle the intent
takePictureIntent.resolveActivity(packageManager)?.also {
// Create the File where the photo should go
val photoFile: File? = try {
createImageFile()
} catch (ex: IOException) {
// Error occurred while creating the File
Log.wtf("creating file failed", "creating file failed")
null
}
// Continue only if the File was successfully created
photoFile?.also {
val photoURI: Uri = FileProvider.getUriForFile(
context!!,
//BuildConfig.APPLICATION_ID + ".provider",
"com.example.myapplication.fileprovider",
it
)
takePictureIntent.putExtra(EXTRA_OUTPUT, photoURI)
takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
startActivityForResult(takePictureIntent, 1)
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
//super.onActivityResult(requestCode, resultCode, data)
//val file = File(currentPhotoPath)
//val bitmap = BitmapFactory.decodeFile(currentPhotoPath)
//scan(bitmap)
val filePathUri = Uri.parse(currentPhotoPath)
val myFile = File(filePathUri.path)
val file_size = (myFile.length() / 1024).toString().toInt()
Log.wtf("path", currentPhotoPath)
Log.wtf("size", file_size.toString())
//val image = File(currentPhotoPath)
val bmOptions = BitmapFactory.Options()
bmOptions.inJustDecodeBounds = false
bmOptions.inSampleSize = 4
//var bitmap = BitmapFactory.decodeFile(image.absolutePath, bmOptions)
//scan(bitmap)
var thing: Bitmap
BitmapFactory.decodeFile(currentPhotoPath, bmOptions)?.also { bitmap ->
scan(bitmap)
thing = bitmap
}
if (resultCode == Intents.RESULT_OK && requestCode == 1){
//val photo = data!!.extras!!.get(EXTRA_OUTPUT) as Bitmap
//scan(photo)
//val bitmap = BitmapFactory.decodeFile(photoFile.absolutePath)
//scan(bitmap)
}
}
lateinit var currentPhotoPath: String
#Throws(IOException::class)
private fun createImageFile(): File {
// Create an image file name
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val storageDir: File = context!!.getExternalFilesDir(Environment.DIRECTORY_PICTURES)!!
return File.createTempFile(
"JPEG_${timeStamp}_", /* prefix */
".jpg", /* suffix */
storageDir /* directory */
).apply {
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = absolutePath
}
}
private fun scan(photo: Bitmap){
//val intent = Intent(ACTION_IMAGE_CAPTURE)
val imageFrame = Frame.Builder()
.setBitmap(photo)
.build()
val detections = textRecognizer.detect(imageFrame)
val builder = StringBuilder()
if (detections.size() != 0){
for (x in 0..detections.size()) {
builder.append(detections[x].value)
builder.append("\n")
}
}
binding.camFragResult.text = builder
}
}
in my manifest:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapplication.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"></meta-data>
</provider>
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path
name="my_images"
path="." />
</paths>
Your primary bug is is that you did not add FLAG_GRANT_WRITE_URI_PERMISSION to your Intent. You granted the user's chosen camera app read access, not write access. So, the camera app cannot write to your designated location.
In addition:
You will lose the value of currentPhotoPath if your process is terminated while the camera app is in the foreground, which happens quite a bit
You might also consider cleaning up provider_paths.xml (you have two conflicting entries)
private fun dispatchTakePictureIntent() {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
// Create the File where the photo should go
photoFile = createImageFile()
// Continue only if the File was successfully created
if(photoFile != null){
val photoURI: Uri = FileProvider.getUriForFile(
requireContext(),
"com.billsAplication.fileprovider", // Your package
photoFile!!)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
}
if (requireContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
// Start the image capture intent to take photo
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
}
}
Related
The process is to create a jpg file based on the timestamp, add the uri to the list, and display it through the lisetview
the first picture is normal,but Error will be reported when the second picture is obtained
The error occurred before Log.e("addiamge","====" )
E Writing exception to parcel
java.lang.SecurityException: Permission Denial: writing
net.qingmowan.Inspection.custom.MyFileProvider uri
content://net.aaaa.bbb.fileprovider/my_image/inspection_16679577393117723686263338001557.jpg
from pid=30798, uid=10084 requires the provider be exported, or grantUriPermission()
at android.content.ContentProvider.enforceWritePermissionInner(ContentProvider.java:919)
at android.content.ContentProvider$Transport.enforceWritePermission(ContentProvider.java:698)
at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:669)
at android.content.ContentProvider$Transport.openAssetFile(ContentProvider.java:493)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:272)
at android.os.Binder.execTransactInternal(Binder.java:1154)
at android.os.Binder.execTransact(Binder.java:1123)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
var photoURI: Uri? = null
val imageUris = LinkedList<Uri>();
val adapter = ImageAdapter(this, imageUris, layoutInflater)
val imageList = findViewById<ListView>(R.id.imageList)
imageList.adapter = adapter
val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK && photoURI != null) {
Log.e("addiamge","====" )
imageUris.add(photoURI!!)
Log.e("images", imageUris.toString())
adapter.notifyDataSetChanged()
}
}
image.setOnClickListener {
photoURI = getPhotoUri()
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
launcher.launch(intent)
}
private fun getPhotoUri(): Uri? {
val photoFile: File? = try {
createImageFile()
} catch (ex: IOException) {
Log.e("获取拍照文件", "失败", ex)
null
}
photoFile?.also {
val uri = FileProvider.getUriForFile(this, "net.aaa.bbb.fileprovider", it)
return uri
}
return null
}
private fun createImageFile(): File {
val storageDir: File? = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
val timeStamp = Date()
val file = File.createTempFile("inspection_${timeStamp.time}", ".jpg", storageDir).absoluteFile
Log.e("file_message", String.format("name:%s, file.absolutePath))
return file
}
Every time you get a photo from the camera, you need to create a new intent and reset the action
Move the definition of intent to the clickListener
image.setOnClickListener {
photoURI = getPhotoUri()
intent1.action = MediaStore.ACTION_IMAGE_CAPTURE
intent1.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
launcher.launch(intent1)
}
As for why I don't know, I hope someone can supplement my answer
I am using this code and I am missing something, because almost everything is working, but I get a null in the data when the callback responds:
private inner class JavascriptInterface {
#android.webkit.JavascriptInterface
fun image_capture() {
val photoFileName = "photo.jpg"
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
var photoFile = getPhotoFileUri(photoFileName)
if (photoFile != null) {
fileProvider = FileProvider.getUriForFile(applicationContext, "com.codepath.fileprovider", photoFile!!)
intent.putExtra(EXTRA_OUTPUT, fileProvider)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
if (intent.resolveActivity(packageManager) != null) {
getContent.launch(intent)
}
}
}
}
val getContent = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
val intent:Intent? = result.data // <- PROBLEM: data is ALWAYS null
}
}
My manifest snippet related to this looks like this:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
and my fileprovider.xml looks like this:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path name="images" path="Pictures" />
</paths>
Any help is appreciated. Thanks!
That is supposed to be null, as ACTION_IMAGE_CAPTURE is not documented to return a Uri. You are using EXTRA_OUTPUT. The image should be stored in the location that you specified using EXTRA_OUTPUT.
Note, though, that you should be adding both FLAG_GRANT_READ_URI_PERMISSION and FLAG_GRANT_WRITE_URI_PERMISSION to the Intent, as the camera app needs to be able to write the image to the desired location.
So, I ended up checking out the TakePicture contract #ian (thanks for that tip!) and after a lot of cobbling together various resources I found, I finally got it to work. This is the pertinent kotlin code for the webview Activity:
class WebViewShell : AppCompatActivity() {
val APP_TAG = "MyApp"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_web_view)
// Storing data into SharedPreferences
val sharedPreferences = getSharedPreferences("MySharedPrefs", MODE_PRIVATE)
val storedurl: String = sharedPreferences.getString("url", "").toString()
val myWebView: WebView = findViewById(R.id.webview_webview)
myWebView.clearCache(true)
myWebView.settings.setJavaScriptCanOpenWindowsAutomatically(true)
myWebView.settings.setJavaScriptEnabled(true)
myWebView.settings.setAppCacheEnabled(true)
myWebView.settings.setAppCacheMaxSize(10 * 1024 * 1024)
myWebView.settings.setAppCachePath("")
myWebView.settings.setDomStorageEnabled(true)
myWebView.settings.setRenderPriority(android.webkit.WebSettings.RenderPriority.HIGH)
WebView.setWebContentsDebuggingEnabled(true)
myWebView.addJavascriptInterface(JavascriptInterface(),"Android")
myWebView.loadUrl(storedurl)
}
private inner class JavascriptInterface {
#android.webkit.JavascriptInterface
fun image_capture() { // opens Camera
takeImage()
}
}
private fun takeImage() {
try {
val uri = getTmpFileUri()
lifecycleScope.launchWhenStarted {
takeImageResult.launch(uri)
}
}
catch (e: Exception) {
android.widget.Toast.makeText(applicationContext, e.message, android.widget.Toast.LENGTH_LONG).show()
}
}
private val takeImageResult = registerForActivityResult(TakePictureWithUriReturnContract()) { (isSuccess, imageUri) ->
val myWebView: android.webkit.WebView = findViewById(R.id.webview_webview)
if (isSuccess) {
val imageStream: InputStream? = contentResolver.openInputStream(imageUri)
val selectedImage = BitmapFactory.decodeStream(imageStream)
val scaledImage = scaleDown(selectedImage, 800F, true)
val baos = ByteArrayOutputStream()
scaledImage?.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val byteArray: ByteArray = baos.toByteArray()
val dataURL: String = Base64.encodeToString(byteArray, Base64.DEFAULT)
myWebView.loadUrl( "JavaScript:fnWebAppReceiveImage('" + dataURL + "')" )
}
else {
android.widget.Toast.makeText(applicationContext, "Image capture failed", android.widget.Toast.LENGTH_LONG).show()
}
}
private inner class TakePictureWithUriReturnContract : ActivityResultContract<Uri, Pair<Boolean, Uri>>() {
private lateinit var imageUri: Uri
#CallSuper
override fun createIntent(context: Context, input: Uri): Intent {
imageUri = input
return Intent(MediaStore.ACTION_IMAGE_CAPTURE).putExtra(MediaStore.EXTRA_OUTPUT, input)
}
override fun getSynchronousResult(
context: Context,
input: Uri
): SynchronousResult<Pair<Boolean, Uri>>? = null
#Suppress("AutoBoxing")
override fun parseResult(resultCode: Int, intent: Intent?): Pair<Boolean, Uri> {
return (resultCode == Activity.RESULT_OK) to imageUri
}
}
private fun getTmpFileUri(): Uri? {
val mediaStorageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), APP_TAG)
if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs()) {
throw Exception("Failed to create directory to store media temp file")
}
return FileProvider.getUriForFile(applicationContext, getApplicationContext().getPackageName() + ".provider", File(mediaStorageDir.path + File.separator + "photo.jpg"))
}
fun scaleDown(realImage: Bitmap, maxImageSize: Float, filter: Boolean): Bitmap? {
val ratio = Math.min(maxImageSize / realImage.width, maxImageSize / realImage.height)
val width = Math.round(ratio * realImage.width)
val height = Math.round(ratio * realImage.height)
return Bitmap.createScaledBitmap(realImage, width, height, filter)
}
}
To round things out, here is the pertinent JavaScript code - which the Activity is loading via the myWebView.loadUrl(storedurl) statement.
This is the JavaScript code which calls the Android code:
if (window.Android) {
Android.image_capture();
}
And when the picture has been taken, and sized by the Android code, it sends the Base64 back to JavaScript with:
myWebView.loadUrl("JavaScript:fnWebAppReceiveImage('" + dataURL + "')")
Note how weirdly you have to specify function arguments. There probably is a better way, but this code works. If there are any suggestions about how to specify a function argument easier than this, please let me know.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.MyApp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
</application>
</manifest>
And the provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path name="external_files" path="." />
</paths>
Hope this helps someone - it took me days of research to figure this one out!
Im doing an app and i want to share photo just i saved to phone to another apps like instagram twitter.Im not able to do it and i cant see where the mistake is.Here is my code
`private fun getScreenshot(currentPage: Int){
QuickShot.of(requireActivity().findViewById<ConstraintLayout(currentPage))
.setResultListener(this)
.enableLogging()
.setFilename("screen")
.setPath("Spotibud")
.toJPG()
.save()
}
override fun onQuickShotSuccess(path: String?) {
Log.d(TAG, "onQuickShotSuccess: $path")
shareOnInstagram(path!!)
}
override fun onQuickShotFailed(path: String?, errorMsg: String?) {
Log.d(TAG, "onQuickShotFailed: $errorMsg")
}
private fun shareOnInstagram(path: String){
val stickerAssetUri: Uri = Uri.parse(path)
val intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM,stickerAssetUri)
type = "image/*"
}
startActivity(intent)
}`
and my log when app saves image
2021-02-18 17:28:08.750 16355-16355/com.example.contestifyfirsttry D/Home Fragment: onQuickShotSuccess: /Pictures/Spotibud/screen.jpg
also is there any code how i can see error.try catch not worked
now i found the solution this isnt best practice but im sure it makes you to see what you should do
private fun shareOnInstagram(path: String){
var file : File = File("/storage/emulated/0/Pictures/Spotibud/screen.jpg")
if (file.exists()){
Log.d(TAG, "shareOnInstagram: file exists")
val stickerAssetUri: Uri = Uri.fromFile(file)
val sourceApplication = "com.example.contestifyfirsttry"
val intent = Intent("com.instagram.share.ADD_TO_STORY")
intent.putExtra("source_application", sourceApplication)
intent.type = "image/*"
intent.putExtra("interactive_asset_uri", stickerAssetUri)
intent.putExtra("top_background_color", "#33FF33")
intent.putExtra("bottom_background_color", "#FF00FF")
val activity: Activity? = activity
activity!!.grantUriPermission(
"com.instagram.android", stickerAssetUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
)
if (activity!!.packageManager.resolveActivity(intent, 0) != null) {
activity!!.startActivityForResult(intent, 0)
}
}else{
Log.d(TAG, "shareOnInstagram: file dont exists")
}
}
my app tries to capture a video, and then the result will be sent to server
so I capture the video using the code below, but when I upload it to server, the file size is always 0 byte
because I create it in temporary file ?
here is the code to record a video
private fun recordVideo() {
val videoFile = createVideoFile()
videoFile?.let {
videoUri = FileProvider.getUriForFile(mContext,"com.video.record.fileprovider",it)
val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
intent.putExtra(MediaStore.EXTRA_OUTPUT,videoUri)
startActivityForResult(intent,REQUEST_VIDEO_CAPTURE)
}
}
private fun createVideoFile() : File? {
val fileName = "myVideoAndroid"
val storageDir = mActivity.getExternalFilesDir(Environment.DIRECTORY_MOVIES)
return File.createTempFile(fileName,".mp4",storageDir) // <---- because I make it in temporary file ?
}
and here is the provider tag in the manifest
<provider
android:authorities="com.video.record.fileprovider"
android:name="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
and here is the file path xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android = "http://schemas.android.com/apk/res/android">
<external-path
name="my_videos"
path="Android/data/com.xxxx.mediauploader/files/Movies"/>
</paths>
the video seems good before uploading to server, I can play it perfectly.
and then I upload it using retrofit by using the code below
the interface
#Multipart
#POST("uploadvideo")
fun uploadVideo(
#Part video: MultipartBody.Part
): Call<UploadResponse>
and then used it like this
private fun createVideoFile() : File? {
val fileName = "myVideoAndroid"
val storageDir = mActivity.getExternalFilesDir(Environment.DIRECTORY_MOVIES)
return File.createTempFile(fileName,".mp4",storageDir)
}
val file = File(createVideoFile()!!.absolutePath)
val fileVideoPart = MultipartBody.Part.createFormData("videoFile", file.name, RequestBody.create("video/*".toMediaTypeOrNull(), file))
val call = uploadMediaAPI.uploadVideo(video = fileVideoPart)
call.enqueue(object : Callback<UploadResponse> {
})
I can upload it successfully, but the result is always 0 bytes in server
how to solve this ?
I finally can solve this problem, maybe because the videoUri is created in temporary file, so we need to convert it to real file
pass this videoFile to your retrofit
val videoFile = fileFromContentUri(mContext,videoUri) // <--- pass your temporary videoUri here
the code for fileFromContentUri will be like this
fun fileFromContentUri(context: Context, contentUri: Uri): File {
// Preparing Temp file name
val fileExtension = getFileExtension(context, contentUri)
val fileName = "temp_file" + if (fileExtension != null) ".$fileExtension" else ""
// Creating Temp file
val tempFile = File(context.cacheDir, fileName)
tempFile.createNewFile()
try {
val oStream = FileOutputStream(tempFile)
val inputStream = context.contentResolver.openInputStream(contentUri)
inputStream?.let {
copy(inputStream, oStream)
}
oStream.flush()
} catch (e: Exception) {
e.printStackTrace()
}
return tempFile
}
private fun getFileExtension(context: Context, uri: Uri): String? {
val fileType: String? = context.contentResolver.getType(uri)
return MimeTypeMap.getSingleton().getExtensionFromMimeType(fileType)
}
#Throws(IOException::class)
private fun copy(source: InputStream, target: OutputStream) {
val buf = ByteArray(8192)
var length: Int
while (source.read(buf).also { length = it } > 0) {
target.write(buf, 0, length)
}
}
This question already has answers here:
onActivityResult's intent.getPath() doesn't give me the correct filename
(2 answers)
Getting the Absolute File Path from Content URI for searched images
(2 answers)
Android - Get real path of a .txt file selected from the file explorer
(1 answer)
Closed 3 years ago.
I have an activity where the user can select an image/video from gallery. For images everything is working fine, however i'm struggling with videos.
This is how i call to open the gallery in case of videos:
fun getVideoFromGallery() {
if (Build.VERSION.SDK_INT < 19) {
var intent = Intent()
intent.type = "video/*"
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(
Intent.createChooser(intent, "Select Picture")
, GALLERY_VIDEO
)
} else {
var videopicker = Intent(Intent.ACTION_OPEN_DOCUMENT);
videopicker.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
videopicker.addCategory(Intent.CATEGORY_OPENABLE)
videopicker.type = "video/*"
startActivityForResult(videopicker, GALLERY_VIDEO);
}
}
I receive the notification when the user selected the video in:
public override fun onActivityResult(requestCode:Int, resultCode:Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == GALLERY_VIDEO)
{
if (data != null)
{
val contentURI = data.data
try {
if (data.getData() != null) {
var videoURI = data.getData()
val cR = this#EnviarMultimediaActivity.getContentResolver();
val type = cR.getType(videoURI);
if(!type.isNullOrEmpty() && type.contains("video/", true)){
val videopath = videoURI.getPath()
val file = File(videopath)
Log.d(TAG, "Video uri: "+videoURI)
Log.d(TAG, "Video path: "+file.getAbsolutePath())
var videoCopy = File(Environment.getExternalStorageDirectory().absolutePath+ IMAGE_DIRECTORY + ((Calendar.getInstance().getTimeInMillis()).toString() + ".mp4"))
//file.copyTo(videoCopy, true)
copyVideoFile(file, videoCopy)
Glide
.with(this#EnviarMultimediaActivity)
.asBitmap()
.load(videoURI)
.into(object : CustomTarget<Bitmap>(){
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
val thumbnail = saveImage(resource)
val thumbnailUri = Uri.parse(thumbnail);
val videoCopyURI = Uri.parse(videoCopy.getPath())
listaFicherosEnviar.add(EnviarMultimediaFichero(null, false, 3, videoCopyURI, thumbnailUri))
adapterEnviarMultimediaImagen.swapData(listaFicherosEnviar)
}
override fun onLoadCleared(placeholder: Drawable?) {
}
})
}
}
}
catch (e: IOException) {
e.printStackTrace()
Toast.makeText(this#EnviarMultimediaActivity, "Failed!", Toast.LENGTH_SHORT).show()
}
}
}
}
My onActivityResult is bigger but i just pasted the relevant part for videos.
If i don't try to make the copy Glide created the thumbnail and is displayed in the view.
The problem is that the copy don't work, i tried the File method copyTo and also another method implemented that receive a copy source and copy destination as parameter.
private fun copyVideoFile(sourceFile: File, destFile: File){
if (!sourceFile.exists()) {
return;
}
val source = FileInputStream(sourceFile).getChannel();
val destination = FileOutputStream(destFile).getChannel();
if (destination != null && source != null) {
destination.transferFrom(source, 0, source.size());
}
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
}
The problem is that sourceFile.exists() returns false, so no copy is done.
I tried to lod path and uri and is this:
Video uri: content://com.android.providers.downloads.documents/document/36
Video path: /document/36
I'm a bit lost as i don't understand why if the uri is correct (as Glide works) i can't create a File and make a copy to another File.
I requested permission and in my manifest i have:
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.CAMERA
android.permission.INTERNET
android.permission.READ_EXTERNAL_STORAGE
Later i have retrofit2 api that creates a post to the server where sends as multipart:
val requestBody: RequestBody = RequestBody.create(MediaType.parse("video/*"), file)
val multiPart: MultipartBody.Part = MultipartBody.Part.createFormData("file", file.name, requestBody)
val name = RequestBody.create(MediaType.parse("text/plain"), file.name);
This is why i need an instance of File. As said the copy is just a test, but the File instance i think is required (unless i have a different code in the retrofir2 api to add the file to the post request).
Any help is appreciated.