Внедрение Javascript в веб-представление вне события onPageFinished (использование DatePicker для установки даты на входе веб-представления) - PullRequest
0 голосов
/ 08 февраля 2011

У меня есть приложение для Android, на котором запущен WebView, который загружает определенную страницу, также являющуюся частью приложения.Я хочу использовать Android DatePicker, чтобы получить дату от пользователя и установить значение на входе внутри страницы в WebView.

DatePickerDialog открывается, когда пользователь нажимает на вход, но когда я получаю возвратиз выбора даты, я не могу запустить метод loadUrl для установки значения на входе, он выдает ошибку, и приложение вылетает.

Немного кода (Это тестовый код, так чтоне берите в голову, если это немного вне контекста):

Класс, который я предоставляю WebView:

public class webViewInterface {
    public void openDatePicker(){
        showDialog(0);
    }
}

Функция Javascript на странице,вызывается по щелчку ввода:

function openDatePicker() {
        if (objAndroid != null) objAndroid.openDatePicker();
    }

Слушатель для выбора даты

private DatePickerDialog.OnDateSetListener mDateSetListener =
    new DatePickerDialog.OnDateSetListener() {

        public void onDateSet(DatePicker view, int year, 
                              int monthOfYear, int dayOfMonth) {

            mWebView.loadUrl("javascript:setReturnDate();");
        }
    };

Функция Javascript, которая устанавливает значение навход

function setReturnDate() {
        document.getElementById('txtAgency').value = '9999';
    }

Есть идеи?

Заранее спасибо.

1 Ответ

2 голосов
/ 10 февраля 2011

Спасибо @CommonsWare за комментарий, я отследил ошибку и получил следующее:

"android.view.ViewRoot $ CalledFromWrongThreadException: только исходный поток, создавший иерархию представления, может касаться его представлений."

Гуглил и получил эту ветку форума

Итак, чтобы обновить представление в пользовательском интерфейсе во время выполнения и вне его цепочки, вы должныиспользуйте обработчик, который получает сообщения и выполняет действия соответственно.

Итак, я реализовал обработчик для действия, который получает сообщение с идентификатором int и данными, которые я хочу обновить в веб-представлении:

final Handler handler = new Handler() {
    public void handleMessage(Message msg) {

        int cod = msg.getData().getInt("messageType");
        switch(cod){
            case 1:
                String date = msg.getData().getString("datePickerValue");
                mWebView.loadUrl("javascript:setReturnDate('" + mId + "', '" + date + "');");
                break;
            case 2:
                showDialog(0);
                break;
        }

    }
};

Мне пришлось изменить метод openDatePicker класса, чтобы использовать обработчик, а также создать входной параметр, который является идентификатором элемента управления на странице:

public void openDatePicker(String id){

        mId = id; //mId is a string declared in the Activity scope, so it can be used anywhere
        Message msg = new Message();
        Bundle b = new Bundle();
        b.putInt("messageType", 2);

        msg.setData(b);
        handler.sendMessage(msg);
    }

Переписан обработчик DatePicker для выбора даты, чтобы получить данные и отправить сообщение обработчику:

private DatePickerDialog.OnDateSetListener mDateSetListener =
    new DatePickerDialog.OnDateSetListener() {

        public void onDateSet(DatePicker view, int year, 
                              int monthOfYear, int dayOfMonth) {

            Message msg = new Message();
            Bundle b = new Bundle();
            b.putInt("messageType", 1);
            b.putString("datePickerValue", 
                    String.format("%02d", dayOfMonth) + "/" + 
                    String.format("%02d", (monthOfYear + 1)) + "/" + 
                    String.valueOf(year));
            msg.setData(b);
            handler.sendMessage(msg);
        }
    };

Inвеб-страница, JS ФуФункции получаются так:

function openDatePicker(id) {
        if (objAndroid != null) objAndroid.openDatePicker(id);
    }

    function setReturnDate(id, date) {
        var obj = document.getElementById(id);
        if (obj != null)
            obj.value = date;
    }

И, наконец, ввод (TextBox) получается так:

TextBox obj = FindControl("txtDt") as TextBox;

            if (obj != null)
            {
                obj.Attributes.Add("readonly", "readonly");
                obj.Attributes.Add("OnClick", "javascript:openDatePicker(this.id)");
            }
...