Unable to Add Window Exception on calling DatePickerDialog Show

SammuelMiranda :

i'm new to Android Studio and Android development, but with some online quering i got to write a class to handle the DatePickerDialog and TimePickerDialog requests to set a date.

Based on an example i wrote the class:

class DatePick
{
    protected android.app.Activity activity;
    public final java.util.Calendar currentDate = java.util.Calendar.getInstance();
    private boolean picked;
    public java.util.Calendar date;

    public java.util.Calendar pickDate()
    {
        this.picked = false;
        this.date = java.util.Calendar.getInstance();
        android.app.DatePickerDialog datePicker = new android.app.DatePickerDialog(this.activity.getApplicationContext(), new android.app.DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(android.widget.DatePicker view, int year, int month, int dayOfMonth) { cweb.companion.DatePick.this.date.set(view.getYear(), view.getMonth(), view.getDayOfMonth()); } }, this.currentDate.get(java.util.Calendar.YEAR), this.currentDate.get(java.util.Calendar.MONTH), this.currentDate.get(java.util.Calendar.DAY_OF_MONTH)) { @Override public void onClick(android.content.DialogInterface dialog, int which) { cweb.companion.DatePick.this.picked = (which == android.content.DialogInterface.BUTTON_POSITIVE); } };
        datePicker.show(); //todo resolve: exception here for unable to add window null token
        datePicker = null; //dispose?
        if (this.picked)
        {
            android.app.TimePickerDialog timePicker = new android.app.TimePickerDialog(this.activity.getApplicationContext(), new android.app.TimePickerDialog.OnTimeSetListener() { @Override public void onTimeSet(android.widget.TimePicker view, int hourOfDay, int minute) { cweb.companion.DatePick.this.date.set(cweb.companion.DatePick.this.date.get(java.util.Calendar.YEAR), cweb.companion.DatePick.this.date.get(java.util.Calendar.MONTH), cweb.companion.DatePick.this.date.get(java.util.Calendar.DAY_OF_MONTH), hourOfDay, minute); } }, this.currentDate.get(java.util.Calendar.HOUR_OF_DAY), this.currentDate.get(java.util.Calendar.MINUTE), true) { @Override public void onClick(android.content.DialogInterface dialog, int which) { cweb.companion.DatePick.this.picked = (which == android.content.DialogInterface.BUTTON_POSITIVE); } };
            timePicker.show(); //picked may change back to false after that (maybe, depending on the user's confirm/abort)
            timePicker = null; //dispose?
        }
        if (!this.picked) { this.date = null; }
        return cweb.companion.DatePick.this.date;
    }

    public static java.lang.String toString(java.util.Calendar date) { return java.lang.String.format("%02d", date.get(java.util.Calendar.DAY_OF_MONTH)) + "/" + java.lang.String.format("%02d", date.get(java.util.Calendar.MONTH)) + "/" + java.lang.String.format("%04d", date.get(java.util.Calendar.YEAR)) + " " + java.lang.String.format("%02d", date.get(java.util.Calendar.HOUR_OF_DAY)) + ":" + java.lang.String.format("%02d", date.get(java.util.Calendar.MINUTE)) + ":" + java.lang.String.format("%02d", date.get(java.util.Calendar.SECOND)); }
    public DatePick(android.app.Activity activity) { this.activity = activity; }
}

And then called it in my MainActivity (the only activity in the app) by this declaration:

public class MainActivity extends androidx.appcompat.app.AppCompatActivity
{
    protected android.widget.Button datePickCall;
    private java.util.Calendar date;

    private void pickdatePickCall()
    {
        cweb.companion.DatePick picker = new cweb.companion.DatePick(this);
        this.date = picker.pickDate();
        this.datePickCall.setText(cweb.companion.DatePick.toString(this.date));
    }

    @Override protected void onCreate(android.os.Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        this.setContentView(cweb.companion.R.layout.activity_main);
        this.datePickCall = this.findViewById(cweb.companion.R.id.datePickCall);
        this.datePickCall.setOnClickListener(new android.view.View.OnClickListener() { @Override public void onClick(android.view.View v) { cweb.companion.MainActivity.this.pickdatePickCall(); }});
    }
}

But as i debug the app, on the line marked with the todo at DatePick class where it calls the "show()" method of a dialog i get an exception and message about "Unable to add window - Token null, is activity running?". Can't seem to understand how does it not work, any help?

einUsername :

Try replacing the application context with the activity context.

DatePickerDialog(Context context) Creates a new date picker dialog for the current date using the parent context's default date picker dialog theme.

Source: https://developer.android.com/reference/android/app/DatePickerDialog

Update: I know it seems contradictory. One could assume that the application context has everything the activity has and more. But that's not the case. getApplicationContext() can not be used to start dialogs. More here.

To your code: When you wrote new cweb.companion.DatePick(this); you are already passing the activity context so you can just get rid of the getApplicationContext() and write new DatePickerDialog(activity, new ...

I also noticed that you use this. all the time when it's not necessary. For example i would replace this.picked = false; with picked = false;

And you could use imports to get rid of those long package names. I would replace things like

android.app.DatePickerDialog datePicker = new android.app.DatePickerDialog(...

with

import android.app.DatePickerDialog;
public class DatePick { ...
DatePickerDialog datePicker = new DatePickerDialog(...

Just so it's easier to read the code. Try it out, i hope this helps.

Update 2: The following code is working on my pc. It shows the dialog and then a toast. Try to adapt it to your needs. If this doesn't work on yours then i don't know the reason. ;)

package com.something.dialogtest;

import android.app.DatePickerDialog;
import android.os.Bundle;
import android.widget.DatePicker;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import java.util.Calendar;

public class MainActivity extends AppCompatActivity {

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

        DatePickerDialog datePicker = new DatePickerDialog(this,
                new DatePickerDialog.OnDateSetListener() {
                    @Override
                    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                        Toast.makeText(MainActivity.this, "onDateSet", Toast.LENGTH_SHORT).show();
                    }
                },
                Calendar.getInstance().get(Calendar.YEAR),
                Calendar.getInstance().get(Calendar.MONTH),
                Calendar.getInstance().get(Calendar.DAY_OF_MONTH));
        datePicker.show();
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=195097&siteId=1