Can't get Extra data via Intent - android

I'm trying to put extra data (string) in an intent. I use startActivity to get my extra string data on the other side.
But I can't get why it doesn't work! Here's my code :
This is the destination Activity from where I want to parse my extra data -- Recipe Activity :
class RecipeActivity : AppCompatActivity() {
for (k in 0..name_arr.size-1) {
if(temp_arr[position]==name_arr[k]){
//to parse the id number of the selected recipe by the user to the next activity
val i = Intent(baseContext, ResRecActivity::class.java)
i.putExtra("ItemPosition",k)
startActivity(i)
}
}
}
This is the Target Activity for successful parsing of extra data -- ResRecActivity :
class ResRecActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_res_rec)
setSupportActionBar(toolbar)
var posit : String = intent.getStringExtra("ItemPosition") //wanting to get the extra data
//BELOW LINE IS THE ERROR LINE
*readJson(posit.toInt())* //Intending to parse the extra data in Integer datatype to readJson Function
}
}
Error that I am getting is :
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testarca/com.example.arca.ResRecActivity}: kotlin.KotlinNullPointerException
Caused by: *kotlin.KotlinNullPointerException*
at com.example.arca.ResRecActivity.onCreate(ResRecActivity.kt:37)
Main Aim :
I just want to parse the Integer "position" (in my case "k") from "RecipeActivity" to "ResRecActivity", for using that integer position in another function named "readJson" as a parameter to the function.
And I am trying to achieve that using Intent property for Handling between the activities.
Note: Also give me a similar solution to parse an ArrayList data from one activity to another using intent.

When you use i.putExtra("ItemPosition",k), you're putting an Int into your extras.
Therefore you must use getIntExtra to retrieve it:
val posit = intent.getIntExtra("ItemPosition", 0)

First
replace this line
val i = Intent(baseContext, ResRecActivity::class.java)
with
val i = Intent(this, ResRecActivity::class.java)
Second
You put Int in intent, so you should use intent.getIntExtra("ItemPosition", -1)
Hope this helps.

Related

Pass ArrayList<ZipEntry> from one activity to another

So for one of my personal projects I want to pass an arraylist of ZipEntry objects from one activity to another but I am unable to do so. I have tried the following things:
Creating Bundle() and passing that bundle using putExtra()
Passing ArrayList directly using putExta()
Creating bundle & passing it using putExtra():
Implementation:
// Add data to intent and launch install activity
val newActIntent = Intent(this, InstallActivity::class.java)
val data = Bundle()
data.putSerializable("x", languageListAdapter.selectedItems)
newActIntent.putExtra("z", data)
this.startActivity(newActIntent)
Error:
java.lang.IllegalArgumentException: Parcel: unknown type for value split_config.en.apk
Passing ArrayList<> directly using putExtra()
Implementation:
val newActIntent = Intent(this, InstallActivity::class.java)
newActIntent.putExtra("x", languageListAdapter.selectedItems)
this.startActivity(newActIntent)
Error:
java.lang.IllegalArgumentException: Parcel: unknown type for value split_config.en.apk
Note: ZipEntry object is java.util.zip.ZipEntry
In order to send an ArrayList<ZipEntry> from one Activity to another you need to make sure that your ZipEntry object is serializable, you can do it by implementing Serializable interface.
You can also use Parcelable as an alternative of Serializable.
If you use Serializable you use getSerializableExtra and if it's Parcelable you use getParcelableArrayListExtra
#Parcelize
data class ZipEntry : Parcelable
Fixed this issue thanks to the comment from #wambada
Implementation:
Created a singleton object to store the ArrayLists
object ZipEntrySingleton {
var aList: ArrayList<ZipEntry>? = null
var lList: ArrayList<ZipEntry>? = null
}
Created the singleton object in activity 1 and passed the data to it.
// Add data to intent and launch install activity
val newActIntent = Intent(this, InstallActivity::class.java)
val x = ZipEntrySingleton
x.aList = xListAdapter.selectedItems
x.lList = yListAdapter.selectedItems
this.startActivity(newActIntent)
Retrieved the data in the new activity by using:
ZipEntrySingleton.aList

How can get rid of the multiply Intents

I have 2 activities. And I need pass a lot of variables from one activity to another activity:
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra(ACCOUNT1, accoun1)
intent.putExtra(ACCOUNT2, accoun2)
intent.putExtra(ACCOUNT3, accoun3)
intent.putExtra(ACCOUNT4, accoun4)
intent.putExtra(ACCOUNT5, accoun5)
intent.putExtra(ACCOUNT6, accoun6)
intent.putExtra(ACCOUNT7, accoun7)
intent.putExtra(ACCOUNT8, accoun8)
intent.putExtra(ACCOUNT9, accoun9)
and so on. How can I make this transfer easier? Maybe is some other ways to pass multiply values from one activity to another activity?
I recently had a similar case.
How I solved:
I created an entity that kept all the information for me, that way, I just passed an object between activities, but I had everything I needed inside that object.
Hope this can help.
There is a bundleOf function in the Jetpack core-ktx library that works like mapOf.
val intent = Intent(this, SecondActivity::class.java)
val extras = bundleOf(
ACCOUNT1 to accoun1,
ACCOUNT2 to accoun2,
ACCOUNT3 to accoun3,
// etc.
)
intent.putExtras(extras)
But that doesn't save much code compared to just using apply unless you use the same bundle of extras in multiple places in your code:
val intent = Intent(this, SecondActivity::class.java).apply {
putExtra(ACCOUNT1, accoun1)
putExtra(ACCOUNT2, accoun2)
putExtra(ACCOUNT3, accoun3)
//...
}
You could make a parcelable data class that stores all your values and pass that instead. See instructions here for creating the class easily: https://developer.android.com/kotlin/parcelize
#Parcelize
data class AccountInfo(
val account1: String,
val account2: String,
val account3: String,
//...
): Parcelable
Then you can put this into your bundles, and you don't have to create a bunch of the same kinds of variables in both activities, because all the variables are inside one class.
val intent = Intent(this, SecondActivity::class.java).apply {
putExtra(ACCOUNT_INFO, myAccountInfoInstance)
}
if all of your variables has the same type you can add all to list and pass the list to second activity/fragment.

Launch Activity from onClick method of Listview (Fragment)

I recently started learning Android development in Kotlin. I did follow this guide and everything went good.
Now I'm trying to merge the content of those two guides:
https://developer.android.com/training/contacts-provider/retrieve-details.html#kotlin
and
https://developer.android.com/guide/components/fragments#Example
in order to display the details of a Contact using Fragments. I'm having trouble to launch an activity in the onItemClick method (the guide uses a ListView):
override fun onItemClick(parent: AdapterView<*>, view: View?, position: Int, id: Long) {
// Get the Cursor
val cursor: Cursor? = (parent.adapter as? CursorAdapter)?.cursor?.apply {
// Move to the selected contact
moveToPosition(position)
// Get the _ID value
contactId = getLong(Companion.CONTACT_ID_INDEX)
// Get the selected LOOKUP KEY
//contactKey = getString(CONTACT_KEY_INDEX)
mContactKey = getString(Companion.CONTACT_KEY_INDEX)
// Create the contact's content Uri
contactUri = ContactsContract.Contacts.getLookupUri(contactId, mContactKey)
/*
* You can use contactUri as the content URI for retrieving
* the details for a contact.
*/
}
val intent = Intent().apply{
setClass(activity,DetailsActivity::class.java)
putExtra("contactID",contactId)
putExtra("mContackKey",mContactKey)
putExtra("contactUri",contactUri)
}
startActivity(intent)
}
If I create the Intent to start the activity as displayed in the guide, I get the compiler error "Inferred type is FragmentActivity?, but context was expected".
I changed then the Intent to either one of the following:
val intent = Intent().apply{
setClass(requireContext(),DetailsActivity::class.java)
putExtra("contactID",contactId)
putExtra("mContackKey",mContactKey)
putExtra("contactUri",contactUri)
}
startActivity(intent)
or
val intent = Intent().apply{
context?.let { setClass(it,DetailsActivity::class.java) }
putExtra("contactID",contactId)
putExtra("mContackKey",mContactKey)
putExtra("contactUri",contactUri)
}
startActivity(intent)
whit this, I do not get the compiler error, but in the Logcat I see the notice "W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy#9dc9013"
Can you please point me to the correct way to instantiate an activity from the onClick method of a ListView inside a Fragment ? Thank you!
On a related note: do you recommend those guides or is their content obsolete ?
Edit: the full fragment class is here
Try below code for opening new activity from fragment :
activity?.let{
val intent = Intent (it, DetailsActivity::class.java)
intent.putExtra("contactID",contactId);
intent.putExtra("mContackKey",mContactKey);
intent.putExtra("contactUri",contactUri);
it.startActivity(intent)
}
startActivity() is a function in the Context class (of which Activity is a subclass), not of the Fragment class.
So you can make a direct bare call to startActivity() from within the code of a subclass of Context (as any Activity implementation is), but when you are calling it from a Fragment, you have to call it on a context: context.startActivity().
The Fragment.context property is nullable, so you can use requireContext().startActivity(). It won't be null when responding to clicks, so this is safe.

Kotlin running certain activity and accessing class object

I followed this guide (How to run a certain activity in Android Studio?) to launch another activity aside from my main.
I have a GetUser.xml and ShowUser.xml layouts.
In GetUser.xml, user can enter their name and age.
I have a user class with constructor that takes in name and age inside GetUser.kt. I initialize User object with the values : name, age I got from the input fields in GetUser.
Now when I run the other activity ShowUser, I wish to access this object so I can get the values and display it in ShowUser.xml
My question is how do I access this object from the GetUser.kt and use it in ShowUser.kt ?
As far as I understand, you are looking for extra.
When starting one Activity from another, you can pass data via extra.
Let's say you have a class Person with String name and int age.
There are 2 simple ways to to this.
1. Send data separately
Because Person is a simple class that consists of 2 member fields, we can pass each data separately and combine into Person in started Activity.
We need Intent to do this.
val p = Person(name, age) // Person data
val intent = Intent(this, NewActivity::class.java)
intent.putExtra('name', p.name)
intent.putExtra('age', p.age)
startActivity(intent)
On started NewActivity's onCreate(), you can receive this data and make an object out of it.
val name = intent.getStringExtra('name')
val age = intent.getIntExtra('age')
val combinedPersonData = Person(name, age)
2. Send whole instance
If the class you are trying to send is too big to use method 1, you can try sending it as itself.
To do this, you need to implement Serializable or Parcelable to your class.
class Person(val name: String, val age: Int): Serializable { ... }
Make sure all of the members in the class are also Serializable or are primitive types.
With this, you can send the person object as serializable object.
val p = Person(name, age) // Person data
val intent = Intent(this, NewActivity::class.java)
intent.putExtra('person', p)
startActivity(intent)
In the receiver's onCreate(),
val p = intent.getSerializableExtra('person') as Person
will receive the while Person data.

Sending information between Activities in Kotlin

fun kullaniciOlustur2(view: View){
val intent = Intent(applicationContext,KullaniciOlustur2::class.java)
intent.putExtra("input",makeUsername.text.toString())
intent.putExtra("input2",makeUserphone.text.toString())
startActivity(intent)
}
Mainactivity2 starts here..before this, I was using
val intent = intent
val received: String = intent.getStringExtra("input")
makeUsername.text = received
But this method doesn't work anymore.
I tried using getIntent() but couldn't get anything
val intent = getIntent()
Try this code
Activity 1
val intent = Intent(FirstActivity.this,SecondActivity::class.java) //not application context
intent.putExtra("input",makeUsername.text.toString())
intent.putExtra("input2",makeUserphone.text.toString())
startActivity(intent)
Activity 2
inside onCreate() method use
val stringOne = getIntent().getStringExtra("input")
Or more cleaner way is
val extras = getIntent().getExtras()
if (null != extras) {
val value = extras.getString("input")
//The key argument here must match that used in the other activity
}
and please check similar answers in Java, you may be able to get the Idea here already told in another answer.
I also Use Anko to remove this kind of boilerplate code
I recommend using Kotlin Anko, there are plenty of methods that will help you to remove this boilerplate code
check Anko Intents here
Use Below Code:
The Code is same as Java .Just difference is kotlin do not have
1. No semicolon at the end.
2. to call another activity kotlin use ::
ex.KotlinActivity::class.java
startActivity(Intent(this, KotlinActivity::class.java).putExtra("DataTrasfer", ""))
To Get Value:
intent.getStringExtra("DataTrasfer")

Categories

Resources