Невозможно добавить исключение окна при вызове DatePickerDialog Show - PullRequest
0 голосов
/ 11 марта 2020

Я новичок в Android Studio и Android разработке, но с некоторыми онлайн-запросами я написал класс для обработки запросов DatePickerDialog и TimePickerDialog для установки даты.

На основе Например, я написал класс:

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; }
}

И затем вызвал его в моей MainActivity (единственной активности в приложении) с помощью этого объявления:

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(); }});
    }
}

Но когда я отлаживал приложение, в строке, помеченной todo в классе DatePick, где он вызывает метод "show ()" диалогового окна, я получаю исключение:

Невозможно добавить окно - токен нулевой, выполняется ли операция?

Не могу понять, как это не работает, любая помощь?

1 Ответ

0 голосов
/ 11 марта 2020

Попробуйте заменить контекст приложения на контекст активности.

DatePickerDialog (Контекст контекста) Создает новый диалог выбора даты для текущей даты, используя родительский контекст *1005* по умолчанию выбора даты. тема диалога.

Источник: https://developer.android.com/reference/android/app/DatePickerDialog

Обновление : я знаю, это кажется противоречивым. Можно предположить, что в контексте приложения есть все, что есть у активности, и даже больше. Но это не так. getApplicationContext () не может использоваться для запуска диалогов. Подробнее здесь .

К вашему коду: когда вы пишете new cweb.companion.DatePick(this);, вы уже передаете контекст действия, так что вы можете просто избавиться от getApplicationContext() и написать new DatePickerDialog(activity, new ...

Я также заметил, что вы используете this. все время, когда это не нужно. Например, я бы заменил this.picked = false; на picked = false;

И вы могли бы использовать импорт, чтобы избавиться от этих длинных имен пакетов. Я бы заменил такие вещи, как

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

на

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

Просто чтобы легче было читать код. Попробуйте, надеюсь, это поможет.

Обновление 2: Следующий код работает на моем p c. Он показывает диалог, а затем тост. Попробуйте адаптировать его к вашим потребностям. Если это не сработает, то я не знаю причину. ;)

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();
    }
}
...