What am I doing wrong?
I've looked at other questions and thought I was doing the exact same things, but since its not working for me, obviously I'm doing something wrong!
I have my MainActivity.class that gets JSON data (coordinates) from a URL. This part works. I then want to load up a MapView, called OverlayActivity.class, and send this data to this map so I can populate it with overlays etc.
I pull varying numbers of points down and dynamically create buttons. Depending on what button is clicked, it sends different data.
Here's the code for this loop:
final LinearLayout layout = (LinearLayout) findViewById(R.id.menuLayout);
layout.removeAllViewsInLayout();
String itemName="";
int itemID=0;
for (int i = 0; i < dataSetsMap.size(); i++) {
itemID=i+1;
itemName=dataSetsMap.get(itemID);
Button b = new Button(this);
b.setText(itemName);
layout.addView(b);
// These need to be final to use them inside OnClickListener()
final String tempName=itemName;
final int tempID=itemID;
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent();
Bundle b = new Bundle();
i.setClass(myContext, OverlayActivity.class);
Log.i(TAG, "Setting extras: 1:"+tempName+" and 2:"+tempID);
b.putInt(tempName, tempID);
i.putExtras(b);
startActivity(i);
}
});
} // End for()
So obviously I want to read this data on the other side, assuming I'm sending it correctly. So, to read it, I've been trying a few different things:
//Method 1:
String test1=intent.getStringExtra("name");
String test2=intent.getStringExtra("id");
//Method 2:
String meh=getIntent().getExtras().getString("id").toString();
String bleh=getIntent().getExtras().getString("name");
//Method 3:
String value=savedInstanceState.getString("name");
String id=savedInstanceState.getString("id").toString();
//Method 4:
Bundle bundle = getIntent().getExtras();
String id=bundle.getString("id");
String value = getIntent().getExtras().getString("name");
i get a NullPointerException when trying to use any of these methods. Its my first time using these types of methods so can someone point me in the right direction or tell me where I've gone wrong?
Firstly, using Bundle b when you've already got Button b isn't really a good idea if for no other reason than it gets confusing, ;)
Secondly, you don't need to use a Bundle to pass a string and an int. Just add them to your Intent directly...
Intent i = new Intent(myContext, OverlayActivity.class);
i.putExtra("name", tempName);
i.putExtra("id", tempID);
startActivity(i);
To retrieve them in your OverlayActivity use...
Intent i = getIntent();
String name = i.getStringExtra("name");
int id = i.getIntExtra("id", -1); // -1 in this case is a default value to return if id doesn't exist
Why not just do this:
Intent i = new Intent();
i.setClass(myContext, OverlayActivity.class);
Log.i(TAG, "Setting extras: 1:"+tempName+" and 2:"+tempID);
i.putExtra("name", tempName);
i.putExtra("id", tempID);
startActivity(i);
and then you can fetch them with:
String name = getIntent().getStringExtra("name", "");
int id = getIntent().getIntExtra("id", 0);
Related
I am a new android programmer.
I have 4 activities: A B C D.
The order is A -> B -> C -> D -> A and A -> D using buttons.
I want to save data in ArrayList that is in activity D.
The problem is that when I move from D to A and come back to D, the data in the ArrayList didn't save.
Code for D activity here:
public class SchedulerActivity extends AppCompatActivity {
public String name = "";
public String number = "";
public String date = "";
public String hour = "";
public ArrayList<EventClass> scheduler = new ArrayList<>();
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scheduler);
Bundle extras = getIntent().getExtras();
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(SchedulerActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
finish();
}
});
if (extras != null) {
String sender = extras.getString("sender");
if(sender.compareTo("Hours") == 0) {
name = extras.getString("name");
number = extras.getString("number");
date = extras.getString("date");
hour = extras.getString("hour");
Date real_date = new Date();
SimpleDateFormat formatter1=new SimpleDateFormat("dd/MM/yyyy");
try {
real_date = formatter1.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
scheduler.add(new EventClass(real_date, name, number, "", hour));
for (EventClass event : scheduler){
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
final TextView t = new TextView(this);
t.setText(event.toString());
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
linearLayout.addView(t, params);
}
}
else{
for (EventClass event : scheduler){
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
final Button btn = new Button(this);
final TextView t = new TextView(this);
t.setText(event.toString());
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
linearLayout.addView(btn, params);
}
}
}
}
I want to change my ArrayList when C->D occurs and print it and when D->A occurs I just want to print it. I know that I can with SharedPreferences but for the first step, I want to do this with ArrayList.
What's the best way to do this?
Creating static objects is not a good approach. So you can use android activity stack in-place of using static Arraylist. Android activities are stored in the activity stack. Going back to a previous activity could mean two things.
You opened the new activity from another activity with startActivityForResult. In that case you can just call the finishActivity() function from your code and it'll take you back to the previous activity.
Keep track of the activity stack. Whenever you start a new activity with an intent you can specify an intent flag like FLAG_ACTIVITY_REORDER_TO_FRONT or FLAG_ACTIVITY_PREVIOUS_IS_TOP. You can use this to shuffle between the activities in your application.
The scheduler is a non-static field in the SchedulerActivity which means that its existance is tied to the instance of the activity. When the activity instance is destroyed, and that might happen for example when the screen orientation is destroyed or you move to another activity, so are all its non-static fields. You can change that by adding a static keyword before your field:
public static ArrayList<EventClass> scheduler = new ArrayList<>();
Now, your field is tied to the class itself, not the instance, whitch means it wont be destroyed along with the instance. But it also means that it is shared between all instances and must be referenced with the class name outside of the class body:
EventClass event = SchedulerActivity.scheduler.get(0)
A good approach is saving your data in a local database, like Room. You need to save before go to new activity, and get it back on OnResume().
I want to pass the string from activity to other activities.
For example, tell that I have 5 activities I get a text from the second to the third to the forth to the fifth but when I click a button to go to the third the text is not saved how can I save the string when I pass it?
i try to pass the text that i get from second activity to all the others with Intent:
//While on MainActivity
Intent Second = new Intent(MainActivity.this, SecondActivity.class);
startActivity(Second);
//While on SecondActivity
Intent Third = new Intent(SecondActivity.this, ThirdActivity.class);
Third.putExtra("Third", String);
startActivity(Third);
//While on ThirdActivity
TextView String;
String = findViewByID(R.id.TextView1);
String.setText(string);
String string = getIntent().getStringExtra("Third");
Intent Forth = new Intent(ThirdActivity.this, ForthActivity.class);
Forth.putExtra("Forth", string);
startActivity(Forth);
And i passing strings like that until Activity 5 that has a button that goes to the third and the textview text is not saved
I expected when I click the button from activity 5 that goes to the third activity the text view on third activity to be the text from the second activity that I pass it.
Forward all Extras
You can "forward" all extras using putExtras(intent):
Intent third = new Intent(this, ThirdActivity.class);
third.putExtras(getIntent());
third.putExtra("THIRD", myString);
This will maintain the same key at every step, so if you backtrack (Activity 5 => Activity 3) you can still extract the relevant values for that activity.
Bonus: Use constants to avoid typos
Since your extras might be read in multiple Activities, I would define constants in the final Activity in your flow (I assume a summary or confirmation activity):
public class LastActivity extends AppCompatActivity {
public static final String EXTRA_NAME = "EXTRA_NAME"
public static final String EXTRA_EMAIL = "EXTRA_EMAIL"
public static final String EXTRA_BOOKING_ID = "EXTRA_BOOKING_ID"
// rest of class
}
Then you don't risk typos when you putExtra or getXxxExtra:
String name = intent.getStringExtra(LastActivity.EXTRA_NAME);
I'm trying to make a pretty simple app to help my girlfriend feel safer.
Im really bad at this, and a little help would go a long way. I've been trying to work with intents, and I really feel as if I'm super close to the solution at hand, I just need a little help.
So, the opening page is supposed to wait until you have data in your shared Preferences and then it will act on it.
The second page is supposed to take some data from EditTexts and store it in your intent. For some reason though, my data is not being stored, and when I pull something from the intent it is "".
CLASS 1:
public void ActivateAlarm(View view){
Bundle myBundle = getIntent().getExtras();
if(myBundle == null){
Log.i("The bundle is empty!", "Smashing success!");
}
else{
SharedPreferences sharedPreferences = this.getSharedPreferences("com.example.jackson.distressalarm", Context.MODE_PRIVATE);
String NumberToCall = sharedPreferences.getString("CallNumber", "");
String TextOne = sharedPreferences.getString("1Text", "");
String TextTwo = sharedPreferences.getString("2Text", "");
String TextThree = sharedPreferences.getString("3Text", "");
Button myButton = (Button) findViewById(R.id.button);
myButton.setText(TextOne);
Log.i("MY NUMBER TO CALL", NumberToCall);
/*Take in the data from the settings. Check it for consistency.
1)Are the numbers empty?
2)Is the number 911 or a 7 digit number?
3)Do they have a passcode?
4)Is the number real? No philisophical BS
*/
}
}
CLASS 2:
public void GoToAlarm(View view){
EditText NumberToCall = (EditText) findViewById(R.id.callNumber);
EditText text1 = (EditText) findViewById(R.id.textNumOne);
EditText text2 = (EditText) findViewById(R.id.textNumTwo);
EditText text3 = (EditText) findViewById(R.id.textNumThree);
Intent intent = new Intent(this, AlarmActive.class);
intent.putExtra("callNumber", NumberToCall.getText().toString());
intent.putExtra("1Text", text1.getText().toString());
intent.putExtra("2Text", text2.getText().toString());
intent.putExtra("3Text", text3.getText().toString());
startActivity(intent);
}
I think the problem is coming from a bit of a mix-up between Intents and SharedPreferences.
An Intent is a way to pass data from one activity to another. You're passing data correctly in Class 2, but you're not retrieving it in Class 1. Here's how you can do that:
String NumberToCall = intent.getStringExtra("CallNumber");
String TextOne = intent.getStringExtra("1Text");
String TextTwo = intent.getStringExtra("2Text");
String TextThree = intent.getStringExtra("3Text");
SharedPreferences are a way to save user data. If you want to save data in addition to passing it between activities, you'll need to add it to SharedPreferences with the following code:
SharedPreferences preferences = this.getSharedPreferences("com.example.jackson.distressalarm", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("callNumber", NumberToCall.getText().toString());
editor.putString("1Text", text1.getText().toString());
editor.putString("2Text", text2.getText().toString());
editor.putString("3Text", text3.getText().toString());
editor.apply();
You can retrieve the values with the code you were using in Class 1.
I am trying to send a string and a int type data from one activity to another but due to lack of knowledge i don't know how to do it.
With the particular coding given below now i can only send any one of the data type.
searched a lot but not found any answer appropriate for my question. If i have asked any thing wrong plzz notify me as i am new to android Dev.
Any help may be appreciated.
this is my java coding of the two activities :
First.java
public class QM extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qm);
}
public void FLG(View view) {
// Do something in response to button
EditText mEditText= (EditText)findViewById(R.id.editText1);
String str = mEditText.getText().toString();
Intent intent = new Intent(this, Q1.class);
intent.putExtra("myExtra", str);
startActivity(intent);
finish();
}
}
Second.java
public class Q1 extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_q1);
Intent intent = getIntent();
if (intent.hasExtra("myExtra")){
TextView mText = (TextView)findViewById(R.id.textView1);
mText.setText("user name "+intent.getStringExtra("myExtra")+"!"); }
}
}
You can send 2 extras or even more as long you have different keys for it, so in your problem you need 2 extras one for String and one for Integer.
sample:
pass:
Intent intent = new Intent(this, Q1.class);
intent.putExtra("myExtra", str);
intent.putExtra("myExtraInt", yourInt);
get:
Intent intent = getIntent();
if (intent.hasExtra("myExtra") && intent.hasExtra("myExtraInt")){
TextView mText = (TextView)findViewById(R.id.textView1);
mText.setText("user name "+intent.getStringExtra("myExtra")+"!");
int extraInt = intent.getIntExtra(myExtraInt);
}
I'd like to give you some information.
Imagine the Intent's extras to be a (theoretically) infinitely sized bagpack. You can put certain type of data into it in an infinite number as long as each of the data has a unique name which is a string.
Internally it's a table that maps names to values.
So: Yes you can put String and Int simultaneously into the Intent's extras like this.
String str = "Test";
int val = 2933;
Intent i = new Intent(MyActivity.this, NewActivity.class);
i.putExtra("MyStringExtraUniqueName", str);
i.putExtra("MyIntExtraUniqueName", val);
To check for it use i.hasExtra("MyStringExtraUniqueName") as you did already and to get it use i.getExtra("MyStringExtraUniqueName").
BUT if you only use getExtra you'll be returned data of type object. Remember to cast the returned value to the appropriate type or use one of the specialized getter methods for some predefined data types.
See this for the available getters: http://developer.android.com/reference/android/content/Intent.html
Bundle data = new Bundle();
data.putInt("intKey", 5);
data.putString("stringKey", "stackoverflow");
Intent i = new Intent(MyActivity.this, NewActivity.class);
i.putExtras(data);
//And in the second acitvity fetch this way
Bundle data = getIntent().putExtras(b);
I am trying to pass the ID of the clicked on data from my listview to a new activity in a second class i.e. I click the item on the listview.The onListItemClick method is called and starts a new intent. The id is passed with the object in the i.getExtra. Then the id is stored into a new variable on the second class to be used later.
Ive got as far as working out how to pass the id, but I cant seem to work out how I then store it in the new variable on the second class.
Heres my code:
public void onListItemClick(ListView list, View v, int list_posistion, long item_id)
{
long id = item_id;
Intent i = new Intent("com.example.sqliteexample.SQLView");
i.putExtra(null, id);
startActivity(i);
}
Could anyone tell me how to reference it in the second class?
You need to get Bundle from Intent and then do get... to get particular element.
Bundle extras = getIntent().getExtras();
String id;
if (extras != null) {
id= extras.getString("key"); //key should be what ever used in invoker.
}
One thing surprising is why you are using null as key? I would avoid using reserve words, instead use proper name like userID etc.,
Intent intent = new Intent("com.example.sqliteexample.SQLView");
Bundle bundle = new Bundle();
bundle.putString("position", v.getTag().toString());
intent.putExtras(bundle);
context.startActivity(intent);
in second class
Bundle intent= getIntent().getExtras();
if (intent.getExtras() == null) {
id= intent.getString("position");
}
Hope this helps
It is very simple.
Just change :
i.putExtra(null, id);
with :
i.putExtra("myId", id);
and in the second Activity just use :
Bundle extras = getIntent().getExtras();
if (extras != null) {
String value = extras.getInt("myId");
}
The first parameter for Intent.putExtra() is a String key used to identify your Extra. Instead of i.putExtra(null, id) try i.putExtra("SomeString", id).
Then, in the onCreate of (or anywhere within) your second activity, you can get your id back from the intent like this:
Intent intent = getIntent();
long id = intent.getLongExtra("SomeString");
There are also methods for getting Strings, Chars, Booleans, Ints, and more complex data structures. Check here: http://developer.android.com/reference/android/content/Intent.html for more info on methods for the Intent class.