I used this method to get file from uri, it is work fine with all devices but only crash with samsung devices!
fun Activity.getFilePath(uri: Uri): File {
var cursor: Cursor? = null
return try {
val dataArray = arrayOf(MediaStore.Images.Media.DATA)
cursor = contentResolver.query(uri, dataArray, null, null, null)
val index = cursor?.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor?.moveToFirst()
File(index?.let { cursor?.getString(it) })
} catch (e: Exception) {
throw KotlinNullPointerException("File not founded")
} finally {
cursor?.close()
}
}
get image from gallery
fun Activity.chooseImageFromGallery(withAskPermission: Boolean) {
if (isPermissionsGranted(Manifest.permission.READ_EXTERNAL_STORAGE)) {
val intent = Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST)
} else {
if (withAskPermission && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
PICK_IMAGE_REQUEST)
}
}
}
on Activity result
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE_REQUEST) {
uri = data?.data
file = uri?.let { activity?.getFilePath(it) }
//
}
}
Related
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
}
I am currently using the following code here:
val cameraRequestCode = 1
val cameraPermissionCode = 1
var imageUri : Uri? = null
#RequiresApi(api = Build.VERSION_CODES.M)
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?
) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == cameraRequestCode) {
if (resultCode == Activity.RESULT_OK) {
var stream: FileOutputStream? = null
try {
val photo: Bitmap =
MediaStore.Images.Media.getBitmap(contentResolver, imageUri)
val saveFilePath: String = getRealPathFromURI(imageUri)
stream = FileOutputStream(saveFilePath)
photo.compress(Bitmap.CompressFormat.JPEG, 25, stream)
} catch (e: IOException) {
e.printStackTrace()
Toast.makeText(
applicationContext,
"Can't save image !",
Toast.LENGTH_SHORT
).show()
} finally {
try {
if (stream != null) {
stream.close()
Toast.makeText(
applicationContext,
"Image saved successfully !",
Toast.LENGTH_SHORT
).show()
} else {
Toast.makeText(
applicationContext,
"Can't save image, try again !",
Toast.LENGTH_SHORT
).show()
}
} catch (e: IOException) {
e.printStackTrace()
}
}
farmersPixImageView.setImageURI(imageUri)
} else if (resultCode == Activity.RESULT_CANCELED) {
Toast.makeText(applicationContext, "Cancelled", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(applicationContext, "Can't capture image !", Toast.LENGTH_SHORT)
.show()
}
}
}
private fun getRealPathFromURI(contentUri: Uri?): String {
val proj = arrayOf(MediaStore.Images.Media.DATA)
val cursor: Cursor = managedQuery(contentUri, proj, null, null, null)
val column_index: Int = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor.moveToFirst()
return cursor.getString(column_index)
}
#RequiresApi(Build.VERSION_CODES.M)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add)
farmersPixImageView.setOnClickListener {
//if system os is Marshmallow or Above, we need to request runtime permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.CAMERA)
== PackageManager.PERMISSION_DENIED ||
checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_DENIED
) {
//permission was not enabled
val permission = arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
//show popup to request permission
requestPermissions(permission, cameraPermissionCode)
} else {
val values = ContentValues()
values.put(
MediaStore.Images.Media.TITLE,
"${relativeFileName}_${System.currentTimeMillis()}"
)
values.put(
MediaStore.Images.Media.DISPLAY_NAME,
"${relativeFileName}_${getDate(
System.currentTimeMillis(),
"MM/dd/yyyy hh:mm:ss.SSS"
)}"
)
values.put(MediaStore.Images.Media.DESCRIPTION, "My Photos")
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
imageUri = contentResolver.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values
)
val cameraIntent =
Intent(MediaStore.ACTION_IMAGE_CAPTURE)
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
startActivityForResult(cameraIntent, cameraRequestCode)
}
}
}
}
I am using this because I could not get the sample from the Official Documentation to work.
I previously used:
values.put(MediaStore.Images.Media.RELATIVE_PATH, relativeLocation)
but it is only available on Android Q onwards.
I also don't know how to use imageUri to save to custom location because it using contentResolver:
imageUri = contentResolver.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values
)
How do I save the photo on custom location using the above code?
I have tried to use the WebView to upload one single file and it works well. However, once I selected more than 1 file and upload, the program crashed. The code is below:
override fun onActivityResult(
requestCode: Int, resultCode: Int,
intent: Intent?
) {
super.onActivityResult(requestCode, resultCode, intent)
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == mUploadMessage || requestCode != FILECHOOSER_RESULTCODE) return
var results: Array<Uri>? = null
if (resultCode === Activity.RESULT_OK) {
if (intent != null) {
val dataString = intent.dataString
val clipData = intent.clipData
if (clipData != null) {
for (i in 0 until clipData.itemCount) {
val item = clipData.getItemAt(i)
results!![i] = item.uri //Here is the crash point
}
}
if (dataString != null) results =
arrayOf(Uri.parse(dataString))
}
}
mUploadMessage!!.onReceiveValue(results)
mUploadMessage = null
return
}
}
And here is the code in WebChromeClient():
override fun onShowFileChooser(
view: WebView,
filePathCallback: ValueCallback<Array<Uri>>,
fileChooserParams: FileChooserParams
): Boolean {
if (mUploadMessage!= null) {
mUploadMessage!!.onReceiveValue(null);
mUploadMessage = null;
}
mUploadMessage = filePathCallback
val intent = fileChooserParams.createIntent()
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
intent.setType("*/*")
startActivityForResult(intent, FILECHOOSER_RESULTCODE)
return true
}
From the logcat I can see the crash point is results!![i] = item.uri when I get the uri from clipData in the For loop in OnActivityResult. I have comment on that code line. The crash message is "kotlin.KotlinNullPointerException".
I found the solution.
Just need to initialize the results:
results= Array(clipData.itemCount, {clipData.getItemAt(0).uri})
I am trying to select an image in an activity but as soon as I click to select, I get to the Device Folder but it has no picture in it. Please see my code below:
class AddPainting : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_painting)
}
fun select(view: View) {
if(checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 2);
} else {
val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 1);
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if(requestCode == 2) {
if(grantResults.size > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
val intent = Intent(Intent.ACTION_PICK);
intent.type = "image/*";
startActivityForResult(intent, 1);
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if(requestCode == 1 && requestCode == Activity.RESULT_OK && data != null) {
val image = data.data;
try{
val selectedImage = MediaStore.Images.Media.getBitmap(this.contentResolver, image);
imageView.setImageURI(data?.data);
}catch (e: Exception) {
e.printStackTrace();
}
}
super.onActivityResult(requestCode, resultCode, data)
}
fun save(view: View) {
}
}
This is what I see when it transfers me to pick a picture
Use your selectedImage bitmap to set in ImageView
imageView.setImageURI(data?.data);
to
imageView.setImageURI(selectedImage);
I need help. On my onCreate() I have this code:
takePhotoDialog = DialogGetPhotoFrom.getInstance().apply {
setListener(object : DialogGetPhotoFrom.DialogListener {
override fun onTakeFromGallery() {
Log.v("ProjectDetails", "onTakeFromGallery called")
val intent = Intent().apply {
type = "image/*"
action = Intent.ACTION_GET_CONTENT
}
startActivityForResult(Intent.createChooser(intent, "Select Image"), REQUEST_PICK_IMAGE)
}
override fun onTakePhoto() {
dispatchTakePictureIntent()
}
})
}
projectDetails_pickImage.setOnClickListener { takePhotoDialog?.show(supportFragmentManager) }
An on my onActivityResult, I wrote:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_PICK_IMAGE -> {
Log.v("ProjectDetails", "REQUEST_PICK_IMAGE called")
if (resultCode == Activity.RESULT_OK) {
if (data != null) {
try {
val inputStream = contentResolver.openInputStream(data.data)
val bitMap = BitmapFactory.decodeStream(inputStream)
projectDetails_image.setImageBitmap(bitMap)
// TODO Save image URI to database
} catch (e: Exception) {
Toast.makeText(this, "Can't set background.", Toast.LENGTH_SHORT).show()
}
} else {
Log.v("ProjectDetails", "data is null")
}
}
}
}
}
The problem is, onActivityResult() doesn't fire when an image is selected. What should I do?
Solved it! The solution is to put the codes inside my onTakeGallery() function to a function that belongs to the Activity class. So my code will look like this:
takePhotoDialog = DialogGetPhotoFrom.getInstance().apply {
setListener(object : DialogGetPhotoFrom.DialogListener {
override fun onTakeFromGallery() {
dispatchSelectFromGalleryIntent()
}
override fun onTakePhoto() {
dispatchTakePictureIntent()
}
})
}
projectDetails_pickImage.setOnClickListener {
takePhotoDialog?.show(supportFragmentManager)
}
And the extracted codes goes here:
private fun dispatchSelectFromGalleryIntent() {
val intent = Intent().apply {
type = "image/*"
action = Intent.ACTION_GET_CONTENT
}
startActivityForResult(Intent.createChooser(intent, "Select Image"), REQUEST_PICK_IMAGE)
}