I am trying to show an AlertDialog when an item in a ListActivity is clicked. My app displays the ListActivity under a tab of a TabActivity, and the AlertDialog shows up no problem. The ListActivity (called FavouritesActivity) is pretty much straight from the Android docs, with this setting:
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//... code to set the strings station, number, route, and direction
FavouritesActivity.this.confirmSend(position);
}
});
and then
public void confirmSend(final int position) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure?")
.setCancelable(true)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
//... some code to run here
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
However, in a second tab of the TabActivity, I have an ActivityGroup that uses the LocalActivityManager to start another ListActivity, like so (again, pretty much unchanged from a tutorial on nesting lists under tabs online):
public class MyGroupActivity extends ActivityGroup {
// Keep this in a static variable to make it accessible for all the nesten activities, lets them manipulate the view
public static MyGroupActivity group;
// Need to keep track of the history if you want the back-button to work properly, don't use this if your activities requires a lot of memory.
private ArrayList<View> history;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.history = new ArrayList<View>();
group = this;
// Start the root activity withing the group and get its view
View view = getLocalActivityManager().startActivity("FirstListActivity", new
Intent(this,FirstListActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
.getDecorView();
// Replace the view of this ActivityGroup
replaceView(view);
}
public void replaceView(View v) {
// Changes this Groups View to the new View.
setContentView(v);
}
The FirstListActivity here is a ListActivity that is the first in a series. The user picks an item and is presented with another ListActivity, with code like this:
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent intent = new Intent();
intent.setClass(FirstListActivity.this, TheNextListActivity.class);
// Create View using the Group Activity's LocalActivityManager
View newview = MyGroupActivity.group.getLocalActivityManager()
.startActivity("show_routes", intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
.getDecorView();
// And replace the view
MyGroupActivity.group.replaceView(newview);
}
});
The last ListActivity in this series has EXACTLY the same onItemClick listener and associated confirmSend function as the first ListActivity example I showed (the one which does work), but now when the user clicks on an item, the AlertDialog fails to show and the application stops unexpectedly, with this debug output:
W/WindowManager( 570): Attempted to add application window with unknown token android.os.BinderProxy@4373af30. Aborting.
D/AndroidRuntime( 1953): Shutting down VM
W/dalvikvm( 1953): threadid=3: thread exiting with uncaught exception (group=0x4000fe70)
E/AndroidRuntime( 1953): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 1953): android.view.WindowManager$BadTokenException: Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord@43750f98 is not valid; is your activity running?
E/AndroidRuntime( 1953): at android.view.ViewRoot.setView(ViewRoot.java:425)
E/AndroidRuntime( 1953): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:178)
E/AndroidRuntime( 1953): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/AndroidRuntime( 1953): at android.view.Window$LocalWindowManager.addView(Window.java:392)
E/AndroidRuntime( 1953): at android.app.Dialog.show(Dialog.java:231)
E/AndroidRuntime( 1953): at com.ttcsms.LastListActivity.confirmSend(LastListActivity.java:119)
E/AndroidRuntime( 1953): at com.ttcsms.LastListActivity$1.onItemClick(LastListActivity.java:66)
E/AndroidRuntime( 1953): at android.widget.AdapterView.performItemClick(AdapterView.java:283)
E/AndroidRuntime( 1953): at android.widget.ListView.performItemClick(ListView.java:3132)
E/AndroidRuntime( 1953): at android.widget.AbsListView$PerformClick.run(AbsListView.java:1620)
E/AndroidRuntime( 1953): at android.os.Handler.handleCallback(Handler.java:587)
E/AndroidRuntime( 1953): at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime( 1953): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 1953): at android.app.ActivityThread.main(ActivityThread.java:3948)
E/AndroidRuntime( 1953): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 1953): at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 1953): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
E/AndroidRuntime( 1953): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
E/AndroidRuntime( 1953): at dalvik.system.NativeStart.main(Native Method)
I/Process ( 570): Sending signal. PID: 1953 SIG: 3
I/dalvikvm( 1953): threadid=7: reacting to signal 3
I/dalvikvm( 1953): Wrote stack trace to '/data/anr/traces.txt'
I/Process ( 1953): Sending signal. PID: 1953 SIG: 9
I/ActivityManager( 570): Process com.ttcsms (pid 1953) has died.
What is the difference between these two routes to the AlertDialog that cause this failure? It seems to have something to do with the AlertDialog.Building(this) bit. When within the ActivityGroup, it's getting the wrong context or something. Every example I found online of this error was solved by changing between "this" and "getApplicationContext()", but in this case neither of those work. I tried other variations on getting the context but as I mostly guessing at random I thought it would be better to ask here for advice. What context should I be passing, or, what else is wrong?
Got it! Actually here it's an Android Context problem.
In line:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
Instead of this, you should pass the Context of the TabActivity, the context of the visible/main activity is passed to display any popup within activity.
So, simple solution:
hope this helps. cheers :)