0

Hello everyone Im having an issue with making a dialog appear from an onClick listener from within a listview item. The dialogs were appearing and working fine within my application before I made certain methods in the activity that calls for the listview adapter static so that I could call those methods from the adapter. I am getting the error of:

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application

from the call to:

   alertDialog.show();

Before you tell me to go lookup this issue (because I have discovered that it is common) I have. And I have found solutions but none of them work for me. I haven't found anyone else having this issue within a custom listview adapter.

AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getContext());

was working fine until the listview and certain methods were made static in the Services Acivity.

DancerAdpater.java

public class DancerAdapter extends ArrayAdapter<OneDancer> {

   int type;
    private static FragmentManager fragmentManager;
    static Context context;
    static public Integer count=1;




  public DancerAdapter(Context context, ArrayList<OneDancer> dancers, int type) {
    super(context, 0, dancers);
    this.type=type;
    this.context=context;

}
    public DancerAdapter(Context context, ArrayList<OneDancer> dancers, int type,FragmentManager fragmentManager) {
        super(context, 0, dancers);
        this.type=type;
        this.fragmentManager = fragmentManager;
    }

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // Get the data item for this position
        final OneDancer oneDancer = getItem(position);
        // Check if an existing view is being reused, otherwise inflate the view
        if (convertView == null) {


if(type==3) {

                convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_services, parent, false);

                final Button button4 = (Button)convertView.findViewById(R.id.button4);

                final TextView counterTextView = (TextView)convertView.findViewById(R.id.textView10);

                final Button button6 = (Button)convertView.findViewById(R.id.button6);

                final Button button5 = (Button)convertView.findViewById(R.id.button5);

                final Button button8 = (Button)convertView.findViewById(R.id.button8);

                final Button button9 = (Button)convertView.findViewById(R.id.button9);

                final Button button10 = (Button)convertView.findViewById(R.id.button10);



//Start Suite Button
                button8.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
                        // set title
                        alertDialogBuilder.setTitle("Confirm - Hold for Suite?");
                        // set dialog message
                        alertDialogBuilder
                                .setMessage("Confirm hold suite for " + oneDancer.name + "?")
                                .setCancelable(false)
                                .setPositiveButton("Yes",new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog,int id) {

                                        AsyncHttpClient client = new AsyncHttpClient();
                                        RequestParams params = new RequestParams();
                                        params.put("action", "makeVip");
                                        params.put("name", oneDancer.name);
                                        //params.put("TimeOut", );


                                        Log.v("SignInActivity","Girl Made UnAvailable Response Query");

                                        client.post("http://peekatu.com/apiweb/girlList.php", params,
                                                new AsyncHttpResponseHandler() {
                                                    @Override
                                                    public void onSuccess(String response) {
                                                        Log.v("response", response);
                                                        //responseString = response;
                                                        //parseDancerList(response);


                                                        button5.setVisibility(View.GONE);
                                                        button4.setVisibility(View.GONE);
                                                        button8.setVisibility(View.GONE);
                                                        button6.setVisibility(View.VISIBLE);
                                                        button9.setVisibility(View.VISIBLE);
                                                        button10.setVisibility(View.VISIBLE);
                                                        counterTextView.setVisibility(View.VISIBLE);
                                                        Services.refresh();


                                                        if (response.indexOf("OK") > -1) {
                                                            Toast.makeText(getContext(),
                                                                    "VIP Dance has began for " + oneDancer.name,
                                                                    Toast.LENGTH_SHORT).show();



                                                        }

                                                    }

                                                    @Override
                                                    public void onFailure(Throwable error, String content) {
                                                        Log.v("response", "response failed network error");
                                                        //waitncall(true);

                                                    }

                                                });
                                        dialog.cancel();
                                    }
                                })
                                .setNegativeButton("No",new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog,int id) {
                                        // if this button is clicked, just close
                                        // the dialog box and do nothing
                                        dialog.cancel();
                                    }
                                });

                        // create alert dialog
                        AlertDialog alertDialog = alertDialogBuilder.create();

                        // show it
                        alertDialog.show();



                    }
                });

item_services.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#3d87d5">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Name"
        android:id="@+id/tvName"
        android:layout_weight="1"
        android:layout_gravity="center_vertical"
        android:textSize="20dp"
        android:textStyle="bold" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tvAvail"
        android:layout_gravity="center_vertical"
        android:layout_weight=".1"
        android:src="@drawable/online"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/feature_button"
        android:id="@+id/button5"
        android:layout_gravity="center_vertical|right" />

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/start_dance"
        android:id="@+id/button4"
        android:layout_gravity="center_vertical"
        android:background="#005906"
        android:layout_weight="1"
         />

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="+30 Mins"
        android:id="@+id/button10"
        android:layout_weight="1"
        android:visibility="gone" />

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="+60 Mins"
        android:id="@+id/button9"
        android:layout_weight="1"
        android:visibility="gone" />

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Start Suite"
        android:id="@+id/button8"
        android:layout_weight="1"
        android:background="#fdd32b" />

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="00"
        android:id="@+id/textView10"
        android:visibility="gone"
        android:layout_weight="1" />

    <Button
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/stop_dance"
        android:id="@+id/button6"
        android:background="#ab0000"
        android:visibility="gone"
        android:layout_weight="1" />

</LinearLayout>

Services.java

public class Services extends Activity {

static Context context;
static private ListView listView ;
static private String responseString;
static String responseString2;
static ArrayList<OneDancer> oneDancerArrayList = new ArrayList<OneDancer>();
public DancerAdapter adapter;
Button addDancer;
Button loginDancer;
EditText dancerName;
EditText nameInput;
Integer count=0;
static DialogFragment newFragment;
public View rootView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sign_in);

    Services.context = getApplicationContext();
    if(adapter!=null){
        adapter.clear();
    }

    View rootView = null;
    View currentFocus = getWindow().getCurrentFocus();
    if (currentFocus != null)
        rootView = currentFocus.getRootView();

    Log.v("SignInActivity", "Activity has began");
    // Declare Listview
    listView = (ListView) findViewById(R.id.listView);

    // Assign adapter to ListView
    listView.setAdapter(adapter);

    //Call to Database and retrieve girl list
    getGirlList();

    }

static public void refresh(){
        getGirlList();
        adapter.notifyDataSetChanged();
    }
static public void getGirlList() {

    Log.v("SignInActivity","getGirlList has started");


    AsyncHttpClient client = new AsyncHttpClient();
    RequestParams params = new RequestParams();
    params.put("action", "getDancers");

    Log.v("SignInActivity","Girl List Response Query");

    client.post("http://peekatu.com/apiweb/girlList.php", params,
            new AsyncHttpResponseHandler() {
                @Override
                public void onSuccess(String response) {
                    Log.v("response", response);
                    responseString = response;
                    parseDancerList(response);
                    Log.v("SignInActivity", response);
                    Log.v("SignInActivity","Girl List Response" + responseString);
                }

                @Override
                public void onFailure(Throwable error, String content) {
                    Log.v("response", "response failed network error");
                    //waitncall(true);

                }

            });
    Log.v("SignInActivity","getGirlList ended");
}


// Parsing of private messages
    static public void parseDancerList(String response) {

    Log.v("SignInActivity","parseDancerList");
    XMLParser parser = new XMLParser();

    Document doc = parser.getDomElement(response); // getting DOM element

    NodeList nl = doc.getElementsByTagName("DANCERS");

oneDancerArrayList.clear();



    Log.v("response ", "Dancer Count " + nl.getLength());
    // looping through all item nodes <item>
    for (int i = 0; i < nl.getLength(); i++) {
        // creating new HashMap
        //adapter = new DancerAdapter(context,oneDancerArrayList,3);
       // adapter = new DancerAdapter(this,oneDancerArrayList,3);
        Element e = (Element) nl.item(i);
        Log.v("response ", "Dancers  " + parser.getValue(e, "NAME"));

        OneDancer newDancer = new OneDancer(parser.getValue(e,"POSITION"),
                parser.getValue(e,"NAME"),
                parser.getValue(e,"AVAILABLE"),
                null,
                null,
                null,
                null,
                null,
                null,"0");

        adapter.addAll(newDancer);
        listView.setAdapter(adapter);
        adapter.notifyDataSetChanged();




    }

}

I have tried this and Services.this as well as getApplicationContext() and none of these solutions are working for me. Please help. Thank you.

TWeeKeD
  • 119
  • 1
  • 2
  • 16
  • are you tried 'this' to crate adapter like " adapter = new DancerAdapter(this,oneDancerArrayList,3) ? – Abu Yousuf Aug 27 '16 at 18:17
  • yes. it tells me i cant use this from within a static context – TWeeKeD Aug 27 '16 at 18:21
  • then use a function and pass the resource array/list as parameter and initialize the adapter inside the function with 'this'. like public void setAdapter(String[] str){ customListViewAdapter = new CustomListViewAdapter( str, this); } – Abu Yousuf Aug 27 '16 at 18:25
  • why you need most of function to be static? – Abu Yousuf Aug 27 '16 at 18:59
  • the purpose of the button is to trigger a call to the database and update information within the listview item. I have to have the methods as static in order to call them from the adapter. – TWeeKeD Aug 27 '16 at 21:38

1 Answers1

0

You can follow this step:

  1. Create a global ArrayList for adapter data source and initialize adapter with this arraylist(initialize it before using it) in onCreate() method
  2. When new data is available clear previous data of ArrayList by calling ArrayList.clear() then add all new data to that Arraylist and call adapter.notifyDataSetChanged();

By this way you can avoid using this in static context.

Edited: Use the Context to create AlertDialog that was passed to constructor.

  1. Declare a Context variable in Adapter class and initialize it inside the constructor with the context object you are passing as parameter.
  2. Then use that context object to initialize the AlertDialog.

     AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getContext());
    

Use context variable that you initialized in contructor instead of getContext()

Abu Yousuf
  • 5,729
  • 3
  • 31
  • 50
  • let me know your problem is solved and still having problem – Abu Yousuf Aug 27 '16 at 19:10
  • ok. i have made this change and that does work as far as allowing the listview to populate but when I click on the button within the listview to load the dialog box I still get crash with `Unable to Add window` error – TWeeKeD Aug 27 '16 at 19:28
  • I have made the changes and updated the code in my original question to reflect the updates. It runs and the list populates but I still get same error when dialog is supposed to open. – TWeeKeD Aug 27 '16 at 20:26
  • Bump! Still struggling with this one. – TWeeKeD Aug 28 '16 at 16:42