pass Object to another activity - java

I have found this way to do this
Student student = new Student (18,"Z r");
Intent i = new Intent(this, B.class);
i.putExtra("studentObject", student);
startActivity(i);
The problem is that if the object changed in the first activity No change took place in the another activity.
I thought how to make it like a constructor that no copy of the object is pass but the object it self.
Thanks

How about if you configure the "object" as a singleton of the entire application? This way, everybody (your app) sees the changes... See some insights here: http://developer.android.com/guide/faq/framework.html#3
For example, in some other file (Student.java):
public class Student {
public String Name;
}
Create a custom application class:
public MyApp extends Application {
private Student obj = new Student();
public Student getMyObject() {
return obj;
}
}
Anywhere in your application (e.g. SomeActivity.java):
Student appStudent = ((MyApp) getActivity().getApplicationContext()).getMyObject();
appStudent.Name = "New Name"; // "global" update

You could also look into a BroadcastReceiver. With a BroadcastReceiver you can send a message from one Activity to another and with an interface you can pass the object from one Activity to the other.
I think this is a great example, where a BroadcastReceiver is created to check the internet connection of the device. But you can easily convert this in a BroadcastReceiver with your own custom action to send the object.

Implement parcelable in your student class and you can copy the student into the intent.
How can I make my custom objects Parcelable?
Code works with parcelable classes
> Student student = new Student (18,"Zar E Ahmer"); Intent i = new
> Intent(this, B.class); i.putExtra("studentObject", student);
> startActivity(i);
Below is an example of bean class I use that implements parcelable. Here you would replace KmlMarkerOptions with Student
#SuppressLint("ParcelCreator")
public class KmlMarkerOptions implements Parcelable {
public MarkerOptions markeroptions = new MarkerOptions();
public String href = "";
public int hrefhash =-1;
public String id = "";
public long imageId = -1;
public int locationId = -1;
public int markerSize = -1;
public KmlMarkerOptions(){
}
public KmlMarkerOptions(Parcel in) {
this.markeroptions = in.readParcelable(null);
this.href = in.readString();
this.hrefhash = in.readInt();
this.id = in.readString();
this.imageId = in.readLong();
this.locationId = in.readInt();
this.markerSize = in.readInt();
}
#SuppressWarnings("rawtypes")
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public KmlSummary createFromParcel(Parcel in) {
return new KmlSummary(in);
}
public KmlSummary[] newArray(int size) {
return new KmlSummary[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(markeroptions, 0);
dest.writeString(href);
dest.writeInt(hrefhash);
dest.writeString(id);
dest.writeLong(imageId);
dest.writeInt(locationId);
dest.writeInt(markerSize);
}
}

Related

Modify variables in an instance from another class Android

I simplified this for brevity; hopefully this example isn't actually functional. I'm creating and doing things with a variable, then I'm having another class do some stuff, then that class refers back to the original and tells it to do more stuff with that variable.
I've done exactly this with views. I simply pass the activity and then when I need to use it I use activity.findViewById(id) to do stuff. With variables, you can't just do activity.variable. I tried using a getter (as shown in this example), but maybe I'm still just doing it wrong or it can't be done how I'd like:
public class MyActivity {
private int test;
public void onCreate(Bundle savedInstanceState) {
test = 5;
int data = 100;
//Pass something to it
new NotAnActivity().func(MyActivity.this,data);
}
public int gettest() {
return test;
}
public void func(Activity instance, int response) {
int test = new MyActivity().gettest();
//Do stuff with test
}
}
public class NotAnActivity {
public void func(Activity instance, int data) {
//Do stuff with data
int response = 20;
//Try to pass information back
new MyActivity().func(instance,response);
}
}
You can't use a activity.gettest() because you're passing the superclass Activity between classes. To have access to the gettest() method you need to pass the specific child activity (MyActivity extends Activity, pass MyActivity instead of Activity) or you can cast to your specific activity.
((MyActivity)activity).getter();
So here, instead of:
public void func(Activity instance, int data) {
//Do stuff with data
int test = ((MyActivity)instance).gettest();
}
or
public void func(MyActivity instance, int data) {
//Do stuff with data
int test = instance.gettest();
}
It's not a good idea to instantiate your activities yourself new A()
public class MainActivity extends AppCompatActivity {
private int test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
test = 5;
int data = 100;
new NotAnActivity().func(this,data);
}
public int gettest() {
return test;
}
public void func(MainActivity instance, int response) {
//int test = new MainActivity().gettest();
int test = instance.gettest();
Log.v("variable", "test = " + test);
}
}
class NotAnActivity {
public void func(MainActivity instance, int data) {
//Do stuff with data
int response = 20;
//Try to pass information back
instance.func(instance,response);
}
}
You can try it. Your mistake is [new MyActivity()]

Android. Passing this custom object to next Activity?

I have this custom object which I want to pass to a different Activity:
public class FindRouteOutputForDisplay {
public ArrayList<VertexDisplay> vertexDisplayArrayList;
public ArrayList<Integer> integerArrayList;
}
I tried this, but doesn't work.
Intent newIntent = new Intent(FirstActivity.this, SecondActivity.class);
FindRouteOutputForDisplay data = getMyData();
newIntent.putExtra("data", data); // Error
startActivity(newIntent);
Should I pass
public ArrayList<VertexDisplay> vertexDisplayArrayList;
public ArrayList<Integer> integerArrayList;
separately one-by-one? Any way to pass all of them at once?
You can try this solution.
public class FindRouteOutputForDisplay implements Serializable{
public ArrayList<VertexDisplay> vertexDisplayArrayList;
public ArrayList<Integer> integerArrayList;
}
Intent newIntent = new Intent(FirstActivity.this, SecondActivity.class);
FindRouteOutputForDisplay data = getMyData();
newIntent.putSerializable("data", data);
startActivity(newIntent);
If you have any errors on "putSerializable" so you can cast your object to Serializable in this way.
newIntent.putSerializable("data", (Serializable)data);
And in your activity just get your data by this
FindRouteOutputForDisplay data = getIntent().getSerializable("data");
Hope it helps.
Save your data in your application context class. Since this class is available across your application instance, you can get or set the variables defined inside this class from all activities. More info here
Change this :
startActivity(routeDetailIntent);
To :
startActivity(newIntent);
You should make the custom objects implement the Parcelable interface:
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();
}
}
You can also have a look here if you want other solutions.
I have a trick for you. Add Gson to your dependencies.
repositories {
mavenCentral()
}
dependencies {
compile 'com.google.code.gson:gson:2.2.4'
}
Convert your object to Json and ship it as a String.
String data = new Gson().toJson(getMyData())
Convert it back from String in a new Activity
FindRouteOutputForDisplay data = new Gson(stringData, FindRouteOutputForDisplay.class).
You can make the class static and use it anywhere in your app.
you have passed wrong intent to start activity.
Intent newIntent = new Intent(FirstActivity.this, SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("value", data );
newIntent.putExtras(bundle);
startActivity(newIntent );
I also face this problem so I'm trying this below code:
Pass the object with intent
In starting activity we can set the parcelable object to an intent
User user = new User("1", "u", "u", "u");
ArrayList<User> userList = new ArrayList<User>();
Sensor sensor = new Sensor("1", "s", "s", true, user, userList);
intent.putExtra("com.score.senzors.pojos.Sensor", sensor);
In destination activity we can get the parcelable object from intent extras(bundle)
Bundle bundle = getIntent().getExtras();
Sensor sensor = bundle.getParcelable("com.score.senzors.pojos.Sensor")
Hope it Helps you

android how to get value from the interface

I am getting values in broadcast receiver in MyFragment class which extends the interface DelayTime as -
if(intent.getAction().equals(BroadcastHelper.DEPARTURE_TIME)){
Bundle args = intent.getExtras();
if (args != null) {
int departure_time = args.getInt("Departure");
DepartureTime(departure_time);
}
}
else if(intent.getAction().equals(BroadcastHelper.ARRIVAL_TIME)){
Bundle args = intent.getExtras();
if (args != null) {
int arrival_time = args.getInt("Arrival");
ArrivalTime(arrival_time);
}
}
#Override
public int ArrivalTime(int arrival_time){
//what to do here
Log.d("hi","arrival_time" + arrival_time);
return arrival_time;
}
#Override
public int DepartureTime(int departure_time){
//what to do here
return departure_time;
}
I have an interface DelayTime -
public interface DelayTime {
public int ArrivalTime(int arrival_time);
public int DepartureTime(int departure_time);
}
I need to get the values from MyFragment class in MyOwn Class using the interface. In MyOwn class, the implementation which I have done is like -
DelayTime delaytime = new MyFragment();
int arri = delaytime.ArrivalTime(arr);
Log.d("hi","arrival 0" + arri);
myAdapter.setArrTime(arri); //Null pointer here
The value of arri is 0. The logs are like -
arrival_time 4500
arrival_time 0
Your interface DelayTime should look like this, for standards:
public interface Delayer {
void setArrivalTime(int arrivalTime);
void setDepartureTime(int departureTime);
}
When instantiating your MyOwn class you should pass MyFragment in its constructor and save a reference to it.
MyOwn mClass = new MyOwn((DelayTime) mFragment);
In the MyOwn class the constructor should be something like:
public MyOwn(DelayTime fragmentInterface) {
this.fragmentInterface = fragmentInterface;
}
Have the MyOwn class consume the interface methods:
public void setArrivalTime(int arrivalTime) {
fragmentInterface.setArrivalTime(arrivalTime);
}
And use the interface with your MyOwn object like this:
mClass.setArrivalTime(yourValue);
Also note that fragments are used with the (support) fragment manager and not instantiated directly like that.
I suggest you have a read here: https://developer.android.com/guide/components/fragments.html

Sane way to go from ArrayList<Long> through an Intent

I'm currently writing an app that pulls an array of longs from a server via json, and then passes that list from one activity into another. The basic skeleton looks like this:
public void onResponse(Map result)
{
ArrayList handles= (ArrayList)result.get("fileHandles");
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("handles", handles);
}
So the first problem becomes evident, the only methods for putExtra are putIntegerArrayListExtra, putStringArrayListExtra, putCharSequenceArrayListExtra, and putParcelableArrayListExtra. Thinking Long would probably be parcelable, I was wrong it doesn't work (even if I use ArrayList<Long>). Next I thought I'd just pass a long [], however I see no straight-forward conversion to go from ArrayList<Long> to long [] that intent.putExtra will accept. This was the solution I finally ended up with:
ArrayList handles= (ArrayList)result.get("fileHandles");
long [] handleArray = new long[handles.size()];
for (int i = 0; i < handles.size(); i++)
{
handleArray[i] = Long.parseLong(handles.get(i).toString());
}
Obviously this seemed a little bit ridiculous to me, but every other conversion I tried seemed to complain for one reason or another. I've thought about re-thinking my serialization to have the problem taken care of before I get to this point, but I find it odd that passing ArrayList<Long> from activity to activity could be so difficult. Is there a more obvious solution I'm missing?
You can use it as a Serializable extra. ArrayList is Serializable and Long extends Number which also implements Serializable:
// Put as Serializable
i.putExtra("handles", handles);
// Unfortunately you'll get an unsafe cast warning here, but it's safe to use
ArrayList<Long> handles = (ArrayList<Long>) i.getSerializableExtra("handles");
Two options: Use Parcelable or Serializable
in:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("handles", new FileHandles(handles));
out:
FileHandles handles = intent.getParcelableExtra("handles");
object:
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
import java.util.List;
public class FileHandles implements Parcelable {
private final List<Long> fileHandles;
public FileHandles(List<Long> fileHandles) {
this.fileHandles = fileHandles;
}
public FileHandles(Parcel in) {
int size = in.readInt();
long[] parcelFileHandles = new long[size];
in.readLongArray(parcelFileHandles);
this.fileHandles = toObjects(size, parcelFileHandles);
}
private List<Long> toObjects(int size, long[] parcelFileHandles) {
List<Long> primitiveConv = new ArrayList<Long>();
for (int i = 0; i < size; i++) {
primitiveConv.add(parcelFileHandles[i]);
}
return primitiveConv;
}
public List<Long> asList() { // Prefer you didn't use this method & added domain login here, but stackoverflow can only teach so much..
return fileHandles;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(fileHandles.size());
dest.writeLongArray(toPrimitives(fileHandles));
}
private static long[] toPrimitives(List<Long> list) {
return toPrimitives(list.toArray(new Long[list.size()]));
}
public static long[] toPrimitives(Long... objects) {
long[] primitives = new long[objects.length];
for (int i = 0; i < objects.length; i++)
primitives[i] = objects[i];
return primitives;
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
#Override
public FileHandles createFromParcel(Parcel in) {
return new FileHandles(in);
}
#Override
public FileHandles[] newArray(int size) {
return new FileHandles[size];
}
};
}
Serializable (forced to use ArrayList which implements Serializable (List does not)
in:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("handles", new ArrayList<Long>());
out:
ArrayList handles = (ArrayList) intent.getSerializableExtra("handles");

Reading ArrayList in Parcelable

I have a class called SuperMedia that implements Parcelable. One of the fields of the class is an ArrayList children. When I create a Bundle and try to pass a "SuperMedia" object from one activity to another, all the fields get passed fine with the exception of the ArrayList "children" which just shows up as being empty every time.
In my first Activity I do:
Bundle a = new Bundle();
a.putParcelable("media",media); //media is an object of type "SuperMedia" and all the "children" have been initialized and added to the array
final Intent i = new Intent("com.tv.video.subcategories");
i.putExtra("subcategories", a);
On my Second Activity I do:
Intent i = getIntent();
Bundle secondBun = i.getBundleExtra("subcategories");
SuperMedia media = secondBun.getParcelable("media"); //For some reason the ArrayList"children" field shows up as empty.
Im not sure why this is happening. If anybody can guide me on the right path that would be greatly appreciated. Below is my SuperMedia class btw.
public class SuperMedia implements Parcelable{
public URI mthumb;
public String mTitle;
public ArrayList<SuperMedia> children = new ArrayList();
public SuperMedia(URI thumb, String title) {
this.mthumb = thumb;
this.mTitle = title;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
dest.writeString(mTitle);
dest.writeString(mthumb.toString());
dest.writeTypedList(children);
}
public static final Parcelable.Creator<SuperMedia> CREATOR = new Parcelable.Creator<SuperMedia>() {
public SuperMedia createFromParcel(Parcel in) {
return new SuperMedia(in);
}
public SuperMedia[] newArray(int size) {
return new SuperMedia[size];
}
};
private SuperMedia(Parcel in) {
mTitle = in.readString();
try {
mthumb = new URI(in.readString());
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
in.readTypedList(children, SuperMedia.CREATOR);
}
public SuperMedia(){
}
}
If you want simply pass object through intent then you can make SuperMedia Serializable no need to Parcelable.
public class SuperMedia implements Serializable{...}
put it as
Bundle a = new Bundle();
a.putSerializable("media",media);
and we get it as.
Intent i = getIntent();
Bundle secondBun = i.getBundleExtra("subcategories");
SuperMedia media = (SuperMedia)secondBun.getSerializable("media");
if you really needed Parcelable then may it help you.
Arraylist in parcelable object
Use Bundle's putParcellableArrayList for storing SuperMedia object
Bundle args = new Bundle();
args.putParcelableArrayList("media", "media");
and for restroring
getArguments().getParcelableArrayList("media");
This way will ensure bundle save your list objects as implemented in parcelable instance.
Also, be aware of using only ArrayList, other List subclasses not supported.

Categories