How do you pass data from current activity to Previous activity - android

I am trying to pass a value from Activity 3 to Activity 2 but I am getting null Value. If I click Back button its going to previous Activity but value is null. Added the suggested Approach code below. but still not able to get the results.
Suggested Approach:
Activity :3
override fun onBackPressed() {
sendDataBackToPreviousActivity()
super.onBackPressed()
}
private fun sendDataBackToPreviousActivity()
{
val navBarTitle21=intent.getStringExtra(TestProjectMenuViewHolder.TEST_TITLE_NAME)
val intent=Intent().apply { putExtra("ReturnMessage",navBarTitle21)}
setResult(Activity.RESULT_OK,intent)
}
Activity:2
Main Class:
companion object {
const val START_ACTIVITY_3_REQUEST_CODE = 0
}
val intent=Intent(this,TestProjectMenuDetail::class.java)
startActivityForResult(intent, START_ACTIVITY_3_REQUEST_CODE)
Declared outside Main Class:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == START_ACTIVITY_3_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
val message = data!!.getStringExtra("ReturnMessage")
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
println("Message Value: $message")
}
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}
First Approach:
Activity:3
val navBarTitle= intent.getStringExtra(TestMenuViewHolder.TEST_TITLE_KEY)
supportActionBar?.title=navBarTitle//Something Like "StackOverFlow". THis is for back Button
TestMenuDetail:
val navBarTitle2=intent.getStringExtra(TestMenuViewHolder.TEST_TITLE_NAME)
val TestVar=Intent(this#TestMenuDetail,TestMenuList::class.java)
intent.putExtra("TestVar2",navBarTitle2)
println("Test Value $navBarTitle2")//Test Value Hello
Activity:2
TestMenuList:
val navBarTitle3=intent.getStringExtra("TestVar2")
println("Helllo Test: $navBarTitle3")//Helllo Test: null

You should use startActivityForResult API to achieve your task.
Activity2.kt
class Activity2 : AppCompatActivity() {
companion object {
const val START_ACTIVITY_3_REQUEST_CODE = 0
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity2)
// Start Activity3
val intent = Intent(this, Activity3::class.java)
startActivityForResult(intent, START_ACTIVITY_3_REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == START_ACTIVITY_3_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
val message = data!!.getStringExtra("message")
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}
}
Activity3.kt
class Activity3 : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity3)
}
override fun onBackPressed() {
sendDataBackToPreviousActivity()
super.onBackPressed()
}
/**
* Send data back to previous activity which start this one, you can call this method when users press on back key
* or when users press on a view (button, image, etc) on this activity.
*/
private fun sendDataBackToPreviousActivity() {
val intent = Intent().apply {
putExtra("message", "This is a message from Activity3")
// Put your data here if you want.
}
setResult(Activity.RESULT_OK, intent)
}
}

Ok here is what I would do:
Override the onBackPressed method and then pass the variable value inside the method with an Intent. And in activity 2 receive the value from activity 3.
In activity 3
#override
public void onBackPressed (){
Intent intent = new Intent(getApplicationContext(), Activity2.class);
intent.put("value_key", value);
startActivity(intent);
}
Receive value in activity 2
getIntent.getValue("value_key");
Don't forget to check the syntax, I just wrote it from my phone. Hope it helps!

You can always use SharedPreferences, and then clear them, after receiving data in previous activity. It's 100% effective way. Put it:
val sharedPreference = getSharedPreferences("prefs name",Context.MODE_PRIVATE)
var editor = sharedPreference.edit()
editor.putString("your value name","value")
editor.commit()
and get it:
sharedPreference.getString("your value name","default value")
but of course you have to open preferences again in previous activity ;)
val sharedPreference = getSharedPreferences("prefs name",Context.MODE_PRIVATE)

Related

Showing Result returned in a Carousel RecyclerView (Kotlin)

I have a rotating carousel (using carouselrecyclerview) to rotate a list of images around.
The user can call a second activity and then search the images, and then return the selected image’s ID back to the MainActivity.kt.
The MainActivity.kt receives the result (using intent) in the onActivityResult.
I then need to call scrollToPosition (from the carouselLayoutManager) to move the carousel to the position that was selected in the second activity.
As the call to the carouselLayoutManager is within the onCreate, I can’t call it from the onActivityResult? I have tried moving the onActivityResult to within the onCreate, but then the onActivityResult is not called when returning from the second activity.
So, how can I call the code which is within the onCreate from the onActivityResult please?
Any help really appreciated as I’m struggling on this.
MainActivity.kt
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val carouselRecyclerview = findViewById<CarouselRecyclerview>(R.id.recycler)
val list = ArrayList<DataModel>()
// Load the images of the Veg
for (mycount in 0..41) {
list.add(DataModel(VegName[mycount].image, VegName[mycount].name))
}
val adapter = DataAdapter(list)
carouselRecyclerview.adapter = adapter
val carouselLayoutManager = carouselRecyclerview.getCarouselLayoutManager()
carouselLayoutManager.scrollToPosition(1)
carouselRecyclerview.setItemSelectListener(object : CarouselLayoutManager.OnSelected {
override fun onItemSelected(position: Int) {
var ShowIt = findViewById(R.id.textVegName) as TextView
//Cente item
ShowIt.text = list[position].text
}
})
Searchbutton.setOnClickListener {
val intent = Intent(this, SearchActivity::class.java)
startActivityForResult(intent, SEARCH_ACTIVITY_REQUEST_CODE)
}
// Move the carousel to the position received - THIS ISN'T CALLED?
fun setthelocation(SetThisPlace: Int ) {
carouselLayoutManager.scrollToPosition(SetThisPlace)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == SEARCH_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
val returnedfrom = VegName.find{ it.name == data?.getStringExtra("result") }
if (returnedfrom==null)
Toast.makeText(applicationContext, "Did not find the result returned!", Toast.LENGTH_LONG).show()
else {
Toast.makeText(applicationContext, "Got = " + returnedfrom.id, Toast.LENGTH_LONG).show()
//Need to call eiter setthelocation() or carouselLayoutManager.scrollToPosition???
return
}
}
}
}
As the call to the carouselLayoutManager is within the onCreate, I can’t call it from the onActivityResult?
I think you're confusing terms. There is no "call to the carouselLayoutManager" - that's a variable to assign to an object, not a function you call.
I have tried moving the onActivityResult to within the onCreate, but then the onActivityResult is not called when returning from the second activity.
onActivityResult is a base-class method that is invoked for you when you use startActivityForResult and close the opened activity. If you "move it to within the onCreate" all you're doing is calling the base class implementation (which does nothing).
So, how can I call the code which is within the onCreate from the onActivityResult please?
The easiest solution would be to hold on to the layout manager as a variable you can use in either onCreate or onActivityResult:
// Class-level property you can use in either function
private lateinit var carouselLayoutManager: LayoutManager
override fun onCreate(...) {
// Replace local val with class-level property
// Instead of this:
// val carouselLayoutManager = carouselRecyclerview.getCarouselLayoutManager()
// Do this: initialize member property to use here and in onActivityResult
carouselLayoutManager = carouselRecyclerview.getCarouselLayoutManager()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == SEARCH_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
val returnedfrom = VegName.find{ it.name == data?.getStringExtra("result") }
if (returnedfrom==null)
Toast.makeText(applicationContext, "Did not find the result returned!", Toast.LENGTH_LONG).show()
else {
Toast.makeText(applicationContext, "Got = " + returnedfrom.id, Toast.LENGTH_LONG).show()
//Need to call eiter setthelocation() or carouselLayoutManager.scrollToPosition???
// Now you can call this since it's a member property
carouselLayoutManager.scrollToPosition(...)
return
}
}
}
}
hm, for this I would recommend you to use the NavComponent and send your data through fragments or registering for activity but I don't want to confuse you and I will try to give you a solution for this problem.
I think the easiest way to solve this (in this context) would be to launch the intent as you are doing:
MainActivity.kt ->
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val carouselRecyclerview = findViewById<CarouselRecyclerview>(R.id.recycler)
val list = ArrayList<DataModel>()
// Load the images of the Veg
for (mycount in 0..41) {
list.add(DataModel(VegName[mycount].image, VegName[mycount].name))
}
val adapter = DataAdapter(list)
carouselRecyclerview.adapter = adapter
val carouselLayoutManager = carouselRecyclerview.getCarouselLayoutManager()
carouselLayoutManager.scrollToPosition(1)
carouselRecyclerview.setItemSelectListener(object : CarouselLayoutManager.OnSelected {
override fun onItemSelected(position: Int) {
var ShowIt = findViewById(R.id.textVegName) as TextView
//Cente item
ShowIt.text = list[position].text
}
})
Searchbutton.setOnClickListener {
val intent = Intent(this, SearchActivity::class.java)
startActivity(intent)
}
fun setTheLocation(SetThisPlace: Int ) {
carouselLayoutManager.scrollToPosition(SetThisPlace)
}
// onNewIntent would receive the intent needed to execute your logic.
// I wouldn't use onActivityResult because, IMO, It is dirty code and it is deprecated.
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
if (intent?.hasExtra("position") == true) {
setTheLocation(intent.getIntExtra("position"))
}
}
SearchActivity.kt ->
override fun onCreate(savedInstanceState: Bundle?) {
...
.... your code ...
exampleOfSendingBackFunction()
}
//Here you will send back the position to MainActivity.kt clearing all flags.
fun exampleOfSendingBackFunction() {
val intent = Intent(this, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
putExtras(
"position" to yourPositionVariable
)
}
startActivity(intent)
}
I hope it helps :D

send data back from secondActivity and update is giving me void android.widget.TextView.setText(java.lang.CharSequence) on a null object reference

hello I am making note app I have tried other answers to questions like this and it didn't work for me. also I have tried Registering a callback for an Activity Result it was two complicated I didn't get it. when I add item to the recyclerview but when i click that added item it is giving me Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
the point is send data back from secondActivity and update the Recyclerview TextView
this is my code for mainactivity
override fun update(position: Int) {
val note = notes[position]
val intent = Intent(this, Data::class.java)
intent.putExtra(Data.INTENT_PARCELABLE, note)
startActivityForResult(intent, REQUEST_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode === REQUEST_CODE) {
if (resultCode === Activity.RESULT_OK) { // Activity.RESULT_OK
// get String data from Intent
val x: String? = data?.getStringExtra("keyName")
val y: String? = data?.getStringExtra("keyName")
// set text view with string
val tit = findViewById<TextView>(R.id.tit)
val desc= findViewById<TextView>(R.id.desc)
tit.text = x
desc.text = y
}
}
}}
second activity
class Data : AppCompatActivity() {
private lateinit var binding: ActivityDataBinding
companion object {
const val INTENT_PARCELABLE = "object_intent"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDataBinding.inflate(layoutInflater)
setContentView(binding.root)
title = "Edit Note"
val name = intent.getSerializableExtra(INTENT_PARCELABLE) as Notes
binding.tit.setText(name.title)
binding.desc.setText(name.description)
// get the text from the EditText
val a = binding.tit.text.toString()
val b = binding.desc.text.toString()
// put the String to pass back into an Intent and close this activity
val data = Intent()
data.putExtra("keyName", a)
data.putExtra("keyName", b)
setResult(Activity.RESULT_OK, data)
finish()
}
}

Passing an integer between Activities Doesn’t return the correct value?

I’m using Kotlin and trying to return a number from two Activities.
So from MainActivity I get a click (Searchbutton), this starts up my second activity: SearchActivity. When a click happens it then (should!) returns the number 59 to the MainActivity, which I should be able to see in Log.d.
What I actually see is I get the default value “0” being returned to MainActivity?
I’m assuming that the default value indicates that the value hasn’t been passed through the two activities?
Any help really appreciated!
MainActivity.java
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Searchbutton.setOnClickListener {
val intent = Intent(this, SearchActivity::class.java)
startActivity(intent)
var gotthisInt = intent.getIntExtra("MY_KEY", 1);
Log.d("TAG", "What was received= " + gotthisInt)
}
}
}
SearchActivity.java
class SearchActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_container)
Searchbutton2.setOnClickListener {
val intent = Intent(this#SearchActivity, MainActivity::class.java).apply {
putExtra("MY_KEY", 59)
}
startActivity(intent)
}
}
}
In Android to pass data between Activity, you should use startActivityForResult(Intent, int). So change your code to.
MainActivity.java
class MainActivity : AppCompatActivity() {
private val SEARCH_ACTIVITY_REQUEST_CODE = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Searchbutton.setOnClickListener {
val intent = Intent(this, SearchActivity::class.java)
startActivityForResult(intent, SEARCH_ACTIVITY_REQUEST_CODE)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == SEARCH_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
val gotthisInt = data?.getIntExtra("MY_KEY", 1) ?: 1
Log.d("TAG", "What was received = $gotthisInt")
}
}
}
}
SearchActivity.java
class SearchActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.fragment_container)
Searchbutton2.setOnClickListener {
val data = Intent().apply { putExtra("MY_KEY", 59) }
setResult(Activity.RESULT_OK, data)
finish()
}
}
}

Activity Results API returned data is null

I am trying out the new Activity Results API by trying to return a parcelable dataesque class from a child activity. Using Alpha4 of the library.
I have setup the Intent with a custom contract 'AddAttendeeContract' as per my understanding of the docs. It compiles and runs and as far as I can see the correct methods are being called but the data is just null.
What might I be missing?
class MainActivity : AppCompatActivity() {
...
override fun onCreate(savedInstanceState: Bundle?) {
... //boilerplate setup nonsense
fab.setOnClickListener {
addAttendee()
}
}
private val addAttendee = registerForActivityResult(AddAttendeeContract()) { attendee: AttendeeData? ->
println("Attendee") // this does not print out
println(attendee) // this does not either
}
}
And the contract
class AddAttendeeContract : ActivityResultContract<Void?, AttendeeData?>() {
override fun createIntent(
context: Context,
input: Void?
): Intent =
Intent(context, AddAttendeeActivity::class.java)
override fun parseResult(
resultCode: Int,
intent: Intent?
): AttendeeData? = when {
resultCode != Activity.RESULT_OK -> null
else -> intent?.getParcelableExtra<AttendeeData>("attendee")
}
}
Finally is the invocation in the child activity class.
class AddAttendeeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
... //boilerplate
add.setOnClickListener { //button on a form
val name: String = view.name.text.toString().trim()
val rate: Double = view.rate.text.toString().trim().toDouble()
val number: Int = view.number.text.toString().trim().toInt()
val intent = Intent(this, MainActivity::class.java).apply {
putExtra("attendee", AttendeeData(name=name, rate=rate, number=number))
}
setResult(Activity.RESULT_OK, intent)
startActivity(intent)
}
}
}
Any insights as to what is going on?
This is solved. The problem was that the second activity was startign a new intent, rather than finishing and returning to the old one.
In the second/child activity had to change the line:
startActivity(intent)
to
finish() and things all worked as expected.

Passing an data back to first activity using onBackPressed() and onActivityResult()

I am trying to receive the user-changed value of an Edit Text, and set that value to the first activities Text View. To do this I am employing the functions onBackPressed() and onActivityResult() as shown below. However, it apperast that no data is being sent back to the first activity when then back button is being pressed
Second Activity (sending data back):
class MetaDataActivity : AppCompatActivity() {
val name by lazy {findViewById<EditText>(R.id.editTextName)}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_meta_data)
val food = intent.getParcelableExtra("Food") as Food
name.setText(food.name)
}
override fun onBackPressed() {
val intent = Intent()
intent.putExtra("New Name", name.toString())
setResult(Activity.RESULT_OK, intent)
super.onBackPressed()
}
}
First activity (receiving user-changed data):
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val food1: ImageButton = findViewById(R.id.imageButtonFood1)
val name1: TextView = findViewById(R.id.textViewName1)
val date1: TextView = findViewById(R.id.textViewDate1)
val pizza = Food(
"Pizza", "www.test.com", "Italy, Tomato",
"1/1/2018", "pizza#mail.com", 5)
date1.text = pizza.date
food1.setOnClickListener()
{
val intent = Intent(this, MetaDataActivity::class.java)
intent.putExtra("Food", pizza)
startActivityForResult(intent, 1)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1) {
if (resultCode == Activity.RESULT_OK) {
val newName = data?.getStringExtra("New Name")
textViewName1.text = newName
}
}
}
Where I'm trying to be able to edit textViewName1's value from the second activity.
I believe I my parameters for the functions are correct, just cannot determine why it is not receiving the user-changed name value?
Thankyou

Categories

Resources