Injecter Javascript dans une vue Web en dehors de l'événement OnPageFinished (Utilisation de DatePicker pour définir une date sur une entrée d'un WebView)

J'ai une application Android, une application Web qui charge une certaine page, également une partie de l'application. Je souhaite utiliser Android DatePicker pour obtenir une date de l'utilisateur et définir la valeur d'une entrée dans la page dans la WebView.

Le DatePickerDialog s'ouvre lorsque l'utilisateur clique sur l'entrée, mais lorsque je reçois le retour de la sélection de la date, je ne peux pas exécuter la méthode loadUrl pour définir la valeur dans l'entrée, cela me donne une erreur et les crashs de l'application.

Un peu de code (c'est un code de test, alors ne me dérange pas si c'est un peu hors contexte):

La classe i fournit à la WebView:

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

Fonction Javascript sur la page, appelée sur le clic de l'entrée:

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

Auditeur pour la sélection de la date

 private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { mWebView.loadUrl("javascript:setReturnDate();"); } }; 

Fonction Javascript qui définit une valeur sur l'entrée

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

Des idées?

Merci d'avance.

Merci @CommonsWare pour le commentaire, j'ai suivi l'erreur et obtenu ceci:

"Android.view.ViewRoot $ CalledFromWrongThreadException: Seul le thread original qui a créé une hiérarchie de vue peut toucher ses vues."

Googlé et a obtenu ce fil de discussion

Ainsi, afin de mettre à jour une vue dans l'interface utilisateur à l'exécution et à l'extérieur de son thread, vous devez utiliser un gestionnaire, recevoir des messages et exécuter des actions en conséquence.

J'ai donc mis en place un gestionnaire pour l'activité, qui reçoit un message avec un identifiant int et les données que je souhaite mettre à jour dans la visualisation web:

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

J'ai dû changer la méthode openDatePicker de la classe pour utiliser le gestionnaire, ainsi que créer un paramètre d'entrée, qui est l'identifiant du contrôle dans la page:

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

Réécrit l'auditeur DatePicker pour la sélection de la date, pour obtenir les données et envoyer un message au gestionnaire:

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

Dans la page Web, les fonctions js sont sorties comme ceci:

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

Et enfin, l'entrée (TextBox) s'est formée comme suit:

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