I'm trying to follow https://developer.android.com/training/camera/photobasics to get original image size, but I got null on the 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 = 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 dispatchTakePictureIntent(numbers: Int) {
Intent(MediaStore.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
null
}
// Continue only if the File was successfully created
photoFile?.also {
val photoURI: Uri = FileProvider.getUriForFile(
this,
BuildConfig.APPLICATION_ID + ".provider",
it
)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(takePictureIntent, numbers)
}
}
}
}
onActivityResult :
val bitmap = data?.extras?.get("data") as Bitmap
strImageTabungan1 = ConvertBase64().getStringImage(bitmap)
img_1.setImageBitmap(bitmap)
I can open the camera activity, but when trying to get the result, it returns
**java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=888, result=-1, data=Intent { }} to activity {com.example.abcdef/com.example.abcdef.form.ExampleActivity}: kotlin.TypeCastException: null cannot be cast to non-null type android.graphics.Bitmap**
What's wrong with it?
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
This question already has answers here:
Having trouble implementing ACTION_OPEN_DOCUMENT to my project
(4 answers)
Closed 6 months ago.
for the last 2 days I've been trying to implement a profile picture feature into an application using Uri and it works... for android versions < 11, and this is probably the reason, so I wanted to ask, how should I handle this problem ? Should I copy the files, store them application storage and then get the Uri? The code I'm currently using is based on this:
private var currentPhotoUri: Uri = Uri.EMPTY
private var isChanged = false
// intent launcher used for the profile picture image, on result it updates the picture
private val intentLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
val photoResult: Uri? = it.data?.data
if(photoResult != null) {
// user picked from gallery
currentPhotoUri = photoResult
changeProfilePicture(photoResult) // just a function that saves the Uri with room
} else {
// user made a photo
changeProfilePicture(currentPhotoUri)
}
}
}
private fun openIntentChooserForImageSources() {
// creating gallery intent
val galleryIntent = Intent(Intent.ACTION_OPEN_DOCUMENT, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
galleryIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
// creating camera intent
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
cameraIntent.also { takePictureIntent ->
takePictureIntent.resolveActivity(requireActivity().packageManager)?.also {
val photoFile: File? = try {
createImageFile()
} catch (e: IOException){
null
}
photoFile?.also {
val photoFileUri: Uri = FileProvider.getUriForFile(
requireContext(),
requireActivity().packageName,
it
)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoFileUri)
}
}
}
val intentChooser = Intent.createChooser(galleryIntent, "Select an app")
intentChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(cameraIntent))
intentLauncher.launch(intentChooser)
}
#Throws(IOException::class)
private fun createImageFile(): File {
// Create an image file name
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val storageDir = requireActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(
"JPEG_${timeStamp}_", /* prefix */
".jpg", /* suffix */
storageDir /* directory */
).apply {
currentPhotoUri = this.toUri()
}
}
the error I get: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord (...) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
For the case where you use ACTION_OPEN_DOCUMENT, call takePersistableUriPermission() on a ContentResolver to get durable access to the content.
This question already has answers here:
Why do I get null in data parmeter of onActivityResult
(1 answer)
Android "Taking Photos Simply" tutorial does not work for me [duplicate]
(1 answer)
Closed 2 years ago.
I have this application where once the user takes a photo using the camera app, it will automatically set the ImageView in the application to that captured image. I keep getting this error and it's causing my application to crash:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {com.company.example/com.company.example.Camera}: java.lang.NullPointerException
The error occurs here, specifically the foodBitmap line:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val foodBitmap = Objects.requireNonNull(Objects.requireNonNull(data)!!.extras)!!["data"] as Bitmap
food_image.setImageBitmap(foodBitmap)
}
These are the two functions I'm using to capture the image. I have all the permissions set up properly:
private fun openCamera() {
Intent(MediaStore.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
null
}
// Continue only if the File was successfully created
photoFile?.also {
photoURI = FileProvider.getUriForFile(
Objects.requireNonNull(applicationContext),
BuildConfig.APPLICATION_ID + ".provider",
photoFile
)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(takePictureIntent, 1)
}
}
}
}
#Throws(IOException::class)
private fun createImageFile(): File {
// Create an image file name
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val storageDir: File? = 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
}
}
What am I doing wrong here? Why is data in onActivityResult null?
I m desperated. I have 16 TextViews. The goal is to take a picture of a prescription. What I want is to extract the right text for every Textview I have. This is my last problem.
Here is the code of taking a photo, create a file, recognize the text and put it in a TextView.
private fun dispatchTakePictureIntent() {
Intent(MediaStore.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
null
}
// Continue only if the File was successfully created
photoFile?.also {
photoURI = FileProvider.getUriForFile(
this,
"com.example.android.fileprovider2",
it
)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO)
/*if (REQUEST_TAKE_PHOTO == 1)
{
return imageView.setImageURI(photoURI)
}*/
}
}
}
}
#Throws(IOException::class)
private fun createImageFile(): File {
// Create an image file name
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val storageDir: File? = 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
}
}
fun startRecognizing(v: View) {
if (imageView.drawable != null) {
editText.setText("")
v.isEnabled = false
val bitmap = (imageView.drawable as BitmapDrawable).bitmap
val image = FirebaseVisionImage.fromBitmap(bitmap)
val detector = FirebaseVision.getInstance().onDeviceTextRecognizer
detector.processImage(image)
.addOnSuccessListener { firebaseVisionText ->
v.isEnabled = true
processResultText(firebaseVisionText)
}
.addOnFailureListener {
v.isEnabled = true
editText.setText("Failed")
}
} else {
Toast.makeText(this, "Select an Image First", Toast.LENGTH_LONG).show()
}
}
private fun String.toEditable(): Editable = Editable.Factory.getInstance().newEditable(this)
private fun processResultText(resultText: FirebaseVisionText) {
if (resultText.textBlocks.size == 0) {
editText.setText("No Text Found")
return
}
for (blocks in resultText.textBlocks) {
val blockText = blocks.text
val stringText = resultText.text
val stringTextSplit = stringText.lines()
krankenkasse.text = stringTextSplit[1].toEditable()
et2.text = stringTextSplit[4].toEditable()
et3.text = stringTextSplit[5].toEditable()
et4.text = stringTextSplit[6].toEditable()
et5.text = stringTextSplit[7].toEditable()
et6.text = stringTextSplit[8].toEditable()
et7.text = stringTextSplit[9].toEditable()
et8.text = stringTextSplit[11].toEditable()
editText.append(blockText + "\n")
}
}
If you have questions. Please ask.
If you want to detect some specific regions in the image, you could crop the image based on the regions, and send the cropped images into ML Kit.
Another option is to detect the whole image, but filter out texts which are not in the regions. Each detected text has its own bounding box coordinates.
https://firebase.google.com/docs/reference/android/com/google/firebase/ml/vision/text/FirebaseVisionText.TextBlock#getBoundingBox()
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)
}
}