bitmap.sameAs() doesn't work on image comparison from Intent picking - android

My application checks whether the new selected image is the same as the previous one so that I don't need to update the cloud data, but newBitmap.sameAs(oldBitmap) always return false even though I pick the same photo.
Piece of my code:
private lateinit var oldBitmap: Bitmap
private lateinit var newBitmap: Bitmap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my_profile)
myProfilePictureUrl = intent.getStringExtra("myProfilePictureUrl")!!
if (myProfilePictureUrl.isNotEmpty()) {
Picasso.get().load(myProfilePictureUrl).into(my_profile_imageView)
}
oldBitmap = (my_profile_imageView.drawable as BitmapDrawable).bitmap //for later comparison
my_profile_imageView.setOnClickListener {
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, RESULT_CODE_PICK_IMAGE)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RESULT_CODE_PICK_IMAGE && resultCode == Activity.RESULT_OK) {
val inputStream = contentResolver.openInputStream(data!!.data!!)
val bitmap = BitmapFactory.decodeStream(inputStream)
newBitmap = bitmap //for comparison
my_profile_imageView.setImageBitmap(bitmap)
}
}
And when the user click on the "save" button on the action bar will it first check whether they are the same photo:
private fun updateProfile(nickname: String) {
if (this::newBitmap.isInitialized && !newBitmap.sameAs(oldBitmap)) { //here
//upload task code
}
}
THE PROBLEM IS:
!newBitmap.sameAs(oldBitmap) always return false even they are the same photo, may be the problem of PICASSO? Or the way I used to compare is not right. Any help would be appreciated.

Related

Validation Not Working When Checking If ImageButton Is Empty

Using Kotlin in Android Studio, I created a form where user can fill in necessary details AND click an imageButton to launch the camera, take picture and submit the form. I want to add a validation where the user is prevented from submitting the form if they did not take a photo.
I have tried to validate by using imageButton.drawable == null but it did not display the error toast.
Here are the relevant parts of my codes:
class FormActivity : AppCompatActivity() {
var selectedPhotoUri : Uri? = null
companion object {
const val REQUEST_FROM_CAMERA = 1001
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_artactivity)
...
val imageButton = findViewById<ImageButton>(R.id.imageButton)
// launch camera
imageButton.setOnClickListener {
takePhotoUsingCamera()
}
val submitButton = findViewById<Button>(R.id.submitButton)
submitButton.setOnClickListener {
submitForm(userId.toString(), HRWAnswer, ResultAnswer)
}
}
private fun takePhotoUsingCamera(){
ImagePicker.with(this).cameraOnly()
.crop()
.start(REQUEST_FROM_CAMERA)
}
// to access the image captured
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
when (requestCode){
REQUEST_FROM_CAMERA -> {
selectedPhotoUri = data!!.data
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, selectedPhotoUri)
val bitmapDrawable = BitmapDrawable(bitmap)
val imageButton = findViewById<ImageButton>(R.id.imageButton)
imageButton.setImageDrawable(bitmapDrawable)
}
}
}
}
fun submitForm(userId : String, TestOption: String, ResultOption: String){
...
val imageButton = findViewById<ImageButton>(R.id.imageButton)
if (imageButton.drawable == null) {
Toast.makeText(this, "Image of your Test result is required!", Toast.LENGTH_LONG).show()
imageButton.requestFocus()
}
...
}
}
Check this may it helps you.
class FormActivity : AppCompatActivity() {
lateinit var imageButton : ImageButton//HERE YOU NEED TO ADD BUTTON.Dont add buttons initialization multiple time in once class.
var selectedPhotoUri : Uri? = null
companion object {
const val REQUEST_FROM_CAMERA = 1001
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_artactivity)
...
imageButton = findViewById<ImageButton>(R.id.imageButton)
// launch camera
imageButton.setOnClickListener {
takePhotoUsingCamera()
}
val submitButton = findViewById<Button>(R.id.submitButton)
submitButton.setOnClickListener {
submitForm(userId.toString(), HRWAnswer, ResultAnswer)
}
}
private fun takePhotoUsingCamera(){
ImagePicker.with(this).cameraOnly()
.crop()
.start(REQUEST_FROM_CAMERA)
}
// to access the image captured
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
when (requestCode){
REQUEST_FROM_CAMERA -> {
selectedPhotoUri = data!!.data
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, selectedPhotoUri)
val bitmapDrawable = BitmapDrawable(bitmap)
val imageButton = findViewById<ImageButton>(R.id.imageButton)
imageButton.setImageDrawable(bitmapDrawable)
}
}
}
}
fun submitForm(userId : String, TestOption: String, ResultOption: String){
...
if (imageButton.drawable == null) {
Toast.makeText(this, "Image of your Test result is required!", Toast.LENGTH_LONG).show()
imageButton.requestFocus()
}
...
}
}
as stated by Mike M. in the comment above, it will never be null due to its drawable set layout. i have changed my approach to achieve my target outcome.

registerForActivityResult and onActivityResult onActivityResult in Kotlin

I am currently trying to learn from a step-by-step tutorial to upload an Image or File to my server while using Volley. This tutorial is a little bit outdated and I really don't understand how I can fix these issues.
the tutorial
onActivityResult(Int, Int, Intent?): Unit' is deprecated. Deprecated in Java
Fragment is attempting to registerForActivityResult after being created. Fragments must call registerForActivityResult() before they are created (i.e. initialization, onAttach(), or onCreate()).
My code
//Uploading Photos
private fun launchGallery() {
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
var resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// There are no request codes
val data: Intent? = result.data
}
}
}
private fun uploadImage() {
imageData?: return
val request = object : VolleyFileUploadRequest(
Request.Method.POST,
postURL,
{
println("response is: $it")
},
{
println("error is: $it")
}
) {
override fun getByteData(): MutableMap<String, FileDataPart> {
var params = HashMap<String, FileDataPart>()
params["imageFile"] = FileDataPart("image", imageData!!, "jpeg")
return params
}
}
Volley.newRequestQueue(requireContext()).add(request)
}
#Throws(IOException::class)
private fun createImageData(uri: Uri) {
val inputStream = requireContext().contentResolver.openInputStream(uri)
inputStream?.buffered()?.use {
imageData = it.readBytes()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK && requestCode == IMAGE_PICK_CODE) {
val uri = data?.data
if (uri != null) {
imageView.setImageURI(uri)
createImageData(uri)
}
}
super.onActivityResult(requestCode, resultCode, data)
}
}
you are trying to registerForActivityResult from a method "launchGallery()" which is not the way it should be done, "registerForActivityResult" should be initialized in the Activity/Fragment onCreate function and then you can use the "resultLauncher" variable to open the gallery/camera etc...
also when you are using the "registerForActivityResult" you don't need to override "onActivityResult" (which is now deprecated).
check the Activity Result Api to get a better understanding of how the new api works.
and here is a good tutorial that shows you how to use the Android Activity Result API for selecting and taking images

how to get gallery image path with an Intent

In my android application, I am trying to let the user select a gallery image and show a high-quality image in another activity. is there a way to get an absolute path from URI? or is there an efficient way to do this?
This function opens the gallery and lets the user select an image:
private fun getGalleryImage() {
val galleryImageIntent =
Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
if (galleryImageIntent.resolveActivity(requireActivity().packageManager) != null) {
startActivityForResult(galleryImageIntent, REQUEST_GALLERY_IMAGE)
}
}
And the following gets the result, but I am not sure how to get the image path
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_GALLERY_IMAGE && resultCode == RESULT_OK) {
startActivity(
Intent(context, ImageViewActivity::class.java).putExtra(
"imagePath",
data?.data?.toString()
)
)
} else
super.onActivityResult(requestCode, resultCode, data)
}
Here is my ImageViewActivity:
class ImageViewActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_image_view)
backBtn.setOnClickListener {
finish()
}
val imagePath = intent?.extras?.get("imagePath")
BitmapFactory.decodeFile(imagePath?.toString())?.also { bitmap ->
imageHolder.setImageBitmap(bitmap)
}
}
}
I tried sending the bitmap itself to my ImageViewActivity but it keeps crashing, and from what I read online, it is not possible to send large amount of data to an Activity.

How can I extract Info from an selected mp3 file?

I want to get some info like artist, duration and title from a selected mp3 file.But I seem to get something wrong. I just get some random numbers and that is not what I hoped for. I am thankful for every help I get.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_music)
SelectTrack()
}
private fun SelectTrack() {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "audio/mpeg"
startActivityForResult(intent, 0)
}
var selectedTrackUri: Uri? = null
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 0 && resultCode == Activity.RESULT_OK && data !=null) {
selectedTrackUri = data.data
val title = MediaMetadataRetriever.METADATA_KEY_TITLE.toString()
val duration = MediaMetadataRetriever.METADATA_KEY_DURATION.toString()
val artist = MediaMetadataRetriever.METADATA_KEY_ARTIST.toString()
AddTrackName_txt.text = title
AddArtistName_txt.text = artist
AddTrackLength_txt.text = duration
//Picasso.get().load(album).into(AddTrackPic_View)
}
}
}
The problem is in the way you retrieve the metadata of the file, you are assigning the values of the keys used to extract the metadata, not reading the actual data from the MediaMetadataRetriever.
Example
private fun selectTrack() {
val intent = Intent(Intent.ACTION_GET_CONTENT).apply { type = "audio/mpeg" }
startActivityForResult(intent, RC_MEDIA_FILE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
super.onActivityResult(requestCode, resultCode, intent)
if (requestCode == RC_MEDIA_FILE && resultCode == Activity.RESULT_OK && intent != null) {
val mmr = MediaMetadataRetriever()
mmr.setDataSource(this, intent.data)
val title = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)
val artist = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)
val duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
Log.d("MP3", "title=$title, artist=$artist, duration=$duration")
}
}
companion object {
const val RC_MEDIA_FILE = 100
}
Output
D/MP3: title=Sweet Child O´Mine, artist=Guns N' Roses, duration=356444

Using Kotlin to pass Image from ImageView to another Activity in Android

How to pass Image selected in ImageView to another Activity in Android using Kotlin ?
This is the way to select the Image inside the ImageView using internal Storage and I need to pass the image to another activity
fun Loadimage()
{
var intent = Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intent,ImageCode)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode==ImageCode && data!=null && resultCode== Activity.RESULT_OK)
{
val selectedImage = data.data
val filepath = arrayOf(MediaStore.Images.Media.DATA)
val cursor = contentResolver.query(selectedImage,filepath,null,null,null)
cursor.moveToFirst()
val Index = cursor.getColumnIndex(filepath[0])
val Picture = cursor.getString(Index)
cursor.close()
imageView.setImageBitmap(BitmapFactory.decodeFile(Picture))
}
}
You can pass Picture variable to next activity using Intents like below
val intent = Intent(this, NextActivity::class.java)
intent.putExtra("picture", Picture)
startActivity(intent)
Then in NextActivity, in onCreate method, you can get picture using
val Picture = getIntent().getStringExtra("picture")
In the NextActivity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val postImage = findViewById<ImageView>(R.id.post_image)
myPic = postImage
}
companion object {
lateinit var myPic: ImageView()
}
And in the first Activity:
NextActivity.myPic = Picture

Categories

Resources