My Code works well in API 28 and below except API 19.
the main problem is that onActivityResult doesn't call from other activity in my code when i run it in a device with API 19
The min_sdk is 17. compile_sdk && target_sdk are 27, so the problem will not solve with changing them.
here is the code from the first Activity:
food.name = name
intent.putExtra(Food_Name, burgerNameEtxt.text.toString())
setResult(Activity.RESULT_OK, intent)
finish()
and this is where i should receive the result in another Activity:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
RequestCode -> {
when (resultCode) {
Activity.RESULT_OK -> {
var food = getCurrentFood(mMenueItem.id)
food.name = data!!.getStringExtra(Food_Name)
// doing some thing with data //
}
}
}
}
}
the RequestCode is 1 >> const val RequestCode = 1
which i send it to the first activity with intent. any help will be appreciated :)
For me, it happens because of android:launchMode="singleTask" and this doesn't help intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP).
I fixed it by android:launchMode="singleTop".
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)
}
}
}
Halllo, my BarcodeActivity is called by startActivityForResult through my PCActivity. The value of the scanned barcode should then be returned back to the PCActivity and inserted in a text field there. Unfortunately, I do not get a value back. However, the app does not crash either. Here is my code.
PCActivity:
sn_mb.setDrawableRightTouch {
val intent = Intent(this#PCActivity, BarcodeActivity::class.java)
startActivityForResult(intent, 1)
}
[...]
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1 && resultCode == Activity.RESULT_OK && data != null) {
val returnedSN = intent.getStringExtra("return_sn")
sn_mb.setText(returnedSN)
} else {
sn_mb.setText("FEHLER!")
}
}
BarcodeActivity
saveBtn.setOnClickListener {
val sn = editTextBarcode.text.toString()
sn.toString()
if (sn!= "") {
val returnIntent:Intent = Intent()
returnIntent.putExtra("return_sn", sn)
setResult(Activity.RESULT_OK, returnIntent)
finish()
} else {
Toast.makeText(
applicationContext,
"Das ist keine gültige Seriennummer",
Toast.LENGTH_SHORT
).show()
}
}
I hope someone can explain or help me with this problem. Thank you very much.
You are extracting your data from the wrong place.
Replace
val returnedSN = intent.getStringExtra("return_sn")
with
val returnedSN = data.getStringExtra("return_sn")
The problem is you are not passing the scanned bar code value (sn) to the intent(returnIntent) in your BarCodeActivity.
First make sure sn is String since you want to pass a StringExtra, therefore:
val sn = editTextBarcode.text.toString()
And then pass sn to your return intent:
returnIntent.putExtra("return_sn", sn)
Notice that in your code you are passing integer 1 instead of sn.
EDIT:
One more minor fix to your code, didn't notice it:
val returnIntent:Intent = getIntent()
Notice that it's getIntent() instead of 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.
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))
}
}
}
I started screen capture intent according to MediaProjectionManager:
var intent = mediaProjectionManager.createScreenCaptureIntent()
startActivityForResult(intent, 0)
... but I have no idea how to stop screen capture. Sample projects for API 21 are still not available.
ok, found solution, firstly save result to MediaProjection instance:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
super<Activity>.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data)
}
}
and to stop simply execute:
mediaProjection.stop()