Although everything work as intended and I get results from the Places API, the onActivityResult callback is never called when the user selects a result. What happens is that the result appears in the search textview and the Autocomplete activity doesn't exit. I have to press back for it to close.
// Set the fields to specify which types of place data to return.
val fields = Arrays.asList(Place.Field.ID, Place.Field.NAME)
// Start the autocomplete intent.
val intent: Intent = Autocomplete.IntentBuilder(
AutocompleteActivityMode.OVERLAY, fields
).setTypeFilter(TypeFilter.ADDRESS).
setCountry("DE")
.build(requireContext())
startActivityForResult(intent, AUTOCOMPLETE_REQUEST_CODE)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if(data!=null) {
var status: Status = getStatusFromIntent(data)
//var place: Place = getPlaceFromIntent(data)
}
super.onActivityResult(requestCode, resultCode, data)
}
Do you run method startActivityForResult inside Fragment? Check this out: onActivityResult is not being called in Fragment
You have to override onActivityResult in Activity which contains your fragment.
// In your activity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
This will call your fragment's onActivityResult()
Ensure you're using the latest version of Place client SDK Places 2.1.0
. I don't see any reason in your code that causes the behavior you've addressed. Just use the below implementation and try.
private fun pickNewPlace() {
if (!Places.isInitialized()) {
Places.initialize(context!!, getString(R.string.google_service_api_key))
}
// Set the fields to specify which types of place data to return.
val fields = listOf(Place.Field.ID, Place.Field.NAME)
// Start the autocomplete intent.
val intent = Autocomplete.IntentBuilder(
AutocompleteActivityMode.OVERLAY, fields
).setTypeFilter(TypeFilter.ADDRESS).setCountry("DE").build(context!!)
startActivityForResult(intent, REQUEST_CODE_DEFAULT)
}
onActivityResult result handling
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_DEFAULT) {
if (resultCode == RESULT_OK) {
// Get relevent info from place object
val place = Autocomplete.getPlaceFromIntent(data!!)
} else if (resultCode == AutocompleteActivity.RESULT_ERROR) {
val status = Autocomplete.getStatusFromIntent(data!!)
showAlertMessage(status.statusMessage ?: getString(R.string.something_went_wrong))
}
}
}
Related
I am trying to learn Kotlin and I'm building a simple example as I go. I have 3 image buttons that open the camera and take a photo. The thumbnail is then set into an ImageView. I've used the examples from https://developer.android.com/training/camera/photobasics?hl=en to get the basics working (figuring if I can make it work for one, it'll work for all. It does indeed work for one, but I can't figure out how to make it one function that drops the thumbnail into the correct ImageView.
Inside my onCreate I have the listener for each of the buttons that will invoke the camera:
camRead1.setOnClickListener {dispatchTakePictureIntent() }
camRead2.setOnClickListener {dispatchTakePictureIntent() }
camRead3.setOnClickListener {dispatchTakePictureIntent() }
And I took the sample from the url above:
val REQUEST_IMAGE_CAPTURE = 1
private fun dispatchTakePictureIntent() {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
try {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
} catch (e: ActivityNotFoundException) {
// display error state to the user
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val thumb: ImageView = findViewById(R.id.thumbRead1)
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
val imageBitmap = data.extras.get("data") as Bitmap
thumb.setImageBitmap(imageBitmap)
}
}
and pasted it into my class MainActivity, and after I replaced imageView in the override function with a variable (thumb) and added the super, it worked perfectly for the first one.
However, I am trying to get 3 photos, read1, read2, and read3 which each need to display the thumb in thumbRead1, thumbRead2 and thumbRead3. I can't figure out how the onActivityResult is executed since the call inside dispatchTakePictureIntent is calling startActivityForResult (especially as Android Studio says that startActivityForResult is deprecated).
Obviously, once onActivityResult executes, I can see that thumb defines R.id.thumbRead1 and receives imageBitmap but I don't understand how I can make it aware of the button that was clicked.
Without understanding how onActivityResult is called, I'm thinking that if I can do something like:
findViewById(R.id("thumbRead" + imgID))
to define the specific ImageView that I want the photo pasted into. Am I on the right track here? If not, what is the recommended way of doing this?
Note they've recently added what's supposed to be a cleaner way of starting other activities for results and getting the results, explained here. But since you're already doing it the traditional way, I'll explain how to get that working.
I think the easiest thing to do in this situation is just make more request codes, so you can check which request it was.
val REQUEST_IMAGE_CAPTURE_SOURCE_1 = 1
val REQUEST_IMAGE_CAPTURE_SOURCE_2 = 2
val REQUEST_IMAGE_CAPTURE_SOURCE_3 = 3
//...
camRead1.setOnClickListener { dispatchTakePictureIntent(REQUEST_IMAGE_CAPTURE_SOURCE_1) }
camRead2.setOnClickListener { dispatchTakePictureIntent(REQUEST_IMAGE_CAPTURE_SOURCE_2) }
camRead3.setOnClickListener { dispatchTakePictureIntent(REQUEST_IMAGE_CAPTURE_SOURCE_3) }
//...
private fun dispatchTakePictureIntent(requestCode: Int) {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
try {
startActivityForResult(takePictureIntent, requestCode)
} catch (e: ActivityNotFoundException) {
// display error state to the user
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode != RESULT_OK) {
// possibly show message to user
return
}
val imageViewId = when (requestCode) {
REQUEST_IMAGE_CAPTURE_SOURCE_1 -> R.id.thumbRead1
REQUEST_IMAGE_CAPTURE_SOURCE_2 -> R.id.thumbRead2
REQUEST_IMAGE_CAPTURE_SOURCE_3 -> R.id.thumbRead3
}
val imageView = findViewById<ImageView>(imageViewId)
imageView.imageBitmap = data.extras.get("data") as Bitmap
}
By the way, if you want to get an ID for a view using the String like you were showing you were trying, you would do it like this:
val viewId = resources.getIdentifier("thumbRead$imgId", "id", packageName)
val imageView = findViewById<ImageView>(viewId)
You need to pass different request code for each call and pass it to the dispatchTakePictureIntent function. You do not need to get id by findviewbyid. You simply can add the image on the basis of the request code.
val REQUEST_IMAGE_CAPTURE_ONE = 1
val REQUEST_IMAGE_CAPTURE_TWO = 2
val REQUEST_IMAGE_CAPTURE_THREE = 3
private fun dispatchTakePictureIntent(requestCode: Int) {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
try {
startActivityForResult(takePictureIntent, requestCode)
} catch (e: ActivityNotFoundException) {
// display error state to the user
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
val imageBitmap = data.extras.get("data") as Bitmap
if (requestCode == REQUEST_IMAGE_CAPTURE_ONE ) {
thumbRead1.setImageBitmap(imageBitmap)
}else if (requestCode == REQUEST_IMAGE_CAPTURE_TWO ) {
thumbRead2.setImageBitmap(imageBitmap)
}else if (requestCode == REQUEST_IMAGE_CAPTURE_THREE ) {
thumbRead3.setImageBitmap(imageBitmap)
}
}
}
Hi I am creating a SideActivity to gather some results and pass them back to Main Activity. However, the two strings value from the putextra are NULL rather than the string "20" and the jamSize "medium". Is there a way of passing the data properly?
Here in my Main Activity I have a setOnClickListener and a onActivityResult function.
jamButton.setOnClickListener {
var intent = Intent(this#MainActivity, SideActivity::class.java)
intent.putExtra("jamName", "raspberry")
intent.putExtra("jamPrice", "12.00")
startActivityForResult(intent, 1) // passing request code value 1
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(resultCode == RESULT_OK) {
val jamPrice:String = intent.getStringExtra("jamPrice").toString()
val jamSize:String = intent.getStringExtra("jamSize").toString()
val newJam = DataModel("Jam", "$jamSize", "$jamPrice")
list.add(0, newJam)
jamAdapter.notifyItemInserted(0)
}
}
Here is my Second Activity
completeBtn.setOnClickListener {
val jamPrice: String = textView2.text.toString()
val jamSize: String = textView3.text.toString()
val intent = Intent(this#SideActivity, MainActivity::class.java)
intent.putExtra("jamPrice", "20.00")
intent.putExtra("jamSize", jamSize)
setResult(Activity.RESULT_OK, intent)
finish()
}
In your onActivityResult don't use this :
val jamPrice:String = intent.getStringExtra("jamPrice").toString()
because the intent variable is the Intent of the activity instead use :
val jamPrice: String = data?.getStringExtra("jamPrice").toString()
I am trying to get data from one activity in other. But data always null.
val res = Intent()
res.putExtra("uri", imageUri)
setResult(Activity.RESULT_OK, res)
finish()
In the second activity I always get data as null. What is the problem? (imageUri is not null when I put it).
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(resultCode == Activity.RESULT_OK){
//data == null, WHY???
}
}
I think you need to define the intent with the current context and target class.
val intent = Intent(this#HomeActivity,ProfileActivity::class.java) // define you activity in which you want to go
intent.putExtra("Username","John Doe")
startActivity(intent)
I'm trying to get the result of intent between 2 activities but something is wrong because I always get a resultCode = 0 in initial activity:
Code inside CarsFragment.kt
private fun startAddCarActivity() {
val intent = Intent(context, AddCarActivity::class.java)
startActivityForResult(intent, 1)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// ALWAYS GET requestCode = 1, resultCode = 0 and data = null !!
}
AddCarActivity.kt:
private fun startCarsNavigationActivity() {
intent.putExtra("car", car)
setResult(1, intent)
finish()
}
Problem:
I always get requestCode = 1, resultCode = 0 and data = null in CarsFragment.kt
Where is the problem ?
Result code of 0 means RESULT_CANCELED. This can happen if the Activity you are launching is launched into a different task, or if the user presses the BACK key, or if the launched Activity decides to return RESULT_CANCELED.
I am trying to set up a dialogfragment with a textview, and once clicked, use an intent to launch the autocomplete activity. When a place is selected, the textview shows the address.
In onCreateDialog, I have the following code
binding.dialogLocationText.setOnClickListener {
val fields =
listOf(Place.Field.ID, Place.Field.ADDRESS, Place.Field.NAME)
val intent = Autocomplete.IntentBuilder(
AutocompleteActivityMode.OVERLAY, fields
).build(context!!)
startActivityForResult(intent, AUTOCOMPLETE_REQUEST_CODE)
}
Because the textview is accessed through databinding, I can't access it directly in onActivityResult, so created private lateinit var dialogLocationText: TextView and dialogLocationText = binding.dialogLocationText. Then set text in:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == AUTOCOMPLETE_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
val place = Autocomplete.getPlaceFromIntent(data!!)
dialogLocationText.text = place.address
}
else if (resultCode == AutocompleteActivity.RESULT_ERROR) {
// TODO: Handle the error.
}
}
}
The above does not look like good practice especially with the redundant reference to the textview, and I'm wondering if I can construct differently to follow MVVM.
Thanks for the help.