Losing intent extras between activities - java

I'm having an issue where I'm losing Extras between activites.
I'm sending a ChatObject from a MainActivity Recyclerview to a ChatActivity, and it works fine.
I then send the same ChatObject from the ChatActivity to a GroupSettingsActivity, which also works fine.
My issue is when I try to return from the GroupSettingsActivity to the ChatActivity from my topAppBar home button, I get a nullPointerException trying to getChatId from the ChatObject.
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.shotgunnot/com.example.shotgunnot.ChatActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.shotgunnot.Chat.ChatObject.getChatId()' on a null object reference
I've tried using onResume, and Navutils but I keep getting the same error, I think it's something in the life cycle im not getting.
Androids built in back nav button works as expected.
Here's my MainActivity recyclerview adapter
#Override
public void onBindViewHolder(#NonNull final ChatListViewHolder holder, final int position) {
ChatObject data = chatList.get(position);
holder.mTitle.setText(data.getChatId());
holder.mGroup.setText(data.getGroupId());
System.out.println("GroupPic" + data.getGroupPic());
Glide.with(context)
.load(data.getGroupPic())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(R.drawable.ic_group_24dp)
.apply(RequestOptions.circleCropTransform().circleCrop())
.into(holder.mGroupPic);
holder.mLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), ChatActivity.class);
intent.putExtra("chatObject", chatList.get(holder.getBindingAdapterPosition()));
v.getContext().startActivity(intent);
}
});
}
This is the chatActivity
public class ChatActivity extends AppCompatActivity {
ChatObject mChatObject;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
Intent intent = getIntent(); >>
mChatObject = (ChatObject) intent.getSerializableExtra("chatObject");
BottomAppBar bottomAppBar = findViewById(R.id.bottomAppBar);
bottomAppBar.replaceMenu(R.menu.group_menu);
bottomAppBar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.settings:
Intent intent = new Intent(ChatActivity.this, GroupSettingsActivity.class);
intent.putExtra("chatObject", mChatObject);
startActivity(intent);
return true;
case android.R.id.home:
Intent home = new Intent(getApplicationContext(), MainPageActivity.class);
startActivity(home);
}
return false;
}
});
}
#Override
protected void onResume() {
super.onResume();
Intent intent = getIntent();
mChatObject = (ChatObject) intent.getSerializableExtra("chatObject");
}
}
And finally the GroupSetting Activity
public class GroupSettingsActivity extends AppCompatActivity {
ChatObject mChatObject;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group_settings);
Intent intent = getIntent();
mChatObject = (ChatObject) intent.getSerializableExtra("chatObject");
chatId = mChatObject.getChatId();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, ChatActivity.class);
intent.putExtra("chatObject", mChatObject);
startActivity(intent);
//NavUtils.navigateUpFromSameTask(this);
finish();
default:
return super.onOptionsItemSelected(item);
}
}
Any help would be much appreciated.

You should check if the value that is arriving in the second activity is different from null before using it. Try to do something like this and put a breakpoint to debug what's coming up in your second activity:
1st Activity:
Intent i = new Intent(getApplicationContext(), NewActivity.class);
i.putExtra("user_id", "1234");
i.putExtra("user_name", "John Doe");
startActivity(i);
2nd Activity:
Bundle extras = getIntent().getExtras();
if (extras != null) {
Integer id= extras.getInt("user_id");
String username= extras.getString("user_name");
}

Try to add these flags before starting ChatActivity, to clear the stack and make sure you're creating a new ChatActivity rather then recreating an old one:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

I found a workaround using sharedPrefs based off this answer
How do you save/store objects in SharedPreferences on Android?
saving prefs
#Override
protected void onPause() {
super.onPause();
SharedPreferences.Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(mChatObject);
prefsEditor.putString("mChatObject", json);
prefsEditor.commit();
}
And retrieving them in onCreate
mChatObject = (ChatObject) intent.getSerializableExtra("chatObject");
if(mChatObject != null){
chatId = mChatObject.getChatId();
groupId = mChatObject.getGroupId();
groupPic = mChatObject.getGroupPic();
}else{
Gson gson = new Gson();
String json = mPrefs.getString("mChatObject", "");
mChatObject = (ChatObject) gson.fromJson(json, ChatObject.class);
chatId = mChatObject.getChatId();
groupId = mChatObject.getGroupId();
groupPic = mChatObject.getGroupPic();
}
It feels like a bit of hack though, so if anyone has a better solution that'd be great.
Thanks

Related

Is it possible to pass a value from Adapter to Activity?

I have Activity1, Activity1 Adapter and Activity2
I'm not able to pass value between an Adapter and Activity. When back button is pressed, I'm expecting a value to be coming from the Second Activity (Activity 2) to Activity1 Currently, it gives me null
Here are my code snippets.
Activity1 Adapter
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Activity origin = (Activity) context;
Intent intent = new Intent(context, PostActivity.class);
intent.putExtra("searchText", staggeredCustomCard.getSearchText());
origin.startActivityForResult(intent, 1);
}
});
Activity2
#Override
public void onBackPressed() {
super.onBackPressed();
Intent mIntent = new Intent();
mIntent.getStringExtra("searchText");
setResult(1, mIntent);
}
I'm expecting this searchText to be going to Activity1. Could anyone please guide me how to achieve this?
You are getting getStringExtra("searchText"); from a completely new intent, that's why it's returning null. You need to get search text from getIntent() like this:
#Override
public void onBackPressed() {
super.onBackPressed();
Intent mIntent = new Intent();
String search = getIntent().getStringExtra("searchText");
mIntent.putExtra("searchText", search);
setResult(1, mIntent);
}

Passing a string or a variable from a dialoguebox to an activity Android

I wan to implicitly pass two string or variable from a dialoguebox to be used by another activity and at the same time opening that activity.
dialoguebox
String city = addresses.get(0).getLocality();
String category = "Hazard";
AlertDialog.Builder prompt = new
AlertDialog.Builder(MapsActivity.this);
prompt.setCancelable(false)
.setPositiveButton("Mineralization", new
DialogInterface.OnClickListener() {
.setPositivetiveButton("Geohazard", new
DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
startActivity(new
Intent(getApplicationContext(),MapsActivity.class));
//i want to pass the String city and category here
}
}
)
AlertDialog alert = prompt.create();
alert.setTitle("Please select an option");
alert.show();
TextView myTextView = (TextView) findViewById(R.id.PSString);
myTextView.setText(city);
New activity
package com.example.boneyflesh.homepage;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class GeohazardResults extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_geohazard_results);
}
}
how do i do this? what do i write on the onClickListener and what do i do on the new activity so that i can get the strings?
Instead of doing something like this in your onClick method
startActivity(new Intent(getApplicationContext(),MapsActivity.class));
You can just pass the two strings through the intent to the MapsActivity inside your onClick method as shown below
Intent lIntent = new Intent(getApplicationContext(), MapsActivity.class);
lIntent.putExtra("city", city);
lIntent.putExtra("category", category);
startActivity(lIntent);
and retrieve those values in MapsActivity as shown below
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_geohazard_results);
String city = getIntent().getStringExtra("city");
String category = getIntent().getStringExtra("category");
}
Pass Using Intent and Bundle like Below:
Intent intent = new Intent(getApplicationContext(),MapsActivity.class));
Bundle bundle =new Bundle();
bundle.putString("key1","value1");
bundle.putString("key2","value2");
intent.putExtras(bundle);
startActivity(intent );
And Retrieve value in next Activity like below:
Bundle bundle = getIntent().getExtras();
String value1= bundle.getString("key1");
String value2= bundle.getString("key2");
You need to use extras to send the data.
For example:
Intent intent = new Intent(getApplicationContext(),MapsActivity.class);
intent.putExtra("SOME_NAME_HERE", theString);
startActivity(intent);
Then, in the target activity you write - in onCreate:
Bundle extras = getIntent().getExtras();
if(extras == null) {
theString= null;
} else {
theString = extras.getString("SOME_NAME_HERE");
}
In your dialogbox:
Intent i = new Intent(MapsActivity.this, GeohazardResults.class);
i.putExtra("city", city);
i.putExtra("category", categoty);
startActivity(i);
In your new activity:
Intent i = getIntent();
Bundle extras = i.getExtras();
String city = extras.getString("city");
String category = extras.getString("category");
Instead of doing this -:
startActivity(new Intent(getApplicationContext(),MapsActivity.class));
Do something like this -:
Intent mapsActivityIntent = new Intent(getApplicationContext(), MapsActivity.class);
mapsActivityIntent.putExtra("CITY", city);
mapsActivityIntent.putExtra("CATEGORY", category);
startActivity(mapsActivityIntent);
In your activity you can then get them by doing :
getIntent().getStringExtra("CITY");
getIntent().getStringExtra("CATEGORY");
DialogInterface.OnClickListener() {
.setPositivetiveButton("Geohazard", new
DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
Intent intent = new Intent(getApplicationContext(),MapsActivity.class))
// intent.putExtra(key,value);
intent.putExtra("String1","value1");
intent.putExtra("String2","value2");
startActitvity(intent);
}
}
)
in Acivity
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if(extras != null){
//intent.getStringExtra(key)
string1 = intent.getStringExtra("String1");
string2 = intent.getStringExtra("String2");
}
i would suggest define keys as constants and use those while passing values, to avoid any confusion
pass intent from your dialog like this
Intent intent=new Intent(context, GeohazardResults.class);
Bundle parameters=new Bundle();
parameters.putString("city",city);
parameters.putString("category",category);
intent.putExtra("key",parameters);
startActivity(intent);
and in the next activity receive thiese values like this.
Intent receivedIntent=getIntent();
if(receivedIntent!=null){
Bundle parameters=receivedIntent.getBundleExtra("key");
if(parameters!=null){
String city=parameters.getString("city");
String category=parameters.getString("category");
}
}

How intent object keep/transfer data between two Activity in android?

i have these two Activity and each in the separate file:
public class MainActivity extends AppCompatActivity {
public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
}
public class DisplayMessageActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
ViewGroup layout = (ViewGroup) findViewById(R.id.activity_display_message);
layout.addView(textView);
}
}
in MainActivity we create Intent object and hold him some data ,
in the DisplayMessageActivity we get this intent using getIntent() method ,
and this method return to us Intent object
my question is how this method return to us the same Intent that we create in MainActivity ??
According to official documentation, get intent is used to
Return the intent that started this activity.
It means it is a function that returns the intent that originally started that activity.
That answers your query.
Android Developers Documentation - Activity - getIntent()
It is always a good practice to read official documentation.
The general syntax to add extras is:
Intent intent = new Intent(context, activity.class); //Create intent to start activity
intent.putExtra("key", data); //adding data
startActivity(intent);
To receive that data, from the Activity you started:
Intent intent = getIntent();
String data = intent.getExtra("key");
The String variable - data will hold the value that you attached with the previous activity. This means, you can only use this method till the next activity.
You have to implement onActivityResult in you MainActivity and start DisplayMessageActivity with startActivityForResult:
... sendMessage(View view) {
...
startActivityForResult(intent, MESSAGE_RESULT_CODE);
}
public void onActivityResult(int requestcode, int resultcode, Intent data) {
//You can get your result intent data here
if (requestcode == MESSAGE_RESULT_CODE && resultcode == RESULT_OK) {
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
}
}
and just add in DisplayMessageActivity in onPause, onStop or onBackPressed and onSupportNavigateUp:
//in your case maybe 'your_intent_sent_back_to_mainactivity = getIntent();'
setResult(RESULT_OK, your_intent_sent_back_to_mainactivity);
ADDITIONALLY
The source in Android Developer Community:
https://developer.android.com/training/basics/intents/result.html

How to call one activity multiple times based on from which the activity has been called?

I have one activity which is common for all other activities. I want to call this activity and want to set some conditions based on from which activity it has been called. I thought of bundle for this. How can I call a condition based on bundle value? I have another activity in between. I am not calling the activity directly. So how can we pass data by using bundle?
txt_from.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
i = new Intent(getApplicationContext(), PickLocationActivity.class);
GoSendData.instance.addressType = 0;
i.putExtra("type",1);
startActivity(i);
}
});
From this I am calling second activity.
In common activity I have a view I am calling the activity back from this. The activity from which it has been called , it should be called back from this view.
useLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bundle extras = intent.getExtras();
activityType = extras.getInt("type");
if(activityType==0) {
intent = new Intent(ChooseFromMapActivity.this, GoSend.class);
startActivity(intent);
}
if(activityType == 1)
{
intent = new Intent(ChooseFromMapActivity.this, GoRideActivity.class);
startActivity(intent);
}
}
});
How to achieve this...?
How can I do this with shared preferences?
Change
Bundle extras = intent.getExtras();
to
Bundle extras = getIntent().getExtras();
Hope this helps :)
Check the below code
Activity_1. : This will send the data to the Common Activity.
Intent i = new Intent(Activity_1.this, CommonActivity.class);
i.putExtra("type",1);
startActivity(i);
Activity_2. : This will send the data to the Common Activity.
Intent i = new Intent(Activity_2.this, CommonActivity.class);
i.putExtra("type",2);
startActivity(i);
Then on your Common Activity write this code in the onCreate function.
int receivedValue = getIntent().getIntExtra("type", 0);
// here 0 is the default value when there is no data in the particular key.
now you can check the condition like this
if(receivedValue==1)
{
// do something here
}
if(receivedValue==2)
{
// do something here
}
This will definitely work for you. Try it..!!
Happy coding.
Activity1,
txt_from.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
i = new Intent(getApplicationContext(), PickLocationActivity.class);
GoSendData.instance.addressType = 0;
i.putExtra("type",1);
startActivity(i);
}
});
Activity2,
txt_from.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
i = new Intent(getApplicationContext(), PickLocationActivity.class);
GoSendData.instance.addressType = 0;
i.putExtra("type",2);
startActivity(i);
}
});
Common Activity
useLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = getIntent();
int type = i.getInt("type");
if(type==1) {
Intent intent = new Intent(ChooseFromMapActivity.this, Activity1.class);
startActivity(intent);
}
if(type == 2)
{
Intent intent = new Intent(ChooseFromMapActivity.this, Activity2.class);
startActivity(intent);
}
}
});

Intent putExtra persists

i'm having an issue with Intents and putExtra.
What i want to do is this :
In Activity A(it's not my MainActivity),when i click a button,it will close all my activities, send a string and launch my main activity.For testing purposes it will show a test dialog with my string.All good till now,works as i need it to.
The problem is that if i restart my MainActivity(and i need to do that,it's something like a shopping list,i need to start a new shopping list) the dialog with the putExtra string shows again.
Here are my code snippets :
In Activity A :
#Override
public void onClick(View v) {
Intent intent = new Intent(Gestionarez.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_NO_ANIMATION);
intent.putExtra( "paramName", str );
startActivity( intent );
// TODO Auto-generated method stub
dialog.dismiss();
dialog.cancel();
}
In my MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LoadPref();
Bundle extras = getIntent().getExtras();
if (extras != null) {
String myParam = extras.getString("paramName");
ShowAlertMessage(this, "TEST", myParam + "");
} else {
}
}
And this is how i restart my MainActivity when i need to start a new shopping list :
Intent intent = getIntent();
finish();
startActivity(intent);
replace
Intent intent = getIntent();
finish();
startActivity(intent);
with
Intent intent = new Intent(this, ActivityB.class);
finish();
startActivity(intent);

Categories