I have two buttons, one to select an image from the gallery and one to take a picture with your camera. The part to select it from gallery is working perfectly.
But when the user captures an image with the CameraIntent I am not able to get the URI.
Code:
var uri_path : Uri? = null;
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && requestCode == 1000) {
println("DATA " + data?.data)
uri_path = data?.data;
findViewById<ImageView>(R.id.selected_image).setImageURI(data?.data);
}
if (resultCode == Activity.RESULT_OK && requestCode == 1001) {
//val ImageView = findViewById<ImageView>(R.id.selected_image);
val photo = data!!.extras!!["data"] as Bitmap?
val values = ContentValues()
values.put(MediaStore.Images.Media.TITLE, "Title")
values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera")
uri_path = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
/*
ATTEMPT 2:
Error: Caused by: java.lang.NullPointerException: MediaStore.Images.Media.…, inImage, "Title", null) must not be null
uri_path = photo?.let { getImageUri(applicationContext, it) };
*/
println("PATH " + uri_path);
findViewById<ImageView>(R.id.selected_image).setImageBitmap(photo)
}
}
fun getImageUri(inContext: Context, inImage: Bitmap): Uri? {
val bytes = ByteArrayOutputStream()
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes)
val path: String = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null)
return Uri.parse(path)
}
requestCode 1000 is for the gallery and works, 1001 is to take the picture from the camera and fails.
The uri_path value is NULL. The picture is displayed in the ImageView though. How can I get the image URI from the captured image?
Thanks!
Related
I need to save the image that is taken from camera or image taken from gallery in kotlin. for now I've done this part and i'm finding other examples in kotlin but i'm unable to find. In other examples, images were send in multipart which was coded in java.
These are listeners
private val cameraRequest = 1888
private val pickImage = 100
private var imageUri: Uri? = null
takePhoto.setOnClickListener {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(cameraIntent, cameraRequest)
}
choosePicture.setOnClickListener {
val gallery = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
startActivityForResult(gallery, pickImage)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == cameraRequest) {
val photo: Bitmap = data?.extras?.get("data") as Bitmap
takePhoto.setImageBitmap(photo)
}
if (resultCode == RESULT_OK && requestCode == pickImage) {
imageUri = data?.data
if (imageUri != null) {
choosePicture.setImageURI(imageUri)
}
}
}
You can use this library for making a multipart request: https://github.com/gotev/android-upload-service
Also, it will handle app behaviour for you which includes upload-retry on slow internet connection and many more.
I am opening my phones camera, taking a photo, showing a 50px snippet then saving an image into FirebaseFireStore Storage.
The image is very pixelated when I download it from FireStore. Can someone have a look at my code to see were I am going wrong please?
Perhaps I am saving the 50px image, whereas I would like to save the image that was taken from the camera.
Variable
val REQUEST_CODECAM = 200
var bitmapPhoto: Bitmap? = null
Open the Camera
binding!!.galleryContainer.setOnClickListener { v: View? ->
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(cameraIntent, REQUEST_CODECAM)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODECAM && data != null){
bitmapPhoto = data.extras?.get("data") as Bitmap
// Image is shown in 50px ListView cell
binding!!.issueImage.setImageBitmap(data.extras?.get("data") as Bitmap)
//imageUri = data.data
//Picasso.get().load(imageUri).into(binding!!.issueImage)
}
}
Save Button Pressed...
fun saveImage(action: GenericAction?) {
val imageName = UUID.randomUUID().toString()
val imageReference = FirebaseStorage.getInstance().reference.child("partInfoImagesFolder").child(imageName)
val baos = ByteArrayOutputStream()
bitmapPhoto.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val data = baos.toByteArray()
var uploadTask = imageReference.putBytes(data)
uploadTask.addOnFailureListener {
// Handle unsuccessful uploads
}.addOnSuccessListener { taskSnapshot ->
// taskSnapshot.metadata contains file metadata such as size, content-type, etc.
// ...
imageReference.downloadUrl.addOnCompleteListener { task1: Task<Uri?>? ->
if (task1 != null) {
if (task1.isSuccessful()) {
saveCollOfURLString = task1.getResult().toString()
action?.onCallback()
}
}
}
}
}
I have an activity from which I launch the gallery, select an image, and want to display the selected image in another activity. I have referred to the following solution and implemented the same.
How to get Image URI from Gallery?
Though I am able to pass the URI to the next activity, I cannot see anything on the image view. Any help as to where I am going wrong, appreciated.
btn_launch_gallery.setOnClickListener {
val requestCode = 0
val launchGalleryIntent = Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(launchGalleryIntent, requestCode)
}
My OnActivityResult looks like this, basically implemented the same as given in the example cited above.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode === 0 && resultCode === Activity.RESULT_OK ) {
val selectedImage: Uri? = data?.data
val picturePath = getRealPathFromURI(
selectedImage,
this
)
val intent = Intent(this, LogFoodDetail::class.java)
intent.putExtra("image_from_gallery", picturePath)
try {
startActivity(intent)
}
catch (e: Exception)
{
e.printStackTrace()
Log.e("Error",e.printStackTrace().toString())
}
}
}
fun getRealPathFromURI(contentURI: Uri?, context: Activity): String? {
val projection =
arrayOf(MediaStore.Images.Media.DATA)
val cursor = context.managedQuery(
contentURI, projection, null,
null, null
)
?: return null
val column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
return if (cursor.moveToFirst()) {
// cursor.close();
cursor.getString(column_index)
} else null
// cursor.close();
}
In my next activity, I getting the intent like this and passing the URI to ImageView. However, I cannot see the image. I get the following error - W/System.err: java.io.FileNotFoundException: No content provider: /storage/emulated/0/DCIM/Camera/***.jpg
val resId = intent.getStringExtra("image_from_gallery")
val imgThumbnail: ImageView = findViewById(R.id.food_thumbnail)
try{
val imageStream: InputStream? = contentResolver.openInputStream(Uri.parse(resId))
val bitmap = BitmapFactory.decodeStream(imageStream)
imgThumbnail.setImageBitmap(bitmap)
}
catch (e: Exception)
{
e.printStackTrace()
}
I see the following image in the next activity:
UPDATE:
As commented by #blackapps in his answer passing the URI as a string to the next activity on an intent.putExtra() and resolving the URI in the subsequent activity solved it, the updated code in OnActivityResult() is,
...
val selectedImage: Uri? = data?.data
val intent = Intent(this, LogFoodDetail::class.java)
intent.putExtra("image_from_gallery",
selectedImage.toString())
startActivity(intent)
Dont convert a nice uri to a file system path.
Uri uri = data.getData();
Pass the obtained uri directly to the next activity.
And there you can use it for
imageView.setImageUri(uri);
Instead of the uri you can also pass the uri as string with uri.toString().
You can directly load an local image Uri using:
imgThumbnail.setImageUri(yourUri);
Instead of sending the string path to the activity, you should send the raw uri and then set it directly to the imageView.
I am getting these errors when I am uploading images. The path is storing in database table, But the image folder does not have image.
These are the errors
E/ErrorUtil: Error: /document/primary:DCIM/Camera/20190804_111501.jpg (No such file or directory)
W/System.err: java.io.FileNotFoundException: /document/primary:DCIM/Camera/20190804_111501.jpg (No such file or directory)
Here I shared my code.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == PICK_IMAGE_MULTIPLE && resultCode == Activity.RESULT_OK
&& null != data) {
if(data.getClipData() != null) {
val count = data.getClipData().getItemCount(); //evaluate the count before the for loop --- otherwise, the count is evaluated every loop.
for(i in 0..count-1) {
val imageUri : Uri = data.getClipData().getItemAt(i).uri
// getRealPathFromURI(applicationContext,imageUri)
imageUri.let {
Log.d("imageUri",it.toString())
Log.d("imagePath",it.path)
file = File(it.path)
val jj=Gson()
Log.d("fileIS",jj.toJson(file))
fileType = EnumUtils.FileType.IMAGE.value
val name = file!!.name
Log.d("fimenameis",name)
multipartArray!!.add(MultipartBody.Part.createFormData("files[]", file!!.name, RequestBody.create(MediaType.parse(file!!.path.getMimeType()?: ""), file!!)))
val s = Gson()
Log.d("multipartArray",s.toJson(multipartArray).toString())
}
}
//do something with the image (save it to some directory or whatever you need to do with it here)
} else if(data.getData() != null) {
val imagePath = data.getData().getPath();
fileType = EnumUtils.FileType.IMAGE.value
file = File(imagePath)
multipartArray!!.add(MultipartBody.Part.createFormData("files[]", file!!.name, RequestBody.create(MediaType.parse(file!!.path.getMimeType()?: ""), file!!)))
Log.d("imagePath",imagePath.toString())
//do something with the image (save it to some directory or whatever you need to do with it here)
}
}
yes it happen some time due to file path does not get the absolute path and failed to convert it into file
` private fun getRealPathFromURI(contentURI: Uri): String? {
val result: String?
val cursor = contentResolver.query(contentURI, null, null, null, null)
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentURI.path
} else {
cursor.moveToFirst()
val idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
result = cursor.getString(idx)
cursor.close()
}
return result
}`
val file: File = File(getRealPathFromURI(Uri.parse(imagePath)))
Launch photo picker using Intent.ACTION_GET_CONTENT
Retrieve URI of selected item
Retrieve PATH of URI so that I can POST it to my webserver
Code to launch browse
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, BROWSE_IMAGE_REQUEST_CODE);
Code to retrieve selected image
if (RESULT_OK == resultCode &&
BROWSE_IMAGE_REQUEST_CODE == requestCode) {
Uri uri = data.getData();
Code to send to the webserver
File file = new File(uri.getPath());
new FileSystemResourceFile(file);
I am currently able to retrieve the PATH from the URI no prob /external/images/media/24 but for some weird reason file is always null, help please?
I've done this method to convert Uri from Intent.ACTION_GET_CONTENT to real path:
public static String getRealPathFromUri(Activity activity, Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = activity.managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
Which in turn converted into File:
Uri filePathFromActivity = (Uri) extras.get(Intent.EXTRA_STREAM);
filePathFromActivity = Uri.parse(FileUtil.getRealPathFromUri( (Activity) IntentActivity.this, filePathFromActivity));
File imageFile = new File(filePathFromActivity.getPath());
I know its been a long time since the answer, but I faced the same wall and this is the solution I ended up with. The main benefit of this code is that avoids having parametrized (and hard-coded) all possible providers types and locations across all different android versions.
val act = getActivity() as Activity
object: AsyncTask<Uri, Void, File?>() {
override fun doInBackground(uris: Array<Uri>): File? {
if(act.isFinishing()) return null
try {
val dir = act.getCacheDir()
val file = File.createTempFile("PREFIX", "SUFFIX", dir)
val inputStream = act.getContentResolver().openInputStream(uris[0])
val fos = FileOutputStream(file)
BitmapFactory.decodeStream(inputStream)
.compress(Bitmap.CompressFormat.JPEG, 90, fos)
return file
} catch(e: Exception) { e.printStackTrace() }
return null
}
override fun onPostExecute(result: File?) {
result?.let { doSomethingWithFile(it) }
}
}.execute(uri)
I put it wrapped inside of an AsyncTask for the purpose of leaving unblocked ui thread during bitmap compress. Please be aware that using Bitmap.CompressFormat.JPEG means lossing alpha channel.
Hope it helps!
Pick any file using System File Picker:
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
startActivityForResult(intent, 1)
onActivityResult:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
val file = data?.data?.let {
getFileFromUri(requireContext().contentResolver, uri, requireContext().cacheDir)
}
}
}
Get File:
private fun getFileFromUri(contentResolver: ContentResolver, uri: Uri, directory: File): File {
val file =
File.createTempFile("suffix", "prefix", directory)
file.outputStream().use {
contentResolver.openInputStream(uri)?.copyTo(it)
}
return file
}