This question already has answers here:
How to pass an object from one activity to another on Android
(35 answers)
Closed 9 years ago.
I am badly stuck to pass object from one activity to another activity using Parcelable but I am getting null pointer exception at line Log.i("Name",""+rcp.getName());, you can check this line in below code. Plz do check code CookingDataModel class at the end.
Here is the code of object Receiving Activity
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);// No title to display
setContentView(R.layout.recipe_ingredient_detail);
CookingDataModel cook = new CookingDataModel();
RecipeDataModel rcp;
ArrayList<IngredientDataModel> ing;
Bundle bundle = this.getIntent().getExtras();
if(bundle!=null)
cook = bundle.getParcelable("Cooking");
rcp = cook.getRecipe();
ing = cook.getIngredientList();
Log.i("Name",""+rcp.getName());
Log.i("Decrp",""+rcp.getDescription());
Log.i("Duration",""+rcp.getPrepTime());
Log.i("Instructions",""+rcp.getInstructions());
for(int k = 0; k < ing.size(); k++)
{
Log.i("Item Name",""+ing.get(k).getItemName());
Log.i("Item Amount",""+ing.get(k).getItemAmount());
}
}
Here is the code where I am sending object of CookingDataModel .
ListView recepeListView = getListView();
recepeListView.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> arg0, View arg1, int position,long arg3)
{
CookingDataModel cook = recpeList.get(position);
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putParcelable("Cooking",cook);
intent.putExtras(bundle);
intent.setClass(RecipeList.this,RecipeIngredientDetail.class);
startActivity(intent);
}
});
Here is code of the CookingDataModel class.
public class CookingDataModel implements Parcelable{
private RecipeDataModel recipe = null;
private ArrayList<IngredientDataModel> ingredientList = null;
public RecipeDataModel getRecipe() {
return recipe;
}
public void setRecipe(RecipeDataModel recipe) {
this.recipe = recipe;
}
public ArrayList<IngredientDataModel> getIngredientList() {
return ingredientList;
}
public void setIngredientList(ArrayList<IngredientDataModel> ingredientList) {
this.ingredientList = ingredientList;
}
public static final Parcelable.Creator<CookingDataModel> CREATOR = new Parcelable.Creator<CookingDataModel>()
{
public CookingDataModel createFromParcel(Parcel in)
{
return new CookingDataModel(in);
}
public CookingDataModel[] newArray(int size)
{
return new CookingDataModel[size];
}
};
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel arg0, int arg1) {
// TODO Auto-generated method stub
}
public CookingDataModel(Parcel in) {
// TODO Auto-generated constructor stub
}
public CookingDataModel()
{
}
}
Please help me in this respect that I could proceed my project. Thanks in adavance.
On the main activity:
intent.putExtra("Cooking",cook);
Then on second activity:
getIntent().getExtras().getParcelable("Cooking");
Try this. Do not use bundle if you've just to send a single object.
You may need to cast the getIntent().... part, I'm not sure.
Few things that need change.
No need of creating a new object, it will be overwritten.
CookingDataModel cook = new CookingDataModel();
Typecast when you get the Parcelable object from intent extras,
cook = bundle.getParcelable("Cooking");
Make Sure when you sending the object, it has valid receipe member. If you notice, you are able to get the CookingDataModel from the intent, and also the Receipe from this object but not able to get data from ReceipeModel.
From the code in the sending activity, I cant really say if the CookingDataModel.Receipe is a valid object.
Related
I made simple Client server to android.
I have problem when I send an object from server to the client.
The object is received ok and when I check the log, it shows me the the object was sent successfully.
The problem occurs when I'm trying to get this object and put it in my ListView adapter.
The adapter works, I checked it with a random ArrayList I created.
My issue is when I'm trying to to put the values of AsyncTask in my adapter.
public class RestaurantListFragment extends Fragment {
private ArrayList<Resturant> res = new ArrayList<>();
private ListAdapter adapter;
private Firebase restRef = new Firebase("https://restmeup.firebaseio.com/restaurants");
private Client mClient;
// private connectTask t = (connectTask)new connectTask().execute();
public RestaurantListFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new connectTask().execute();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// new connectTask(getView()).execute();
final View rootView = inflater.inflate(R.layout.fragment_two, container, false);
ListView restaurantList = (ListView) rootView.findViewById(R.id.list);
adapter = new ListAdapter(getContext(), res, getActivity());
restaurantList.setAdapter(adapter);
// connectTask t = (connectTask)new connectTask().execute();
if (mClient != null) {
mClient.sendMessage("bar");
}
SqlQueriesConverter sql = new SqlQueriesConverter();
sql.getResurantsListQuery("bar");
// sql.getUserFavoritesResturants(accessToken.getUserId());
mClient.sendMessage(sql.getQuery());
// t.setArray(res);
mClient.sendMessage("/quit");
mClient.stopClient();
final EditText searchText = (EditText)rootView.findViewById(R.id.searchListView);
searchText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
System.out.println("Before---------");
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String text = searchText.getText().toString().toLowerCase(Locale.getDefault());
adapter.filter(text);
adapter.notifyDataSetChanged();
System.out.println("array: " + res.toString());
}
#Override
public void afterTextChanged(Editable s) {
System.out.println("After---------");
}
});
// Inflate the layout for this fragment
return rootView;
}
public class connectTask extends AsyncTask<ArrayList<?>,ArrayList<?>,Client> {
// private Client mClient;
private ArrayList<?> arrayList = new ArrayList<>();
#Override
protected Client doInBackground(ArrayList<?>... message) {
//we create a Client object and
mClient = new Client(new Client.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(ArrayList<?> message) {
//this method calls the onProgressUpdate
// publishProgress(message);
onProgressUpdate(message);
}
});
mClient.run();
return null;
}
// #Override
protected void onProgressUpdate(ArrayList<?>... values) {
super.onProgressUpdate(values);
ArrayList<?> arr2;
if (values[0].get(0) instanceof Resturant){
Log.d("step 1", "1");
if (((ArrayList<?>)values[0]).get(0)instanceof Resturant) {
// arr2 = (ArrayList<Resturant>) values[0];
res = (ArrayList<Resturant>) values[0];
adapter.notifyDataSetChanged();
Log.d("array",res.toString());
}
}
if (values[0].get(0)instanceof Review){
arr2 = (ArrayList<Review>) values[0];
}
if (values[0].get(0)instanceof UserFavorites){
arr2 = (ArrayList<Review>) values[0];
Log.d("step 2", "2");
}
}
}
}
There are two things you need to change to use the AsyncTask as you intend. The first change you need is to return the ArrayList you get from your mClient in the doInBackground method. This is a bit troublesome because it looks like the Client is already running asynchronously since you pass a callback to get the result (this is the Client.OnMessageReceived anonymous class you have there). The second change would be to implement onPostExecute on your AsyncTask since that is where the results from doInBackground are sent. You'd add the result sent from doInBackground to your adapter in there.
In any case, since it looks like Client is already performing the work asynchronously, you shouldn't need to use an AsyncTask at all. Just implement the logic to add the results to your adapter in the Client.OnMessageReceived callback.
Just get the code you already have in onProgressUpdate and throw it inside messageReceived. Something like this:
mClient = new Client(new Client.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(ArrayList<?> values) {
if (values[0].get(0) instanceof Resturant){
Log.d("step 1", "1");
if (((ArrayList<?>)values[0]).get(0)instanceof Resturant) {
res = (ArrayList<Resturant>) values[0];
adapter.notifyDataSetChanged();
Log.d("array",res.toString());
}
}
}
});
Hi I have a Requirement like Person Details for that i have multiple details like personal,educational,job like In first activity am enter personal details and then educational and then job like that one after another for that how can i maintain all details in single object and pass through app please help me.
Be aware that you need to bundle an object in an Intent, that object must implement the Parcelable interface. Here's a common implementation taken from the Parcelable documentation...
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
Once you've done that, simply pass the object around in an Intent...
Intent i = new Intent(getApplicationContext(), ACTIVITY_TO_START.class);
i.putExtra("extra_key", new MyParcelable());
startActivity(i);
to retrieve the object for the starting activity...
Bundle extras = getIntent().getExtras();
if(extras != null && extras.containsKey("extra_key"))
{
MyParcelable p = (MyParecelable)extras.getParcelable("extra_key");
}
Simple solution: Use intents for this
Personal.class
public class Personal extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.personal);
Intent i = new Intent(getApplicationContext(), Educational.class);
i.putExtra("personal_details",<-get data from object->);
startActivity(i);
}
}
Educational.class
public class Personal extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.personal);
String personal_details;
Bundle extras = getIntent().getExtras();
if (extras != null) {
personal_details= extras.getString("personal_details");
}
Intent i = new Intent(getApplicationContext(), educational.class);
i.putExtra("personal_details",personal_details);
i.putExtra("educational_details",<-get data from object->);
startActivity(i);
}
}
Job.class
public class Personal extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.personal);
String personal_details,educational_details;
Bundle extras = getIntent().getExtras();
if (extras != null) {
personal_details= extras.getString("personal_details");
educational_details= extras.getString("educational_details");
}
Intent i = new Intent(getApplicationContext(), FinalResult.class);
i.putExtra("personal_details",personal_details);
i.putExtra("educational_details",educational_details);
i.putExtra("job_details",<-get data from object->);
startActivity(i);
}
}
FinalResult.class
public class Personal extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.personal);
String personal_details,educational_details,job_details;
Bundle extras = getIntent().getExtras();
if (extras != null) {
personal_details= extras.getString("personal_details");
educational_details= extras.getString("educational_details");
job_details= extras.getString("job_details");
}
}
}
{EDIT-1}
have a look at one of my answers in different storage options in
android - Click Here
You can achieve it using application variable or shared
preferences but i would not recommend it. !
Try storing it in POJO(Plain old Java class)
{EDIT-2}
Hmm if i understand correctly your question:: You are connected to internet(Wifi,Wired,... etc) basically you are trying to show a dialog when there is no network connectivity ! .... You can take the help of Broadcast receivers ...
Try this:: Set the broadcast receiver to fire the intent when there is no net connectivity ....
Write the code to catch that intent and pop the dialog .... In this dialog give the user option to reconnect the connectivity !
I have a class that implements the Parcelable class. From main activity, I pass an parcelable object. At the second activity I retrieve the objet and use the objet to change data. All is ok. But the problem is when I need to retrieve this changes from second activity to the main activity. I don't know how could I do it.
Here the call in the main activity:
public class MainActivity extends Activity {
Tgestion Tges= new Tgestion();
Button buttonI,buttonM,buttonB,buttonD,buttonS;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addListenerOnButton();
}
public void addListenerOnButton() {
final Context context = this;
buttonI = (Button) findViewById(R.id.buttonIntroducir);
buttonI.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent(context, IntroducirPatron.class);
intent.putExtra("com.example.sistemacontrasena.gestion", Tges);
startActivity(intent);
}
});
}
}
Tges is an objet that implements the parcelable class.
In the second activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_introducir_patron);
// --- Obtenemos objeto Parcelable desde el Intent
this.gestion=getIntent().getParcelableExtra("com.example.sistemacontrasena.gestion");
}
After this I set some changes for example this.gestion.setSecret(value);
When I close this second activity, in the main activity I don't know how can I retrieve this.gestion.getSecret() with the value that I put, for example. How can I do that?
The class parcelable is:
import android.os.Parcel;
import android.os.Parcelable;
public class Tgestion implements Parcelable{
private String[] secret;
public Tgestion(){
this.secret=new String[2];
}
/**
* Constructor Tgestion para parcel.
* #param source
*/
private Tgestion(Parcel source) {
this.secret=new String[2];
readFromParcel(source);
}
public void setSecret(String[] s){
for (int i=0;i<this.secret.length;i++){
this.secret[i]=s[i];
}
}
public String[] getSecret(){
return this.secret;
}
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel destino, int flags) {
// TODO Auto-generated method stub
destino.writeStringArray(this.secret);
}
private void readFromParcel(Parcel in){
in.readStringArray(this.secret);
}
public static final Parcelable.Creator<Tgestion> CREATOR = new Parcelable.Creator<Tgestion>() {
#Override
public Tgestion createFromParcel(Parcel source) {
return new Tgestion(source);
}
#Override
public Tgestion[] newArray(int size) {
return new Tgestion[size];
}
};
}
You cannot just change the Parcelable and expect the first activity to see these changes. Parcelables are serialized and deserialized, which means that you have a new copy.
You should use startActivityForResult(), setResult() (in the second activity) and onActivityResult() (in the first one) to return data.
See Getting a Result from an Activity in the docs.
I'm trying to pass an array of custom objects to an activity. I've implemented parcelable as such:
public class WidgetState {
static class Light implements Parcelable
{
int id;
String text;
int offColor,onColor;
boolean on=false;
boolean isRows;
int size;
public static final Parcelable.Creator<Light> CREATOR = new Parcelable.Creator<Light>() {
public Light createFromParcel(Parcel in) {
return new Light(in);
}
public Light[] newArray(int size) {
return new Light[size];
}
};
#Override
public int describeContents() {
return 0;
}
public Light(Parcel src)
{
id = src.readInt();
text = src.readString();
offColor = src.readInt();
onColor = src.readInt();
on = src.readInt()==1;
isRows = src.readInt()==1;
size = src.readInt();
}
public Light() { }
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(text);
dest.writeInt(offColor);
dest.writeInt(onColor);
dest.writeInt(on?1:0);
dest.writeInt(isRows?1:0);
dest.writeInt(size);
}
}
}
I can put a single object in the bundle in the launching activity and retrieve it via
bundle.putParcelable(new WidgetState.Light(),"light");
and retrieve it in the resulting activity via
WidgetState.Light light = (WidgetState.Light)getIntent().getExtras().getParcelable("light")
but when packing and array like this
bundle.putParcelableArray(new WidgetState.Light[4],"lights");
I can do this just fine on the first activity
WidgetState.Light[] lights = (WidgetState.Light[])bundle.getParcelableArray("lights");
intent.putExtras(bundle);
startActivityForResult(intent,1);
but in the second activity i get a RuntimeException when I call
WidgetState.Light [] lights = (WidgetState.Light []) state.getParcelableArray("lights");
Here's all the code in the first activity
Intent intent = new Intent(MainActivity.this,GuiActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelable("light", new WidgetState.Light());
bundle.putParcelableArray("lights", new WidgetState.Light[4]);
WidgetState.Light[]lights = (WidgetState.Light[])bundle.getParcelableArray("lights");
intent.putExtras(bundle);
startActivityForResult(intent,1);
And the second
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gui);
Bundle state = (savedInstanceState!=null)?savedInstanceState:getIntent().getExtras();
try {
WidgetState.Light light = (WidgetState.Light) state.getParcelable("light");
// Throws RuntimeException on next line
WidgetState.Light [] lights = (WidgetState.Light []) state.getParcelableArray("lights");
Toast.makeText(this, "Good bundle", Toast.LENGTH_SHORT).show();
}
catch ( RuntimeException e)
{
Toast.makeText(this, "Failed to read bundle", Toast.LENGTH_SHORT).show();
}
}
What am I missing?
I have an activity where I am adding objects into an ArrayList which implements the Parcelable interface. I then pass this list to another activity via a bundle however I get the following error when I try to print the size of the list in the new activity:
java.lang.RuntimeException: Unable to resume activity {com.example.test/com.example.test.SectionsActivity}: java.lang.NullPointerException
Here is the first activity where I add to list:
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Toast.makeText(getApplicationContext(), l.getItemAtPosition(position).toString() + " added to order", Toast.LENGTH_SHORT).show();
// add clicked item to orderData....
MenuItem m = (MenuItem) l.getItemAtPosition(position);
// create new item
orderData.add(m);
subTotal += m.getPrice();
calc();
}
This is first activity where I send the data via intent:
confirmBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
b.putParcelable("order", orderData);
Intent i = new Intent(v.getContext(), SectionsActivity.class);
i.putExtra("data",b);
startActivity(i);
}
});
and this is second activity where I try to retrieve the bundle and display size:
#Override
protected void onResume() {
super.onResume();
getIntentData();
}
public void getIntentData(){
Intent i = getIntent();
if(i != null & i.hasExtra("data")){
Toast.makeText(this.getApplicationContext(), "recieved", Toast.LENGTH_LONG).show();
b = i.getExtras();
orderData = b.getParcelable("order");
int size = orderData.size();
Toast.makeText(this.getApplicationContext(), String.valueOf(size), Toast.LENGTH_LONG).show();
}
}
Any ideas why I am getting the null pointer?? It's driving me mad!
orderData is a MenuItemList object:
public class MenuItemList extends ArrayList <MenuItem> implements Parcelable{
/**
*
*/
private static final long serialVersionUID = 2998684930374219271L;
public MenuItemList(){
}
public static final Parcelable.Creator<MenuItemList> CREATOR = new Parcelable.Creator<MenuItemList>() {
#Override
public MenuItemList createFromParcel(Parcel source) {
return new MenuItemList(source);
}
#Override
public MenuItemList[] newArray(int size) {
return new MenuItemList[size];
}
};
public MenuItemList(Parcel source) {
readFromParcel(source);
}
private void readFromParcel(Parcel source) {
this.clear();
//read the size of the list
int size = source.readInt();
//Remember order of items written into the Parcel. Important here.
for(int i = 0; i < size; i ++){
MenuItem item = new MenuItem();
item.setName(source.readString());
item.setPrice(source.readDouble());
this.add(item);
}
}
#Override
public void writeToParcel(Parcel dest, int flags) {
int size = this.size();
dest.writeInt(size);
for(int i = 0; i < size; i ++){
MenuItem item = this.get(i);
dest.writeString(item.getName());
dest.writeDouble(item.getPrice());
}
}
#Override
public int describeContents() {
return 0;
}
}
CHANGES TO CODE THAT SOLVED PROBLEM:
CHANGED onClick(View v):
#Override
public void onClick(View v) {
Intent i = new Intent(v.getContext(), SectionsActivity.class);
i.putExtra("data", (ArrayList<MenuItem>)orderData);
startActivity(i);
}
CHANGED getIntent():
public void getIntentData(){
Intent i = getIntent();
if(i != null && i.hasExtra("data")){
Toast.makeText(this.getApplicationContext(), "recieved", Toast.LENGTH_LONG).show();
orderData = i.getParcelableExtra("data");
int size = orderData.size();
Toast.makeText(this.getApplicationContext(), String.valueOf(size), Toast.LENGTH_LONG).show();
}
}
Rewrite
The problem is that you have an extra Bundle. Currently in getIntentData() you have to call:
getIntent() // Fetch the Intent,
.getExtras() // Fetch the Bundle of extras,
.getBundle("data") // Fetch the Bundle "data",
.getParcelable("order"); // Then get your parcelable...
Let's cut out the unnecessary Bundle.
public void onClick(View v) {
Intent i = new Intent(v.getContext(), SectionsActivity.class);
i.putExtra("data", orderData);
startActivity(i);
}
Now update getIntentData():
Intent i = getIntent();
if(i != null && i.hasExtra("data")){
orderData = i.getParcelableExtra("data");
...
}
Unless I missed something, you are using the bitwise & instead of the logical && in your getIntentData() function