Get object from intent throws null - java

I am trying to pass an object to another class using intent. The object implements Parcelable.
The thing is, when I try to get the attributes it doesn't get the object, it says it's null.
But when I do a System.out.println of the intent.getExtras():
Bundle[{usuariocreado =com.example.frpi.repasando.Usuario#4ed1d39}]
It's actually there!
if (this.getIntent().getExtras() != null) {
Usuario usuariocreado = intent.getParcelableExtra("usuariocreado");
usuariocreado.getNombreUsuario();
} else {
System.out.println("Mierda");
}
This is the code on MainActivty which receives the intent.
NombreUsuario = (EditText) findViewById(R.id.UsuarioRegister);
PasswordPrimero = (EditText) findViewById(R.id.PasswordPrimero);
Usuario obj = new Usuario(String.valueOf(NombreUsuario.getText()), String.valueOf(PasswordPrimero.getText()));
Intent intent = new Intent(getBaseContext(), MainActivity.class);
Usuario usuariocreado = new Usuario(String.valueOf(NombreUsuario.getText()), String.valueOf(PasswordPrimero.getText()));
intent.putExtra("usuariocreado ", usuariocreado);
startActivity(intent);
This is the code on the SecondActivity which sends the intent.
What am i doing wrong??
Thanks!
public class Usuario implements Parcelable {
public Usuario(String nombreUsuario, String passwordPrimero) {
NombreUsuario = nombreUsuario;
PasswordPrimero = passwordPrimero;
}
/**
* NombreUsuario : Paco
* PasswordPrimero : Example
*/
private String NombreUsuario;
private String PasswordPrimero;
protected Usuario(Parcel in) {
NombreUsuario = in.readString();
PasswordPrimero = in.readString();
}
public static final Creator<Usuario> CREATOR = new Creator<Usuario>() {
#Override
public Usuario createFromParcel(Parcel in) {
return new Usuario(in);
}
#Override
public Usuario[] newArray(int size) {
return new Usuario[size];
}
};
public String getNombreUsuario() {
return NombreUsuario;
}
public void setNombreUsuario(String NombreUsuario) {
this.NombreUsuario = NombreUsuario;
}
public String getPasswordPrimero() {
return PasswordPrimero;
}
public void setPasswordPrimero(String PasswordPrimero) {
this.PasswordPrimero = PasswordPrimero;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(NombreUsuario);
dest.writeString(PasswordPrimero);
}
}

You have to cast the intent.getParcelableExtra("usuariocreado") with Usuario
Replace
Usuario usuariocreado = intent.getParcelableExtra("usuariocreado");
with
Usuario usuariocreado = ((Usuario) intent.getParcelableExtra("usuariocreado"));

Related

Parcelable object changes completely when sent as an Extra of an Intent

I'm trying to put a Parcelable object as an extra in an intent and pass it to the next Activity, and it doesn't crash but the object changes dramatically. I'm sending when clicking on an item from a RecyclerView in a Fragment and opening an Activity from it.
This is how I send it:
AdminProfile adminProfile = list.get(position).admin;
Intent intent = new Intent(view.getContext(),ClosedChatActivity.class);
intent.putExtra("chat",adminProfile);
view.getContext().startActivity(intent);
This how I get it:
adminProfile = (AdminProfile) getIntent().getExtras().getParcelable("chat");
And here the class:
public class AdminProfile implements Parcelable {
public static final Creator<AdminProfile> CREATOR = new Creator<AdminProfile>() {
#Override
public AdminProfile createFromParcel(Parcel in) {
return new AdminProfile(in);
}
#Override
public AdminProfile[] newArray(int size) {
return new AdminProfile[size];
}
};
public Long idUser;
public String name;
public String professio;
public String description;
public List<WebLink> webLinks;
public Long idOficina;
protected AdminProfile(Parcel in) {
if (in.readByte() == 0) {
idUser = null;
} else {
idUser = in.readLong();
}
name = in.readString();
professio = in.readString();
description = in.readString();
webLinks = in.createTypedArrayList(WebLink.CREATOR);
if (in.readByte() == 0) {
idOficina = null;
} else {
idOficina = in.readLong();
}
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeLong(idUser);
parcel.writeString(name);
parcel.writeString(professio);
parcel.writeString(description);
parcel.writeLong(idOficina);
parcel.writeList(webLinks);
}
}
I can't understand why, but when I send the object I have UserId=3, but when I get it it's userId=55834574848. Any ideas?
The Parcelable functions were filled automatically by Android Studio, and reading the first byte messed it up.
Changing
if (in.readByte() == 0) {
idUser = null;
} else {
idUser = in.readLong();
}
for
idUser = in.readLong();
fixed it.

Broadcasting a list using sendBroadcast()

I have a list which I am trying to broadcast with the use of intents. After following online tutorials, I was adviced to use Parcelable in order to send this data. However, I keep getting this error in logcat:
Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to android.os.Parcelable
from this line of code
bundle.putParcelable("data", (Parcelable)tweets);
I do not know how to correct this.
Where i am building the intent
protected void onHandleWork(#NonNull Intent intent) {
Log.d(TAG, "onHandleWork: ");
List<tweet> tweets = new ArrayList();
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer("HyjgZgfiqSODTdICZUXIHI8HK", "TlynMItosq99QxnLMLGxA6FElD3TAKx9UmBxva5oExg9Gz1mzV");
AccessToken accessToken = new AccessToken("2362719277-w5QlRNB2I7PXdMJuDXf5cc8FDT5H8X38ujxrtiT", "3v2Z2cqezaFrV6pFHu2yfPVFHZgMvLjMVKH4cUujI9kwI");
twitter.setOAuthAccessToken(accessToken);
Query query = new Query("Twitch");
try {
QueryResult result = twitter.search(query);
for (Status status : result.getTweets()) {
String createdat = status.getCreatedAt().toString();
String text = status.getText();
String retweets = String.valueOf(status.getRetweetCount());
String favs = String.valueOf(status.getFavoriteCount());
String uri = status.getUser().getProfileImageURL();
tweet onetweet = new tweet(createdat,text,retweets,favs,uri);
// Log.d(TAG, status.getText());
tweets.add(onetweet);
}
if (isStopped()) return;
} catch (TwitterException e) {
e.printStackTrace();
}
sendToUI(tweets);
}
private void sendToUI(List tweets) {
Intent intent = new Intent("tweet_result");
Bundle bundle = new Bundle();
bundle.putParcelable("data", tweets);
intent.putExtras(bundle);
sendBroadcast(intent);
}
My tweet POJO
import android.os.Parcel;
import android.os.Parcelable;
public class tweet implements Parcelable {
private String created_at;
private String text;
private String retweet_count;
private String favorite_count;
private String image_uri;
public String getImage_uri() {
return image_uri;
}
public String getCreated_at() {
return created_at;
}
public String getText() {
return text;
}
public String getRetweet_count() {
return retweet_count;
}
public String getFavorite_count() {
return favorite_count;
}
protected tweet(Parcel in) {
created_at = in.readString();
text = in.readString();
retweet_count = in.readString();
favorite_count = in.readString();
image_uri = in.readString();
}
public static final Creator<tweet> CREATOR = new Creator<tweet>() {
#Override
public tweet createFromParcel(Parcel in) {
return new tweet(in);
}
#Override
public tweet[] newArray(int size) {
return new tweet[size];
}
};
#Override
public int describeContents() {
return 0;
}
public tweet(String created_at, String text, String retweet_count, String favorite_count, String image_uri) {
this.created_at = created_at;
this.text = text;
this.retweet_count = retweet_count;
this.favorite_count = favorite_count;
this.image_uri = image_uri;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(created_at);
dest.writeString(text);
dest.writeString(retweet_count);
dest.writeString(favorite_count);
dest.writeString(image_uri);
}
}
You used wrong method, you should use intent.putParcelableArrayListExtra() but don't forget about that your array list must contains only parcelables items.
Changing my sendToUI() to this has worked:
private void sendToUI(List tweets) {
Intent intent = new Intent("tweet_result"); //tweet_result is a string to identify this intent
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("data", (ArrayList<? extends Parcelable>) tweets);
intent.putExtras(bundle);
sendBroadcast(intent);
}

How do I iterate through an ArrayList of custom objects from Intent and add them into LinearLayout?

I have an ArrayList of custom FlightData objects within the intent. I load the intent and get the arraylist as null, and the foreach loop also forces me to use Object as type.
Saving arraylist into intent:
intent.putParcelableArrayListExtra("FlightDataList", (ArrayList<? extends Parcelable>) flightDataList);
Loading of intent:
Intent intent = getIntent();
LinearLayout layout_datasheet = findViewById(R.id.layout_datasheet);
List flightDataList = intent.getParcelableArrayListExtra("FlightDataList");
if (flightDataList == null){
Log.d("flightDataList_size", "FlightDataList is null"); // this fires
}
assert flightDataList != null;
for (Object data : flightDataList){
data = (FlightData) data; // items in list are of type FlightData
TextView tv = new TextView(this);
tv.setText(data.toString());
layout_datasheet.addView(tv);
}
My custom class' parcelable functions (x,y,time, has getters-setters):
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeDouble(x);
dest.writeDouble(y);
dest.writeDouble(time);
}
public static final Creator<FlightData> CREATOR = new Creator<FlightData>() {
#Override
public FlightData createFromParcel(Parcel in) {
return new FlightData(in);
}
#Override
public FlightData[] newArray(int size) {
return new FlightData[size];
}
};
1.First Implement Parceable in your FlightData object model / pojo / class
2.val flightDataList= ArrayList<FlightData>()
3.val args = Bundle()
4.args.putParcelableArrayList("FlightDataList", flightDataList)
5.intent.putExtra(args)
Then to get list
val flightDataList = context.getIntent().getExtras().getParcelableArrayList("FlightDataList")
I doubt that you have implemented Parcable in FlightData
https://medium.com/techmacademy/how-to-implement-and-use-a-parcelable-class-in-android-part-1-28cca73fc2d1
It should work. The only thing that I am missing in your example is the constructor. It could explain the null your are getting.
Try adding this constructor for FlightData
public FlightData(Parcel in) {
x = in.readDouble();
y = in.readDouble();
time = in.readDouble();
}
did you try creating a datastructure that implements parcelable?
public class flightDataList implements Parcelable{
String dataThingyString;
int dataThingyInt;
public flightDataList(String dataThingyString, int dataThingyInt){
this.dataThingyString = dataThingyString;
this.dataThingyInt = dataThingyInt;
}
public flightDataList(Parcle in){
this.dataThingyString = in.readString();
this.dataThingyInt = in.readInt();
}
#Override
public void writeToParcel(Parcel dest, int flags){
dest.writeString(dataThingyString);
dest.writeInt(dataThingyInt);
}
public static final Creator<flightDataList> CREATOR = new Creator<flightDataList>(){
#Override
public flightDataList createFromParcel(Parcel source){
return new flightDataList(source);
}
#Override
public flightDataList[] newArray(int size){
return new flightDataList[size];
}
}
public void setdataThingyString(String stringData){
this.dataThingyString = stringData;
}
public void setdataThingyInt(int intData){
this.dataThingyInt = intData;
}
public String getdataThingyString(){
return dataThingyString;
}
public int getdataThingyInt(){
return dataThingyInt;
}
#Override
public int describeContents(){
return 0;
}
}

How do I implement polymorphism properly with Interface?

I have 2 model classes(Data,Title) which contain the same field:
String dataID. I want to get both of this IDs with interface implementation.
I am passing Title model through Bundle to another Activity, passing Data model through Bundle in that same activity(just creating new instance of the activity and resetting information).
I want both of my model classes to implement SharedID interface, with method String getSharedId();
How can I get different ids but from different models? I need to put only one parameter and it should be String in my ViewModelFactory constructor.
public class Data implements SharedId,Parcelable {
private String text;
private String textHeader;
private int viewType;
private String mainId;
private String dataID;
public Data() { }
public String getDataID() {
return dataID;
}
public void setDataID(String dataID) {
this.dataID = dataID;
}
public String getText() {return (String) trimTrailingWhitespace(text); }
public void setText(String text) {
this.text = (String) trimTrailingWhitespace(text);
}
public String getTextHeader() {
return (String) trimTrailingWhitespace(textHeader);
}
public void setTextHeader(String textHeader) {
this.textHeader = textHeader;
}
public int getViewType() {
return viewType;
}
public void setViewType(int viewType) {
this.viewType = viewType;
}
public String getMainId() {
return mainId;
}
public void setMainId(String mainId) {
this.mainId = mainId;
}
protected Data(Parcel in) {
text = in.readString();
textHeader = in.readString();
viewType = in.readInt();
mainId = in.readString();
dataID = in.readString();
}
#Override
public String toString() {
return "Data{" +
"order=" +
", text='" + text + '\'' +
", textHeader='" + textHeader + '\'' +
", viewType=" + viewType +
'}';
}
#SuppressWarnings("StatementWithEmptyBody")
public static CharSequence trimTrailingWhitespace(CharSequence source) {
if (source == null) {
return "";
}
int i = source.length();
// loop back to the first non-whitespace character
while (--i >= 0 && Character.isWhitespace(source.charAt(i))) {
}
return source.subSequence(0, i + 1);
}
public static final Creator<Data> CREATOR = new Creator<Data>() {
#Override
public Data createFromParcel(Parcel in) {
return new Data(in);
}
#Override
public Data[] newArray(int size) {
return new Data[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(text);
dest.writeString(textHeader);
dest.writeInt(viewType);
dest.writeString(mainId);
dest.writeString(dataID);
}
#Override
public String getSharedDataId() {
return getDataID();
}
}
public class Title implements SharedId,Parcelable {
private String dataID;
private String title;
public Title() { }
protected Title(Parcel in) {
dataID = in.readString();
title = in.readString();
}
public String getDataID() {
return dataID;
}
public void setDataID(String dataID) {
this.dataID = dataID;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public static final Creator<Title> CREATOR = new Creator<Title>() {
#Override
public Title createFromParcel(Parcel in) {
return new Title(in);
}
#Override
public Title[] newArray(int size) {
return new Title[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(dataID);
dest.writeString(title);
}
#NonNull
#Override
public String toString() {
return "Title{" +
"dataID='" + dataID + '\'' +
", titleOrder=" +
", title='" + title + '\'' +
'}';
}
#Override
public String getSharedDataId() {
return getDataID();
}
}
And My DetailActivity code, I already succeeded with the mission of passing id, but i need to do this trough interfaces :( So help me out friends, would really appreciate it!
public class DetailActivity extends AppCompatActivity implements
DetailAdapter.OnDialogClickListener,
DetailAdapter.OnDetailClickListener {
private static String id;
private String parentId;
private Data data;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
TextView tvToolbarTitle = findViewById(R.id.title_toolbar_detail);
tvToolbarTitle.setSelected(true);
findViewById(R.id.btn_back).setOnClickListener(v -> finish());
ArrayList<SharedId> sharedIds = new ArrayList<>();
sharedIds.add(new Title());
sharedIds.add(new Data());
for (SharedId sharedId : sharedIds){
System.out.println(sharedId.getSharedDataId());
}
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
Title model = bundle.containsKey("ID") ? bundle.getParcelable("ID") : null;
Data childModel = bundle.containsKey("idDetail") ? bundle.getParcelable("idDetail") : null;
}
if (bundle != null) {
Title model = bundle.containsKey("ID") ? bundle.getParcelable("ID") : null;
Data childModel = bundle.containsKey("idDetail") ? bundle.getParcelable("idDetail") : null;
String parentId = bundle.getString("mainScreenId");
if (parentId != null) {
this.parentId = parentId;
}
if (model != null) {
this.id = model.getDataID();
tvToolbarTitle.setText(model.getTitle());
}
if (childModel != null) {
this.id = childModel.getDataID();
tvToolbarTitle.setText(childModel.getTextHeader());
}
}
RecyclerView recyclerView = findViewById(R.id.rv_detail);
DetailAdapter adapter = new DetailAdapter(this, this);
recyclerView.setAdapter(adapter);
// TODO: 3/1/19 change it to single ID // DetailViewModelFactory(); // id != null ? id : parentId
DetailViewModelFactory detailViewModelFactory = new DetailViewModelFactory(id != null ? id : parentId);
DetailActivityViewModel viewModel = ViewModelProviders.of(this, detailViewModelFactory).get(DetailActivityViewModel.class);
FirebaseListLiveData<Data> liveData = viewModel.getLiveDataQuery();
liveData.observe(this, adapter::setNewData);
}
#Override
public void onDialogClicked(#NonNull String text) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(HtmlCompat.fromHtml(text, 0, null, new HandlerHtml()));
builder.setPositiveButton("Ok", null);
builder.show();
}
#Override
public void onDetailClicked(Data data) {
Intent intent = new Intent();
DetailActivity.open(DetailActivity.this);
intent.putExtra("idDetail", data);
intent.putExtra("mainScreenId", id);
startActivity(intent);
}
public static void open(#NonNull Context context) {
context.startActivity(new Intent(context, InfoActivity.class));
}
}
I found a bit different, but working solution!
I create an interface
public interface SharedId {
String getSharedDataId();
String getHeader();
}
Both of my model classes Data + Title implemented Interface and methods from it.
In DetailActivity i created 2 Strings.
private String mainId;
private String detailId;
And then passed ids with my model classes with bundle
`SharedId mainId = new Title();
SharedId detailId = new Data();
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
mainId = bundle.containsKey("ID") ? bundle.getParcelable("ID") : null;
detailId = bundle.containsKey("idDetail") ?
bundle.getParcelable("idDetail") : null;
}
if (mainId != null) {
this.detailId = mainId.getSharedDataId();
tvToolbarTitle.setText(mainId.getHeader());
}
if (detailId != null) {
this.mainId = detailId.getSharedDataId();
tvToolbarTitle.setText(detailId.getHeader());
}
And passed in my ViewmodelFactory
DetailViewModelFactory detailViewModelFactory =
new DetailViewModelFactory(this.detailId != null ?
this.detailId : this.mainId);

NullPointerException on Android Parcelable Object on Intent

I have this problem with this piece of code and I have been a few days trying to solve it and I can't find the solution.
I have this parcelable class:
public class Sistema implements Parcelable{
private ArrayList<Lista> listas;
private ArrayList<Articulo> articulos;
public Sistema() {
listas = new ArrayList<Lista>();
articulos = new ArrayList<Articulo>();
}
public ArrayList<Lista> getListas() {
return listas;
}
public void agregarLista(Lista lista) {
this.getListas().add(lista);
}
public ArrayList<Articulo> getArticulos(){
return this.articulos;
}
public void agregarArticulo(Articulo articulo){
this.getArticulos().add(articulo);
}
public static final Parcelable.Creator<Sistema> CREATOR =
new Parcelable.Creator<Sistema>() {
#Override
public Sistema createFromParcel(Parcel parcel) {
return new Sistema(parcel);
}
#Override
public Sistema[] newArray(int size) {
return new Sistema[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeTypedList(listas);
parcel.writeTypedList(articulos);
}
public Sistema(Parcel parcel)
{
parcel.readTypedList(listas, Lista.CREATOR);
parcel.readTypedList(articulos, Articulo.CREATOR);
}
}
And then in the main i use an intent to send a Sistema object to an other activity:
public void addArticle(View view) {
Intent intent = new Intent(this, AgregarArticulo.class);
intent.putExtra("objectSystem", s);
this.startActivityForResult(intent, 1);
}
Here is where the problem is, i recieve the intent in the second activity with this code:
Intent intento = getIntent();
s = intento.getParcelableExtra("objectSystem");
When I run the code, i get a NullPointerException in the getParcelableExtra
Do you guys have an idea of what the problem should be?
Thanks
Could you please try this . You need to prefix your package name(com.example.whatever) with the name your passing in putExtra:
public void addArticle(View view) {
Intent intent = new Intent(this, AgregarArticulo.class);
intent.putExtra("YOURPACKAGENAME.objectSystem", s);
this.startActivityForResult(intent, 1);
}
and same in getParcelableExtra also:
Intent intento = getIntent();
s = intento.getParcelableExtra("YOURPACKAGENAME.objectSystem");

Categories