Bundle loses all data between two Activities - java

I've got two different activities Menu and Exercise.
I need to pass some data from Menu to Exercise when I start the latter activity via the click of a button.
Here is the code in Menu activity:
Button b = (Button) findViewById(R.id.temp);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
Intent i = new Intent(context, ExerciseActivity.class);
Bundle b = new Bundle();
b.putString("colors","Blue");
b.putIntArray("workoutlist",new int[] {0,1});
i.putExtras(b);
//i.putExtra("workoutlist",MyApp.workoutList.get(0));
//i.putExtra("colors","Blue");
startActivity(i);
}
});
Using debugging tools I've checked that all the data are inside the bundle of the intent properly.
And here is the code that should retrieve data from the intent in Exercise Activity:
Intent in = getIntent();
Bundle b = in.getExtras();
String[] colorSets = (String[]) b.get("colors");
int[] l = (int[]) b.get("workoutlist");
The fact is when I get the bundle it is empty, and obviously I cannot proceed.
Moreover I already used almost the same code between to other activities and everything is working fine.
Why is this happening? Is it there something I'm missing which generates this error? Maybe some incompatibility between the two activities?
Thank you for your help!

you add String using putString() and get it using getString(). the same goes for other types.
Intent in = getIntent();
Bundle b = in.getExtras();
String colorSets = b.getString("colors");
int[] l = b.getIntArray("workoutlist");

Related

getText with AutoCompleteTextView

The code worked back when I still used an EditText, but I changed it to an AutoCompleteTextView to make things easier for the user, and now I have a problem. Here is the bulk of the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
AutoCompleteTextView edit = (AutoCompleteTextView) findViewById(R.id.et_item);
String[] items = getResources().getStringArray(R.array.items_array);
java.util.Arrays.sort(items);
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
edit.setAdapter(adapter);
public void find(View view) {
String name = edit.getText().toString();
if(name.equalsIgnoreCase("Brown Turkey Fig")){
Intent intent = new Intent(this, BrownTurkeyFig.class);
startActivity(intent);
}
else if(name.equalsIgnoreCase("Emerald Green Arborvitae")){
Intent intent = new Intent(this, EmeraldGreenArborvitae.class);
startActivity(intent);
}
else if(name.equalsIgnoreCase("Delaware Valley White Azalea")){
Intent intent = new Intent(this, DelawareValleyWhiteAzalea.class);
startActivity(intent);
}
Ive included the parts that are related to the question. Basically, the user types the name of a plant in the AutoCompleteTextView, and then clicks a button to be brought to a new activity based on whatever plant they typed in (I included three as examples at the end). Before I added the autofill part, the code worked fine the way it was.
The problem is that when the button is clicked, the next activity is not brought up. It crashes the app.
I do not know what is wrong with it now. Perhaps I am not properly taking the actual text from the AutoCompleteTextView to be compared in my if statements? Any help is appreciated!
You are declaring a local variable "edit" in your oncreate method but also you are using a global variable in your "find" method.
I'm sorry , I can't understand what's your meaning. Maybe you can try to use AutoCompleteTextView.setOnItemClickListener. For example:
edit.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String item = items.get(position);
if(item.equalsIgnoreCase("Brown Turkey Fig")){
Intent intent = new Intent(this, BrownTurkeyFig.class);
startActivity(intent);
} else if(item.equalsIgnoreCase("Emerald GreenArborvitae"){
Intent intent = new
Intent(this,EmeraldGreenArborvitae.class);
startActivity(intent);
} else if(item.equalsIgnoreCase("Delaware Valley White Azalea")){
Intent intent = new Intent(this, DelawareValleyWhiteAzalea.class);
startActivity(intent);
}
}
})
Hope to help you.

How to save an int for another activity?

I have one activity where the user writes in an EditText a number, then I am supposed to convert it to a string and then to an int, but I want to save that value because I am going to use it for another activity, it will be the max number of times that a botton can be pressed but I don't know how to save it from the EditText in a activity to an int in another activity.
Here the EditText of the first activity:
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:id="#+id/texthome"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:hint="Ejemplo:15"
android:layout_weight="1"
android:textSize="20sp" />
Here the textview into int:
EditText conttext = (EditText) findViewById ( R.id.texthome );
String maxicont = conttext.getText().toString();
int maxcont = Integer.parseInt(maxicont);
UPDATE:
i get errors in:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button buttsave = (Button) findViewById(R.id.buttsave);
buttsave.setOnClickListener(new View.OnClickListener"here" {
public void onClick "here" {
Intent intent = new Intent(getApplicationContext(), GuessOne.class);
intent.putExtra("maxNumberPressed", conttext.getText());
startActivity(intent);
}
});
I get errors where i placed the "here" obviously it is not part of the code. It is only to see where the errors are.
You need to use Intents for that. A similar question was answered here:
Passing Values To Another Activity
When starting the other activity, make a bundle.
In the current activity, try:
Intent intent = new Intent(getApplicationContext(), <next activity>.class);
intent.putExtra("maxNumberPressed", editText.getText());
startActivity(intent);
Then in the next activity where you are using it, put this in onCreate method:
Bundle bundle = this.getIntent().getExtras();
String maxPressed = bundle.getString("maxNumberPressed");
Create a button with text as 'save' or something. then do:
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener{
public void onClick() {
Intent intent = new Intent(getApplicationContext(), <next activity>.class);
intent.putExtra("maxNumberPressed", editText.getText());
startActivity(intent);
}
});
How to pass data from an Activity to another can vary a lot, depending on how the Activities are related.
If you are passing data from a parent to a child Activity, you pass the information through an Intent when starting the new child Activity. Here's how you send the information:
itt = new Intent(this, ChildActivityName.class); // Create new Intent
itt.putExtra("MAX", maxcont); // Fill Intent with data
startActivity(itt, SOME_NUMBER_IDENTIFYING_THE_PARENT); // Start Activity
And here's how the receiving child Activity retrieves it:
void onCreate(Bundle savedInstanceState) {
...
Intent itt = getIntent(); // Grab the Intent created with this Activity
int maxcont = itt.getIntExtra("MAX", -1); // Retrieve data, default is -1
}
If you are passing data the other way, from a child to a parent Activity, the simplest way to pass through using startActivityForResult. The parent starts the child activity using this command:
startActivityForResult(itt, SOME_NUMBER_IDENTIFYING_THE_PARENT);
The Child then passes the information back to the parent just before it exits:
Intent itt = new Intent(); // Create new Intent
itt.putExtra("MAX_RETURN", maxcont); // Add data to the Intent
setResult(RESULT_OK, itt); // Signal to parent valid result
finish(); // End this Activity
Once the child calls finish(), the parent's onActivityResult() method will be invoked:
protected void onActivityResult(int requestCode, int resultCode, Intent itt) {
maxcont = data.getIntExtra("MAX_RETURN", -1); // defaults to -1
...
}
The Strings used in putExtra and getIntExtra are identifying keys for associated data, which are used all over the place in Android programming and beyond the scope of this question. Just make sure that the sender and the receiver of the data through the Intents use the EXACT same string!
If you need to pass information between two sibling Activities that are both active, the easiest way is through static public variables in each Activity. That's pretty basic; you should have no problem with these.
If you need to pass information between two sibling Activities that may or may not be Active, then you need to use a Broadcast/Receiver paradigm. But I think that method is overkill for what you are talking about.

Unable to recieve data, from Intent in new activity.

Well, as I mentioned in heading, I can't get data from one activity, to another. I am making a really simple RSS reader, that loads data asynchroously, sends them to listview and opens the selected article in new activity's webview. And the problem is, that when i try to start an activity with webview, a can't pass data from the main activity.
So here is what I am doing:
1) In first activity (Main activity), i get data from my listview element, that user clicks on:
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
News clicked = (News) adapter.getItem(arg2);
String clickedTitle = clicked.title;
String clickedLink = clicked.link;
System.out.println("Title: " + clickedTitle + " / LINK: " + clickedLink); /*Here I can see my data in logs -> they are correct at this moment*/
Intent intent = new Intent(MainActivity.this, OpenFullArticle.class);
intent.putExtra(clickedTitle, "clickedTitle");
intent.putExtra(clickedLink, "clickedLink");
startActivity(intent);
}
});
So for now everything is okey, but than, when a new activity is started (OpenFullArticle activity), I am doing this:
public class OpenFullArticle extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_open_full_article);
String title = getIntent().getExtras().getString("clickedTitle");
String link = getIntent().getStringExtra("clickedLink");
System.out.println(title); //Tried link too, simultaneous each one - both ar null
}
So I'm stuck for this moment and have no idea, what I'm doing wrong. Tried debuger, checked the Intent, and it hadn't extras there, that I added in first activity.
Maybe you can give me a clue, what could cause such a strange issue.
P.S. If it's necessary, I can provide a full code or a full project in github.
Use following code in first activity
Intent intent = new Intent(MainActivity.this, OpenFullArticle.class);
intent.putExtra( "clickedTitle",clickedTitle);
intent.putExtra("clickedLink", clickedLink, );
startActivity(intent);
Change to
intent.putExtra("clickedTitle", clickedTitle);
// the first pram is the key
// the second is the value
intent.putExtra("clickedLink", clickedLink);
http://developer.android.com/reference/android/content/Intent.html#putExtra(java.lang.String, android.os.Bundle)
Also use Log instead of System.out.println.
http://developer.android.com/reference/android/util/Log.html
The mistake is in this line:
intent.putExtra(clickedTitle, "clickedTitle");
intent.putExtra(clickedLink, "clickedLink");
You need to give key first and then the value:
intent.putExtra("clickedTitle", clickedTitle);
Replace
intent.putExtra(clickedTitle, "clickedTitle");
intent.putExtra(clickedLink, "clickedLink");
with
intent.putExtra("clickedTitle",clickedTitle);
intent.putExtra("clickedLink",clickedLink);
Use the following code in your first activity
Intent intent = new Intent(MainActivity.this, OpenFullArticle.class);
intent.putExtra( "clickedTitle",clickedTitle);
intent.putExtra("clickedLink", clickedLink, );
startActivity(intent);
Initially try to isolate the issue by passing some hardcoded values to extras
like
intent.putExtra("id",1);
intent.putExtra("name","abc");
and check whether OpenFullArticle activity has the extras.

How to pass and manipulate objects between activities using intents

This is my first issue with the Android lifecycleand I feel somewhat helpless:
In Activity A there's onCreate. That's the spot where I create an ArrayList called playerNames and ArrayList called moves. Also there's some more stuff happening in oncreate. In A's onStart I create a flag so I know which Activity is running in case I'd like to close all at once. In onDestroy the flag is set back to null.
Eventually I make an intent to get to Activity B where I take the moves list along. Works fine.
Now I'd like to make an intent from B to get back to A. What happens in the lifecycle when I attempt that? Obviously onCreate of A is called and leads to a NullPointerException regrding the playerNames list.
I'd like to store this ArrayList while B is running and get it back when I come back to A. Which method is the right one (onResume? onRestart?) and how do I store it? Do I really need SharedPreferences?
Thanks in advance for your kind help
On Activity A:
-Create an Intent, specifying wich activity you want to start
-Put data on that intent to be received by activity B.
-Start Activity for a result.
-On onActivityResult() verify that you have data to receive and do what you want with it.
On Activity B:
-On the onCreate() receive the data from Activity A;
-Modify the data as you wish;
-Create a new Intent;
-Put the data in the Intent;
-Set the activity result and the intent data.
-Finish activity B
Below is a sample of the steps I describe, what it does is have activity A start an Activity B, and passing it an empty ArrayList. Then on Activity B, the arrayList is populated and sent back to Activity A where the contents of the arrayList, are displayed on screen.
Code:
Activity A:
private static final int REQUEST_LIST = 1;
ArrayList<String> myList;
TextView listText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listText = (TextView) findViewById(R.id.mylist_text);
myList = new ArrayList<String>();
Intent i = new Intent(MainActivity.this, ActivityB.class);
i.putExtra(ActivityB.EXTRA_ARRAY, myList);
startActivityForResult(i, REQUEST_LIST);
}
#Override
protected void
onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) return;
if (requestCode == REQUEST_LIST) {
myList = (ArrayList<String>) data.getSerializableExtra(ActivityB.EXTRA_ARRAY);
StringBuilder text = new StringBuilder();
for (int j = 0; j < myList.size(); j++) {
text.append(myList.get(j) + " ");
}
listText.setText(text.toString());
}
}
Activty B:
public static final String EXTRA_ARRAY = "com.example.androidtest.mainactivity.array";
ArrayList<String> myList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activityb_layout);
myList = (ArrayList<String>) getIntent().getSerializableExtra(EXTRA_ARRAY);
for (int i = 0; i < 10; i++) {
myList.add(String.valueOf(i));
}
Intent data = new Intent();
data.putExtra(EXTRA_ARRAY, myList);
setResult(Activity.RESULT_OK, data);
finish();
}
Attention: You cannot forget to declare your Activity B in the manifest File. Also pay attention on how the activities know what data to send and collect, through constants created in the classes, wich must be consistent, so avoid using literal strings, and use defined constants.
From Activity B you can come back to the previous A instance using:
Intent intent = new Intent(this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
This will clear all current stack and go back to the A instance ( http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP ). As long as your Activity doesn't get destroyed, you'll have all data there.
Anyway, you should consider use Activity's save instance state capability ( http://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState%28android.os.Bundle%29 ).

Make my class take an argument

Well I have a main Screen with 5 buttons. Each time a press a button I want to go a new screen. So far I have other 5 classes (each for each screen) and 5 xmls. But Iam sure that there will be a better way beacuse this screen and the xmls are the same, and what I want to do is change some texts and some data I fetch from a database. I am sure that I can ony another class and only one xml and then pass the values that I want as arguments. (Imagine that in its final state my app must have 15 buttons, so I think it is too mych waste of space and unnecessary to have 15 .java files and 15 xml files that look the same and only some values of images and textviews change). My code for main activity is:
public class MyActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
main2Theme();}
private void main2Theme() {
setContentView(R.layout.main_new);
Button Button100 = (Button)findViewById(R.id.Button100);
Button113.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
Intent i = new Intent(this, OtherScreenName.class);
startActivity(i);
}
}); //and so on for 15 buttons
My OtherScreenName.class is:
public class OtherScreenName extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Theme();
}
#SuppressWarnings("null")
private void Theme() {
Log.d("SnowReportApp","Do first thing");
setContentView(R.layout.otherscreenname); //THIS CHANGES IN EVERY CLASS DEPENDING ON THE ID OF THE BUTTON
String result = "";
InputStream is = null;
StringBuilder sb=null;
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();//() before
nameValuePairs.add(new BasicNameValuePair("ski_id","OtherScreenName"));
TextView text1 = (TextView) findViewById(R.id.otherscreenname_1);
//THESE 2 CHANGE DEPERNDING ON THE BUTTON PRESSED
//perform action.....
//AND ALSO HERE I NEED THE ID OF THE BUTTON
b1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(OtherScreenName.this,MyActivity.class);
startActivity(i);
}
});
Can anyone suggest how to give arguments to my class and what it should be the type of them?
If I understand your question correctly, you want to pass arguments to the activity. Normally it would be done through the class constructor, however, activities can't have user defined constructors, only the default one; they can be instantiated only indirectly via intent creation. If you need to pass data between activities, do it by putting extras to bundles, for example:
bundle.putInt("intName",intValue);
then you can extract the data from bundle by
int intValue = bundle.getInt("intName");
Put extras before starting the activity:
Intent i = new Intent(this, YourActivity.class);
Bundle b = new Bundle();
b.putInt("intName",intValue);
i.putExtras(b);
startActivity(i);
and then read the extras in the onCreate method:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
int intValue;
if (b != null)
{
intValue= b.getInt("intName");
}
}
The same way you can pass other data types as String boolean etc. If this is not sufficient and you need to pass some more complex data, then use Parcelable interface.
You can pass parameters with an Intent by adding extra's to it, something like the following:
Intent i = new Intent(this, MyActivity.class);
i.putExtra("paramName", "value");
startActivity(i);
In your activity you can use the getIntent() method to retrieve the Intent and extract your parameter(s) from it:
Intent i = getIntent();
Bundle extras = i.getExtras();
String param = extras.getString("paramName", "default value");
You can place all the different text and data in your Intent, but you can also decide based on the value of an Intent parameter which data and text to retrieve. If it is a lot of data or text you are probably better off using the second approach.
If you want to pass object instead of simple data, you must use parcelable objects as it´s explained in: [http://developer.android.com/reference/android/os/Parcelable.html][1]
Reading and writing with parcelable objects is very similar to the way with a simple data
Intent intent = new Intent(this ,newthing.class);
Bundle b = new Bundle();
b.putParcelable("results", listOfResults);
intent.putExtras(b);
startActivityForResult(intent,0);
Intent i = getIntent();
Bundle extras = i.getExtras();
String param = extras.getParcelable("results");

Categories

Resources