I have a widget that contains few buttons. when pressed each button opens my main app and sends a different object to it. the objects are passed down as parcelable extras.
however when the activity starts any method that tries to access the extras (in this case writing them to log) crashes the app.
the objects are implemented properly (i parcel and unparcel them when using onSaveInstance etc).
why does the error occur and how do i prevent it while sending the object to the app?
here is the log:
12-31 13:27:45.505: I/GABI(9710): WIDGET - createContactIntents()
12-31 13:27:45.505: V/GABI(9710): creating intent number:0
12-31 13:27:45.505: V/GABI(9710): contact:db
12-31 13:27:45.505: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=name:db number:0506583522 id:4, widgetCallingButton=0, widgetChosenAction=1}]
12-31 13:27:45.505: V/GABI(9710): intent data:Intent { act=0 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.505: V/GABI(9710): creating intent number:1
12-31 13:27:45.510: V/GABI(9710): contact:Developers
12-31 13:27:45.510: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=com.a.example.ContactGroup@4055cfb8, widgetCallingButton=1, widgetChosenAction=1}]
12-31 13:27:45.510: V/GABI(9710): intent data:Intent { act=1 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.510: V/GABI(9710): creating intent number:2
12-31 13:27:45.510: V/GABI(9710): contact:gabi
12-31 13:27:45.510: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=name:gabi number:0506583522 id:1, widgetCallingButton=2, widgetChosenAction=1}]
12-31 13:27:45.510: V/GABI(9710): intent data:Intent { act=2 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.510: V/GABI(9710): creating intent number:3
12-31 13:27:45.510: V/GABI(9710): contact:asaf
12-31 13:27:45.510: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=name:asaf number:*********id:2, widgetCallingButton=3, widgetChosenAction=1}]
12-31 13:27:45.510: V/GABI(9710): intent data:Intent { act=3 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.510: V/GABI(9710): widget number:7 id:37
12-31 13:27:45.510: I/GABI(9710): WIDGET - createContactIntents()
12-31 13:27:45.510: V/GABI(9710): creating intent number:0
12-31 13:27:45.510: V/GABI(9710): contact:db
12-31 13:27:45.510: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=name:db number:**********id:4, widgetCallingButton=0, widgetChosenAction=1}]
12-31 13:27:45.510: V/GABI(9710): intent data:Intent { act=0 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.510: V/GABI(9710): creating intent number:1
12-31 13:27:45.510: V/GABI(9710): contact:Developers
12-31 13:27:45.515: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=com.a.example.ContactGroup@4055cfb8, widgetCallingButton=1, widgetChosenAction=1}]
12-31 13:27:45.515: V/GABI(9710): intent data:Intent { act=1 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.515: V/GABI(9710): creating intent number:2
12-31 13:27:45.515: V/GABI(9710): contact:gabi
12-31 13:27:45.515: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=name:gabi number:******* id:1, widgetCallingButton=2, widgetChosenAction=1}]
12-31 13:27:45.515: V/GABI(9710): intent data:Intent { act=2 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.515: V/GABI(9710): creating intent number:3
12-31 13:27:45.515: V/GABI(9710): contact:asaf
12-31 13:27:45.515: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=name:asaf number:********id:2, widgetCallingButton=3, widgetChosenAction=1}]
12-31 13:27:45.515: V/GABI(9710): intent data:Intent { act=3 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:46.380: W/KeyCharacterMap(9710): No keyboard for id 0
12-31 13:27:46.380: W/KeyCharacterMap(9710): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
12-31 13:27:49.855: V/GABI(9710): widget activation
12-31 13:27:49.855: V/GABI(9710): extras:Bundle[mParcelledData.dataSize=328]
12-31 13:27:49.855: D/AndroidRuntime(9710): Shutting down VM
12-31 13:27:49.855: W/dalvikvm(9710): threadid=1: thread exiting with uncaught exception (group=0x4001e578)
12-31 13:27:49.860: E/AndroidRuntime(9710): FATAL EXCEPTION: main
12-31 13:27:49.860: E/AndroidRuntime(9710): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.a.example/com.a.example.MainActivity}: java.lang.RuntimeException: Parcel android.os.Parcel@4056eb48: Unmarshalling unknown type code 6881399 at offset 224
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.os.Handler.dispatchMessage(Handler.java:99)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.os.Looper.loop(Looper.java:123)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.ActivityThread.main(ActivityThread.java:3691)
12-31 13:27:49.860: E/AndroidRuntime(9710): at java.lang.reflect.Method.invokeNative(Native Method)
12-31 13:27:49.860: E/AndroidRuntime(9710): at java.lang.reflect.Method.invoke(Method.java:507)
12-31 13:27:49.860: E/AndroidRuntime(9710): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
12-31 13:27:49.860: E/AndroidRuntime(9710): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
12-31 13:27:49.860: E/AndroidRuntime(9710): at dalvik.system.NativeStart.main(Native Method)
12-31 13:27:49.860: E/AndroidRuntime(9710): Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@4056eb48: Unmarshalling unknown type code 6881399 at offset 224
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.os.Parcel.readValue(Parcel.java:1913)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.os.Parcel.readMapInternal(Parcel.java:2083)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.os.Bundle.unparcel(Bundle.java:208)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.os.Bundle.getInt(Bundle.java:900)
12-31 13:27:49.860: E/AndroidRuntime(9710): at com.a.example.MainActivity.onCreate(MainActivity.java:61)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
12-31 13:27:49.860: E/AndroidRuntime(9710): ... 11 more
the widget code:
// Create Intents to launch activity
PendingIntent[] pendingIntents=createIntents(context,favoriteContacts,4);
// Get the layout for the App Widget
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
// attach an on-click listener to the buttons
views.setOnClickPendingIntent(R.id.w_ContactImageButton1, pendingIntents[0]);
views.setOnClickPendingIntent(R.id.w_ContactImageButton2, pendingIntents[1]);
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
this is what create intents does:
Log.v("GABI","creating intent number:"+i);
intent=new Intent(context, MainActivity.class);
intent.setAction(i+"");
intent.putExtra(MainActivity.TAG_WIDGET_CHOSEN_ACTION,MainActivity.ACTION_CHOOSE_CONTACT);
intent.putExtra(MainActivity.TAG_WIDGET_CHOSEN_CONTACT,favoriteContacts.get(i));
Log.v("GABI","contact:"+favoriteContacts.get(i).getDisplayName());
intent.putExtra(MainActivity.TAG_WIDGET_CALLING_BUTTON,i);
Log.v("GABI","WIDGET- "+intent.getExtras().toString());
intents[i] = PendingIntent.getActivity(context, 0, intent,PendingIntent.FLAG_ONE_SHOT);
Log.v("GABI","intent data:"+intent.toString());
the main app onCreate method:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int action=ACTION_NO_ACTION;
//if the appWidget started this activity get chosen object and go srtaight to action chooser
Intent intent=getIntent();
Bundle extras=intent.getExtras();
if (extras!=null)
{
Log.v("GABI", "widget activation");
//Log.v("GABI","extras:"+extras.keySet().toString());
Log.v("GABI","extras:"+extras.toString());//here the error happens before that it happened in the previous line...
action=extras.getInt(TAG_WIDGET_CHOSEN_ACTION);
int callingButton=extras.getInt(TAG_WIDGET_CALLING_BUTTON);
if (action==ACTION_CHOOSE_CONTACT)
{
ContactDisplay contact= extras.getParcelable(TAG_WIDGET_CHOSEN_CONTACT);
getSupportFragmentManager().beginTransaction()
.add(R.id.container, FragmentActionChooser.newInstance(contact),FRAGMENT_TAG_ACTION_CHOOSER)
.commit();
}
}
the parcel class constructor:
/**
* Constractor for auto use in android while passing as a parcel
* @param in
*/
public Contact(Parcel in)
{
set_id(in.readLong());
set_firstName(in.readString());
set_lastName(in.readString());
set_phoneNumber(in.readString());
set_email(in.readString());
set_creationDate(in.readString());
set_lastUpdate(in.readString());
set_phones(in.readString());
set_idInPhone(in.readInt());
set_priority(in.readInt());
set_isMember(in.readByte() != 0);
set_numOfCalls(in.readInt());
}
the write to parcel method:
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeLong(get_id());
dest.writeString(get_firstName());
dest.writeString(get_lastName());
dest.writeString(get_phoneNumber());
dest.writeString(get_email());
dest.writeString(get_creationDate());
dest.writeString(get_lastUpdate());
dest.writeString(get_phones());
dest.writeLong(get_idInPhone());
dest.writeInt(get_priority());
dest.writeByte((byte) (is_isMember() ? 1 : 0)); //if is_isMember == true, byte == 1
dest.writeInt(get_numOfCalls());
}
the creator class:
public static final Parcelable.Creator<Contact> CREATOR
= new Parcelable.Creator<Contact>() {
public Contact createFromParcel(Parcel in) {
return new Contact(in);
}
public Contact[] newArray(int size) {
return new Contact[size];
}
};
For your idInPhone in phone in constructor your are reading it as int
set_idInPhone(in.readInt());
But in writeToParcel() method you writing it as long
dest.writeLong(get_idInPhone());
Change any one to long or int according to your variable declaration...