Alternative to onActivityResult for startUpdateFlowForResult - android

What is the alternative to get callback for startUpdateFlowForResult in InAppUpdates instead of onActivityResult since it is deprecated?

We have to wait for Google Play team to migrate away from the deprecated APIs. You can follow this issue on Google's Issue Tracker.

Create this result launcher
private val updateFlowResultLauncher =
registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult(),
) { result ->
if (result.resultCode == RESULT_OK) {
// Handle successful app update
}
}
After that try to launch your intent like this
val starter =
IntentSenderForResultStarter { intent, _, fillInIntent, flagsMask, flagsValues, _, _ ->
val request = IntentSenderRequest.Builder(intent)
.setFillInIntent(fillInIntent)
.setFlags(flagsValues, flagsMask)
.build()
updateFlowResultLauncher.launch(request)
}
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.FLEXIBLE,
starter,
requestCode,
)
Give it a try!

You can use below code snippet alternative of onActivityResult()
First Activity
Step 1
private val openActivity =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
handleActivityResult(REQUEST_CODE, it)
}
Step 2
openActivity.launch(
Intent(this, YourClass::class.java).apply {
putExtra(ANY_KEY, data) // If any data you want to pass
}
)
Step 3
private fun handleActivityResult(requestCode: Int, result: ActivityResult?) {
Timber.e("========***handleActivityResult==requestActivty==$requestCode====resultCode=========${result?.resultCode}")
if (requestCode == REQUEST_CODE) {
when (result?.resultCode) {
Activity.RESULT_OK -> {
val intent = result.data // received any data from another avtivity
}
Activity.RESULT_CANCELED->{
}
}
}
}
In second class
val intent = Intent()
intent.putExtra(ANY_KEY, data)
setResult(Activity.RESULT_OK, intent)
finish()

Related

onActivityResult deprecated, is there alternative (KOTLIN)

Currently I am working on a project for my college, and i have discovered that onActivityResult is deprecated. What can be done to handle it?
This is my code that troubles me
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
val result = CropImage.getActivityResult(data)
if (resultCode == RESULT_OK) {
image = result.uri
Glide.with(this).load(image).into(binding.imgPick)
} else {
Snackbar.make(
binding.root,
"Image not selected",
Snackbar.LENGTH_SHORT
).show()
}
}
}
I tried to find a solution on stackoverflow and already tried to implement couple of thing but with no luck.
You can use the following way :
fun openActivityForResult() {
startForResult.launch(Intent(this, AnotherActivity::class.java))
}
val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
val intent = result.data
// Handle the Intent
//do stuff here
}
}
You can use this in activity or fragment.
First define intent result launcher.
var picker: ActivityResultLauncher<Intent>
then
picker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK && it.data != null) {
//add your code here
}
}
And now launch your activity.
val intent = Intent(context, ImagePickerActivity::class.java)
picker.launch(intent)

How to extract result from SpeechRecognizer - Android

Im sending intent to use speech recognizer
val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.US)
putExtra(RecognizerIntent.EXTRA_PROMPT, R.string.speech_prompt)
}
startForResult.launch(intent)
But how can I extract the results from it? I've tried several way
private val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
Log.d("testing","resultData ${result.data}")//here I see HAS EXTRAS
result.data.let {
inputField.setText(it?.getStringArrayExtra(RecognizerIntent.EXTRA_RESULTS)?.get(0))
//I've used this one and it doesn't work as well
inputField.setText(it?.getStringArrayExtra(SpeechRecognizer.RESULTS_RECOGNITION)?.get(0))
}
}
}
So what is the correct way to extract the result ?
Here is the solution that works for me
private val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
myInput.setText(result.data?.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)?.first())
}
}

how to solve Android Place Autocomplete intent issue?

I'm trying to use google Place Autocomplete in my app.
Like described in the documentation, there is two ways to use this feature : one using a fragment and the other way is to use an Intent and that's what I choose.
My code is like below
Gradle:
implementation 'com.google.android.libraries.places:places:2.5.0'
Kotlin:
Part 1
btn.setOnClickListener {
if (!Places.isInitialized()) {
Places.initialize(
requireActivity().applicationContext,
getString(R.string.google_maps_key)
)
}
#Suppress("DEPRECATION")
startActivityForResult(
Autocomplete
.IntentBuilder(
AutocompleteActivityMode.OVERLAY,
listOf(
Place.Field.ID,
Place.Field.NAME,
Place.Field.LAT_LNG,
Place.Field.ADDRESS,
Place.Field.ADDRESS_COMPONENTS
)
).build(requireContext()),
AUTOCOMPLETE_REQUEST_CODE
)
}
Part 2
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == AUTOCOMPLETE_REQUEST_CODE) {
when (resultCode) {
Activity.RESULT_OK -> {
data?.let {
val place = Autocomplete.getPlaceFromIntent(data)
Timber.i(TAG, "Place: ${place.name}, ${place.id}")
}
}
AutocompleteActivity.RESULT_ERROR -> {
// TODO: Handle the error.
data?.let {
val status = Autocomplete.getStatusFromIntent(data)
Timber.i(TAG, status.statusMessage)
}
}
Activity.RESULT_CANCELED -> {
// The user canceled the operation.
}
}
return
}
super.onActivityResult(requestCode, resultCode, data)
}
The overlay 'Place Auto Complete' view appear perfectly but when I try to tape in the keyboard to search for some place, the view crashes not the app. only the view and I got the error below (I don't know if it is related) :
set_timerslack_ns write failed: Operation not permitted
Any idea how to solve this ?
Did you "enable" your api key for using the google places?

Get Result - Kotlin startActivityForResult does not deliver any result

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()

onActivityResult() deprecated for AppCompatActivity

I am using in-app updates for android and as per the documentation, they are using onActivityResult to handle app behaviour incase the update is interrupted.
This is my function that is called from my fragment:
private fun startImmediateUpdate(appUpdateInfo: AppUpdateInfo) {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.IMMEDIATE,
requireActivity(),
Constants.CODES.APP_UPDATE_REQUEST_CODE
)
}
This is how i am handling results in parent activity
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
Constants.CODES.APP_UPDATE_REQUEST_CODE -> {
if (resultCode != RESULT_OK || resultCode == RESULT_CANCELED || resultCode == ActivityResult.RESULT_IN_APP_UPDATE_FAILED) {
//Do whatever i want to
}
}
}
super.onActivityResult(requestCode, resultCode, data)
}
Now super.onActivityResult(requestCode, resultCode, data) is deprecated. Things are working fine for now but i am worried the app will crash if its wiped out completely
What can i do to replace onActivityResult()? I have looked into registerForActivityResult() but could not find anything that suits my usecase.
As Ian Lake mentioned there is a solution that uses IntentSenderForResultStarter.
First of all in your Activity, create a ActivityResultLauncher:
private val updateFlowResultLauncher =
registerForActivityResult(
ActivityResultContracts.StartIntentSenderForResult(),
) { result ->
if (result.resultCode == RESULT_OK) {
// Handle successful app update
}
}
Now start the update flow as follows:
fun startUpdate(
appUpdateInfo: AppUpdateInfo,
requestCode: Int,
) {
val starter =
IntentSenderForResultStarter { intent, _, fillInIntent, flagsMask, flagsValues, _, _ ->
val request = IntentSenderRequest.Builder(intent)
.setFillInIntent(fillInIntent)
.setFlags(flagsValues, flagsMask)
.build()
updateFlowResultLauncher.launch(request)
}
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.FLEXIBLE,
starter,
requestCode,
)
}
I have the same issue and I see that one possibility is to rewrite to use the startUpdateFlow call instead.
Personally, I think this is not worth doing, so I will ignore this specific deprecation warning instead and wait/hope for Android/Google to make a method where we can pass an ActivityResultLauncher instead.
The New Way
appUpdateInfoTask.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
&& (appUpdateInfo.clientVersionStalenessDays() ?: -1) >= 2
&& appUpdateInfo.updatePriority() >= updatePriority
&& appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)
) {
appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
AppUpdateType.IMMEDIATE,
this,
updateCode
)
openActivityForResult()
}
}
}
private fun openActivityForResult(){
resultUpdate.launch(Intent(this, MainActivity::class.java))
}
var resultUpdate = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result->
if (result.resultCode != Activity.RESULT_OK){
Toast.makeText(
this,
"App Update failed, please try again on the next app launch.",
Toast.LENGTH_SHORT
).show()
}
}

Categories

Resources