Save image using kotlin - android

I am new to Android development, and im making simple aplication that capture image then save. I can capture the image and show into imageview, but unfortunately i cannot save into gallery.
i tryed many ways but cannot save. this is original code to take and show.
// EDITED //
I add function to save file, but still not working
class TomarFotos : AppCompatActivity() {
lateinit var photoPath: String
val REQUEST_IMAGE_CAPTURE = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_tomar_fotos)
val foto = findViewById<Button>(R.id.tomarfotos)
foto.setOnClickListener{
tomarFoto()
}
}
fun tomarFoto() {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if(intent.resolveActivity(packageManager) != null){
var photoFile: File? = null
try{
photoFile = createImageFile()
}catch (e: IOException){}
if(photoFile != null){
val photoUri = FileProvider.getUriForFile(
this,
"com.example.android.fileprovider",
photoFile
)
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)
startActivityForResult(intent,REQUEST_IMAGE_CAPTURE)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val fotoTomada = findViewById<ImageView>(R.id.fotopreview)
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
fotoTomada.rotation = 90f
fotoTomada.setImageURI(Uri.parse(photoPath))
}
}
private fun createImageFile(): File? {
val fileName = "foto"
val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
val image = File.createTempFile(
fileName,
".jpg",
storageDir
)
photoPath = image.absolutePath
return image
}
}
i try developer.android.com already but didnt work

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val fotoTomada = findViewById<ImageView>(R.id.fotopreview)
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
val imageBitmap = data?.extras?.get("data") as Bitmap
fotoTomada.setImageBitmap(imageBitmap)
saveImage(imageBitmap)
}
}
Call this function to save image to gallery
private fun saveImage(bitmap: Bitmap) {
var outStream: FileOutputStream? = null
// Write to SD Card
try {
val dir = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator + "AppName/")
dir.mkdirs()
val fileName = "IMG_${System.currentTimeMillis()}"
val outFile = File(dir, fileName)
outStream = FileOutputStream(outFile)
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream)
outStream.flush()
outStream.close()
Toast.makeText(this#MainActivity, "Image Saved Successfully", Toast.LENGTH_LONG).show()
} catch (e: FileNotFoundException) {
Log.d("TAG", "saveImage: ${e.message}")
} catch (e: IOException) {
Log.d("TAG", "saveImage: ${e.message}")
}
}

Related

I am using image cropper library com.theartofdev.edmodo:android-image-cropper:2.8.0 it is working fine but when I am using android 12 It crashes

This below is my code It is working fine but when I am using android 12 it gives crashes ,as it is showing null in onActivityResult method. Can anyone tell me what I am doing wrong.
The intent is getting null and I don't understand why this is happening ,if normal camera intent is used is is working fine but when using this library it is crashes.
enter code here
private fun pickFromGallery() {
CropImage.activity().setGuidelines(CropImageView.Guidelines.ON).start(this#MainActivity)
}
enter code here
private fun createImageFile(imageName: String): File {
val timeStamp: String = SimpleDateFormat("ddMMyyyy").format(Date())
if (SDK_INT > Build.VERSION_CODES.Q) {
directoryPath =
File(Environment.getExternalStorageDirectory().absolutePath + File.separator + "tt1/tt")
} else {
directoryPath = File(
this.getExternalFilesDir(Environment.DIRECTORY_PICTURES + File.separator + "tt1/1tt),
""
)
}
imageDirectoryPath = File(
directoryPath!!.absolutePath,
File.separator.toString() + "${imageName}.jpg"
)
return imageDirectoryPath as File
}
enter code here
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
val result = CropImage.getActivityResult(data)
if (resultCode == RESULT_OK) {
val resultUri = result.uri
img_existingMtr.saveCroppedImageAsync(resultUri)
img_existingMtr.croppedImage
var abc=img_existingMtr.imageResource
Log.e("## cropped", abc.toString())
img_existingMtr.setImageUriAsync(resultUri)
} else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
val error = result.error
}
}
}
enter code here
private fun storeImage(image: Bitmap) {
val pictureFile: File = createImageFile("firstTest")
if (pictureFile == null) {
Log.e(
"Error",
"Error creating media file, check storage permissions: "
)
return
}
try {
val fos = FileOutputStream(pictureFile)
Log.d("## storeImage", fos.toString())
image.compress(Bitmap.CompressFormat.PNG, 90, fos)
fos.close()
} catch (e: FileNotFoundException) {
Log.d("File1", "File not found: " + e.localizedMessage)
} catch (e: IOException) {
Log.d("File2", "Error accessing file: " + e.localizedMessage)
}
}

Google ML Kit face detection can not identify faces from uri

I'm using google ml kit for face detection, then use bounding Box function to crop faces.
I successfully integrate cameras ,then want to add select from gallery function, which I successfully implement previous training app that I wrote in Java, yet I can find why App written in Kotlin can not identify image Uri from gallery.
I tried multiple methods InputImage.fromBirmap(), InputImage.fromFilePath() and InputImage.fromByteArray("use nv21"), and used Image View to display images with rotation degrees that seems perfect. You can find codes that initiated by on click method below, except InputImage.fromFilePath() and InputImage.fromByteArray("use nv21") which tried first, then delete the codes.
Also thank you before hand.
private fun selectImage() {
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 11)
}
#RequiresApi(Build.VERSION_CODES.N)
#Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
if (requestCode == 11) {
if (data != null){
val bitmap = getBitmapFromUri(data.data!!)
Log.d(TAG, "onActivityResult: ${data.data!!}")
val inputStream = contentResolver.openInputStream(data.data!!)
val exif = ExifInterface(inputStream!!)
val rotation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL
)
val rotationInDegrees: Int = exifToDegrees(rotation)
inputStream.close()
Log.d(TAG, "onActivityResult: rotation: $rotation")
if (bitmap != null) selectedImageAnalyser(bitmap, rotationInDegrees)
}
}
}
}
private fun exifToDegrees(exifOrientation: Int): Int {
return when (exifOrientation) {
ExifInterface.ORIENTATION_ROTATE_90 -> {
90
}
ExifInterface.ORIENTATION_ROTATE_180 -> {
180
}
ExifInterface.ORIENTATION_ROTATE_270 -> {
270
}
else -> 0
}
}
private fun getBitmapFromUri(uri: Uri): Bitmap? {
var bitmap: Bitmap? = null
try {
bitmap = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1) {
val source = ImageDecoder.createSource(
contentResolver, uri
)
ImageDecoder.decodeBitmap(source)
} else {
MediaStore.Images.Media.getBitmap(contentResolver, uri)
}
} catch (e: IOException) {
e.printStackTrace()
}
return bitmap
}
private fun selectedImageAnalyser(bitmap: Bitmap, rotationDegree: Int) {
val mBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true)
val inputImage = InputImage.fromBitmap(mBitmap, rotationDegree)
val rotation = inputImage.rotationDegrees
Log.d(TAG, "onActivityResult: rotation: $rotation")
binding!!.ivFace.apply {
visibility = View.VISIBLE
setImageBitmap(inputImage.bitmapInternal)
}
faceDetector.process(inputImage)
.addOnSuccessListener { faces ->
if (faces.isNullOrEmpty()){
val croppedFace = cropToBox(bitmap,faces[0].boundingBox,rotation)
startEnrollDialog(croppedFace)
} else{
Log.d(TAG, "selectedImageAnalyser: face can not identified")
}
}
.addOnFailureListener { Log.d(TAG, "selectedImageAnalyser: \n\t Cause: ${it.cause} \n\t Message: ${it.message}") }
.addOnCompleteListener { }
}

Unable to capture image in android 11

i'm trying to capture image in android 11 device but request is keep cancelled. i have added also. still unable to capture image. pick image from gallery is working. image is not storing in Android/data folder.
i have added val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) also still unable to create temp file in storage. please provide any solutions
private fun selectImage() {
imageUtils.createImageFile(applicationContext).let {
viewModel.setFileTempPath(it.absolutePath, "doc_name")
startActivityForResult(imageUtils.captureImage(applicationContext, it), 300)
}
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?
) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
300 -> when (resultCode) {
RESULT_OK -> {
Log.d("tmppath", data?.data.toString())
if (data != null && data.data != null) {
val selectedImage: Bitmap =
imageUtils.getBitmap(data.data, this#TaggingActivity)!!
viewModel.dataModel.selectedImagesArrayList.value.let {
if (it == null) {
viewModel.dataModel.selectedImagesArrayList.value = ArrayList()
}
val a = it
a?.add(
ImageDetailsToUpload(
"",
selectedImage,
Constant.CUSTOMER_GEO_TAG,
viewModel.dataModel.documentName.value,
viewModel.commonModel.currentLocation.value!!
)
)
viewModel.dataModel.selectedImagesArrayList.postValue(a)
}
} else {
if (viewModel.dataModel.tmpPath.value != null) {
imageUtils.getBitmapFromPath(viewModel.dataModel.tmpPath.value)
?.let { selectedImage ->
val a = viewModel.dataModel.selectedImagesArrayList.value
a?.add(
ImageDetailsToUpload(
"",
selectedImage,
Constant.CUSTOMER_GEO_TAG,
viewModel.dataModel.documentName.value,
viewModel.commonModel.currentLocation.value!!
)
)
viewModel.dataModel.selectedImagesArrayList.postValue(a)
} ?: run {
viewModel.commonModel.showToastTextView("Sorry Try Again..!")
}
} else {
viewModel.commonModel.showToastTextView("Sorry Try Again..!")
return
}
}
viewModel.dataModel.tmpPath.value = null
}
RESULT_CANCELED -> {
viewModel.setFileTempPath("", "")
Toast.makeText(this,"cancelled",Toast.LENGTH_LONG).show()
}
}
}
//Intent class
fun getCameraIntent(file: File): Intent {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file))
if (Build.VERSION.SDK_INT >= 24) {
try {
val m =
StrictMode::class.java.getMethod("disableDeathOnFileUriExposure")
m.invoke(null)
} catch (e: java.lang.Exception) {
e.printStackTrace()
}
} else {
takePictureIntent.putExtra("return-data", true)
takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
val pickPhoto = Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
)
val intents: ArrayList<Intent> = arrayListOf()
intents.add(takePictureIntent)
intents.add(pickPhoto)
val chooserIntent = Intent.createChooser(
intents.removeAt(intents.size - 1),
" Document Upload"
)
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents.toArray(arrayOf<Parcelable>()))
return chooserIntent
}

Download a PDF into android device download folder Android

I have the following code in my activity that I use to generate a PDF file and save it into the device storage when I click a button I call saveFileToStorageIntent()
The problem that I am finding is that it is not downloaded automatically, instead, this opens another Document provider activity with save option. I want that the pdf file saves directly into Document folder from a single click on my application. What can I do to download the pdf directly to the device?
private fun saveFileToStorageIntent() {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf")
intent.putExtra(Intent.EXTRA_TITLE, "invoice.pdf")
startActivityForResult(intent, CREATE_FILE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == CREATE_FILE) {
if (resultCode == RESULT_OK && data != null) {
writePDFToFile(data.data, presenter.ticketResponse()!!)
}
}
}
private fun writePDFToFile(uri: Uri?, body: ResponseBody) {
var inputStream: InputStream? = null
var outputStream: OutputStream? = null
try {
val fileSize = body.contentLength()
val fileReader = ByteArray(fileSize.toInt())
var fileSizeDownloaded: Long = 0
inputStream = body.byteStream()
outputStream = contentResolver.openOutputStream(uri!!)
while (true) {
val read: Int = inputStream.read(fileReader)
if (read == -1) {
break
}
outputStream?.write(fileReader, 0, read)
fileSizeDownloaded += read.toLong()
}
outputStream?.flush()
} catch (e: Exception) {
Logger.print(TAG, e.message)
} finally {
if (inputStream != null) {
try {
inputStream.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
if (outputStream != null) {
try {
outputStream.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
}
Why are you not using DownloadManager for that?
try{
Uri uri = Uri.parse(downloadPath);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI); // Tell on which network you want to download file.
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); // This will show notification on top when downloading the file.
request.setTitle("Downloading data..."); // Title for notification.
request.setVisibleInDownloadsUi(true);
request.addRequestHeader("Authorization", "bearer my bearertoken"));
request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOCUMENTS, id+".pdf");
((DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request); // This will start downloading
}catch(Exception e){
}
You can change the file path to Downloads in the above code.

Error in onActivityResult after taking image in camera

I am trying to take a picture using the camera and display the same. While the same works fine in the emulator it does not work in my samsung j5 prime device
Here is my code:
Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { cameraIntent ->
cameraIntent.resolveActivity(packageManager)?.also {
val pictureFile : File? = try {
getPictureFile()
} catch (ex: IOException) {
Toast.makeText(this,
"Photo file can't be created, please try again",
Toast.LENGTH_SHORT).show()
null
}
pictureFile ?.also {
photoURI = FileProvider.getUriForFile(
this,
"$packageName.fileprovider",
it
)
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(cameraIntent, REQUEST_CAMERA)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val imgFile = File(pictureFilePath)
Log.d("MyMessage",data.toString())
if (data != null) {
if (imgFile.exists())
{
previewbox.setImageBitmap(setScaledBitmap())
prescripPreview.visibility = View.VISIBLE
filepath = photoURI
}
}
}
When I use an emulator the log returns intent { }
But in the device the log returns null. What is the issue here?

Categories

Resources