How to pass the values from activity to another activity - kotlin

As I'm learning Kotlin for Android development, I'm now trying the basic programs like hello world and how to navigate from one activity to another activity, there is no issue with this.
When I move from one activity to another, it works fine, but I do not know how to pass the values between the activities.
I tried to set the values in one activity and retrieved them in another activity it does not work.
Please see the code snippet below
This is my main activity where I take the username and password from edit text and setting to the intent:
class MainActivity : AppCompatActivity() {
val userName = null
val password = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener {
val intent = Intent(this#MainActivity,SecondActivity::class.java);
var userName = username.textø
var password = password_field.text
intent.putExtra("Username", userName)
intent.putExtra("Password", password)
startActivity(intent);
}
}
}
This is my second activity where I have to receive values from the main activity
class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
var strUser: String = intent.getStringExtra("Username")
var strPassword: String = intent.getStringExtra("Password")
user_name.setText("Seelan")
passwor_print.setText("Seelan")
}
}
Please guide me on how to do this, whether I have some other way to do this in Kotlin if not by intent.

Send value from HomeActivity
val intent = Intent(this#HomeActivity,ProfileActivity::class.java)
intent.putExtra("Username","John Doe")
startActivity(intent)
Get values in ProfileActivity
val profileName=intent.getStringExtra("Username")

I'm on mobile, you must test by yourself.
Try to make a CharSequence to a String in MainActivity , you have put a CharSequence rather than a String, for example:
var userName = username.text.toString()
var password = password_field.text.toString()

In Kotlin, you can pass the data simply by using the Intents. You can directly put your data in intent or you can write those data in bundle and send that bundle to another activity using the intent.
val intent = Intent(this#HomeActivity,ProfileActivity::class.java);
intent.putExtra("profileName", "John Doe")
var b = Bundle()
b.putBoolean("isActive", true)
intent.putExtras(b)
startActivity(intent);

You can simply use the intents and bundle to send data from one activity to another activity.
val intent = Intent(this#OneActivity,TwoActivity::class.java);
intent.putExtra("username", userName)
startActivity(intent);

//On Click on Button
var but = findViewById<Button>(R.id.buttionActivity_two) as Button
but.setOnClickListener {
//Define intent
var intent = Intent(applicationContext,MainActivity::class.java)
// Here "first" is key and 123 is value
intent.putExtra("first",123)
startActivity(intent)
}
}
// If Get In Into Other Activity
var Intent1: Intent
Intent1= getIntent()
//Here first is key and 0 is default value
var obj :Int = Intent1.getIntExtra("first",0);
Log.d("mytag","VAlue is==>"+obj)

first you should do this,
var userName = username.text.toString()
var password = password_field.text.toString()
Add Anko dependency.
implementation "org.jetbrains.anko:anko:0.10.4"
information passing inside MainActivity() is like
startActivity<SecondActivity>("Username" to userName,"Password" to password )
get information from SecondActivity() is,
val profileName=intent.getStringExtra("Username")

You can just access the value without using extras or intent. Simply use companion object in MainActivity:
companion object{
val userName: String = String()
val password: String = String()
}
In SecondActivity:
var strUser: String = MainActivity.username
var strPassword: String = MainActivity.password
And you can access the values from multiple activities easily.

Send data
val Name=findViewById<EditText>(R.id.editTextTextPersonName)
val Name2=findViewById<EditText>(R.id.editTextTextPersonName2)
val name=Name.text.toString()
val age=Name2.text.toString()
val intent1=Intent(this,Second::class.java).also {
it.putExtra("Username",name)
it.putExtra("Age",age)
startActivity(it);
}
Receive data
val name=intent.getStringExtra ("Username")
val age = intent.getStringExtra("Age")
val textView5=findViewById<TextView>(R.id.textView).apply {
text= "Name = $name"
}
val textView6=findViewById<TextView>(R.id.textView2).apply {
text= "Age = $age"
}

Related

Removing an item from RecyclerView leaves a gap?

I have an activity which displays reservation list
The reservation list is stored in SQLite, which works OK
override fun onCreate(savedInstanceState: Bundle?) {
var reservationList = arrayListOf<ReservationModel>()
reservationList.addAll(reservationDB!!.reservationDao().getReservationList())
reservationAdapter = reservationListAdapter(reservationList, this#ReservationListActivity)
val llm01 = LinearLayoutManager(applicationContext, LinearLayoutManager.VERTICAL, true)
reservation_recview.layoutManager = llm01
reservation_recview.adapter = reservationAdapter
}
Then I want to remove "Zenbu City". This is the code:
reservationDB.reservationDao().deleteReservation(selectedReservation)
val newReservationList = arrayListOf<ReservationModel>()
newReservationList.addAll(reservationDB.reservationDao().getAllReservations())
reservationAdapter.removeItemAndRefresh(selectedReservation, newReservationList)
This is how removeItemAndRefresh() implemented in ReservationAdapter:
fun removeItemAndRefresh(selectedItem: ReservationModel, newList: ArrayList<ReservationModel>){
theList.remove(selectedItem)
theList.clear()
theList.addAll(newList)
notifyDataSetChanged()
}
The result is this:
See a noticable gap/empty space on the RecyclerView? How to fix that?

Accessing AlarmManager from inside a RecyclerView Adapter

I'm making an Android alarm app in class. The alarms are displayed inside a recyclerview in the main activity, and I want them to be deleted when pressed. I am able to clear it from the alarm database I set up but I cannot access AlarmManager to cancel the alarm, and the PendingIntent's context also appears to be wrong.
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, index: Int) {
val myViewHolder = holder as MyViewHolder
val sdf = SimpleDateFormat("HH:mm EEEE")
myViewHolder.tvAlarmTime.text = sdf.format(alarms[index].milliseconds)
myViewHolder.tvAlarmFrequency.text = alarms[index].frequency
myViewHolder.itemView.setOnClickListener {
launch {
withContext(Dispatchers.IO) {
val db = AlarmDatabase.getDatabase(myViewHolder.tvAlarmTime.context)
db.alarmDao().deleteTriggeredAlarm((alarms[index].id))
}
}
val pi = PendingIntent.getBroadcast(this, (alarms[index].id).toInt(), Intent("alarmTask"), PendingIntent.FLAG_UPDATE_CURRENT)
val alarmMgr = getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmMgr.cancel(pi)
}
}
In the last 3 lines, the context has a type mismatch as this is a MyAdapter type - I'm not sure what I need to put here, something similar to MainActivity.context I would assume
getSystemService also shows a type inference error as a string, and I assume this is causing the type mismatch for context.ALARM_SERVICE as a string rather than the context.
What is the correct context and how can I access the AlarmManager inside the adapter?
You can use the context of your item view:
val context = myViewHolder.itemView.context
val pi = PendingIntent.getBroadcast(context, (alarms[index].id).toInt(), Intent("alarmTask"), PendingIntent.FLAG_UPDATE_CURRENT)
val alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmMgr.cancel(pi)

Can I get a random user out of the firebase realtime database as chat partner as a second option besides a selected user?

I have a problem with coding a Chat application.
One of the planned features is getting connected with a random user from the database.
Currently I have one button that loads an overview of all users, you can chose one user, and you can chat with that person (message send/receive works, also when i close the app and open it again the messages are still viewable and saved).
For that, I have a NewMessageActivity, which on click on one user leads to the ChatLogActivity and takes the user information with it (toUser and USER_KEY).
Now my plan is to basically skip the NewMessage part and get right into the ChatLogActivity, and assign a random user to that.
I was thinking to just add something like an if/else to my code (so, if toUser is assigned by NewMessageActivity load that, otherwise load random), but I can't get it to work.
My users have each individual uid's, that get created randomly when signing up.
Here's my code:
companion object {
val TAG = "ChatLog"
}
val adapter = GroupAdapter<GroupieViewHolder>()
var toUser: User? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat_log)
recyclerview_chat_log.adapter = adapter
keyboardManagement()
toUser = intent.getParcelableExtra<User>(NewMessageActivity.USER_KEY)
supportActionBar?.title = toUser?.username
listenForMessages()
send_button_chat_log.setOnClickListener {
Log.d(TAG, "Attempt to send message")
performSendMessage()
}
}
Here how I usually get the users for the chat, in case that is important:
val ref = FirebaseDatabase.getInstance().getReference("/users")
ref.addListenerForSingleValueEvent(object: ValueEventListener{
override fun onDataChange(p0: DataSnapshot) {
val adapter = GroupAdapter<GroupieViewHolder>()
p0.children.forEach{
Log.d("NewMessage", it.toString())
val user = it.getValue(User::class.java)
if (user != null) {
adapter.add(UserItem(user))
}
}
adapter.setOnItemClickListener{ item, view ->
val userItem = item as UserItem
val intent = Intent(view.context, ChatLogActivity::class.java)
//intent.putExtra(USER_KEY, userItem.user!)
intent.putExtra(USER_KEY, userItem.user)
startActivity(intent)
//Zurück zum Main Menu statt zur User Auswahl
finish()
}
recyclerView_newmessage.adapter = adapter
}
override fun onCancelled(p0: DatabaseError) {
}
})
}
}
class UserItem(val user: User): Item<GroupieViewHolder>() {
//wird aufgerufen für die einzelnen Userobjekte
override fun bind(viewHolder: GroupieViewHolder, position: Int) {
viewHolder.itemView.username_textView_new_message.text = user.username
Picasso.get().load(user.profileImageURL).into(viewHolder.itemView.picture_imageView_new_message)
}
//Einzelne Zeilen gestalten
override fun getLayout(): Int {
return R.layout.user_row_new_messages
}
}
I'm still a beginner, so I'm pretty clueless what to do by now. If you have any ideas and could help me, I'd really appreciate that! :)
Thanks!

How to kotlin getposition spinner by value with custom object?

I'm trying to make a spinner with custom objects.
When I do getposition from spinner I get result -1. I do not know the cause
this my code:
Model
class User(var name: String?, var mail: String?) {
override fun toString(): String {
return name.toString()
}
}
Activity
val userList = ArrayList<User>()
val user1 = User("Jim","jim#gmail.com")
userList.add(user1)
val user2 = User("John","john#gmail.com")
userList.add(user2)
val user3 = User("peki", "pek#gmail.com")
userList.add(user3)
val adapter = ArrayAdapter<User>(this,
android.R.layout.simple_spinner_item, userList
)
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.setAdapter(adapter)
val ambilPosisi : Int = adapter.getPosition(User("peki","pek#gmail.com"))
Toast.makeText(this, (ambilPosisi).toString(), Toast.LENGTH_LONG).show()
Just declare your User class as data class:
data class User(var name: String?, var mail: String?)
It will generate equals() and toString() methods. So you can use it in object comparison.
You are trying to call
adapter.getPosition()
On an item that is effectively not in the list that was submitted to the adapter. You are creating a new User instance as a parameter to the function call, which, although has the identical fields with user3, does not refer to the same variable.
Calling
adapter.getPosition(user3)
Should return the correct index.

Kotlin - How do i set a sharedpreference code so that i open the closed app, it opens the last Activity, where i left it

I made two activities in my application, I want the app to be opened where I left off. In other words, not the default activity but the activity where I was when I last exited the app.
You could set a SplashActivity, where your app start, that will start other activities.
In this SplashActivity, you can set a var lastActivity, that will be a code to keep in which activity you were last time.
You get it with SharedPreference, and then go to the activity.
i.e :
String lastActivity = SharedPreference.getString(...) // I don't really remember the syntax
if (lastActivity == "HelloWorldActivity")
startActivity(HelloWorldActivity.getStartIntent(context))
else if (lastActivity == "GoodByeActivity")
startActivity(GoodByeActivity.getStartIntent(context))
Then, do NOT forget to edit your SharedPreference value EACH TIME you change activity.
I don't know if this is a good practice, but feel free to test this and give your think.
EDIT
First, you need to understand how is Shared Preference File. I think it looks like this :
"app_name"="Your app name"
"last_activity"="Your last activity"
"user_age"="23"
This could be the first activity you launch :
class SplashActivity : AppCompatActivity() {
var lastActivity = ""
override fun onCreate(savedInstanceState : Bundle?) {
super.onCreate()
/*
Here, we will get the SharedPreferencesFile.
Then, we get the value linked to the key TAG_LAST_ACTIVITY (set in companion object)
*/
val sharedPref = this.getSharedPreferences(getString(R.string.shared_preference_file_name), 0)
lastActivity = sharedPref.getString(TAG_LAST_ACTIVITY, "")
var activityToStart : AppCompatActivity? = null
if (lastActivity.isBlank())
activityToStart = YourActivityToStartAtFirstLaunch.getStartIntent(this)
else if (lastActivity.equals(TAG_ACTIVITY_ONE))
activityToStart = ActivityOne.getStartIntent(this)
else if (lastActivity.equals(TAG_ACTIVITY_TWO))
activityToStart = ActivityTwo.getStartIntent(this)
else if
... // Use as many as else if you need, but think about the "when" condition, it is better !
startActivity(activityToStart)
}
companion object {
private const val TAG_LAST_ACTIVITY = "last_activity"
private const val TAG_ACTIVITY_ONE = "activity_one"
private const val TAG_ACTIVITY_TWO = "activity_two"
}
}
And this could be your ActivityOne, for example :
class ActivityOne : AppCompatActivity() {
override fun onCreate(savedInstanceState : Bundle?) {
super.onCreate()
/*
Here, we will modify the variable LAST_ACTIVITY in the shared preferences file by setting it to "activity_one".
So, if the user quit this app now, you will know at next launch in which activity he stopped.
I think it is a better practice to set this in the onPause() or onStopped() method. Think about it ! ;)
*/
val sharedPrefEditor = this.getSharedPreferences(getString(R.string.shared_preference_file_name, 0)).edit()
sharedPrefEditor.putString(TAG_LAST_ACTIVITY, TAG_ACTIVITY_ONE)
sharedPrefEditor.apply()
}
companion object {
fun getStartIntent(context : Context) : Intent = Intent(context, ActivityOne()::class.java)
private const val TAG_ACTIVITY_ONE = "activity_one"
private const val TAG_LAST_ACTIVITY = "last_activity"
}
}
Do not forget to put your shared preference file name in your values/strings.xml file :
<string name="shared_preference_file_name">com.example.yourappname.sharedpref"</string>