Hacer estallar un diálogo de un hilo no perteneciente a la interfaz de usuario
Estoy desarrollando una aplicación de red, que está orientada a grupos. La cosa es que cuando estoy a punto de unirse a un grupo, primero verifica si el grupo es seguro, y si es así, pide el usuario y la contraseña. Obtener seguridad de grupo puede tardar un par de segundos, así que generar un nuevo hilo para todo el proceso. Me gustaría hacer aparecer un diálogo en caso de que el grupo requiera seguridad. Estoy pensando que puede tener que ver con los hilos de fondo, no puede ser capaz de pop-up Diálogos … Pero la cosa es que tengo que comprobar la seguridad del grupo en el hilo de fondo porque se necesita un poco de tiempo.
Espero que cualquiera pueda llegar a la solución o cualquier forma de preguntar al usuario / pasar sólo cuando el grupo está seguro. Aquí está el hilo de fondo:
- Phonegap no muestra la alerta
- ¿Cuál es la mejor manera de tener cuadros de diálogo reutilizables?
- Diálogo con vista de lista y mensaje
- Android: ¿Presentar una notificación durante una llamada?
- establecer 2 alertas de proximidad con la misma emisión
public void run() { secInf = mGroupId.getSecurityInformation(); if (secInf.getAdmissionLevel() == CreateGroupDialog.PRIVATE_KEY_ACCESS) { showUserPasswordDialog(); } else { mService.joinGroup(mGroupId); // Notifies handler to dismiss ProgresDialog and start activity mHandler.sendMessage(Message.obtain(mHandler, GroupsActivity.JOIN_SUCCESSFUL)); }
Donde showUserPasswordDialog hace (mActivity es la actividad que generó este hilo):
private void showUserPasswordDialog() { AlertDialog dialog; // add this to your code // This example shows how to add a custom layout to an AlertDialog LayoutInflater factory = LayoutInflater.from(mActivity); final View textEntryView = factory.inflate( R.layout.alert_dialog_text_entry, null); AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); builder.setIcon(R.drawable.alert_dialog_icon); builder.setTitle(R.string.ask_user_password); builder.setView(textEntryView); builder.setPositiveButton(R.string.ok_text, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { String userName = ((EditText) mActivity .findViewById(R.id.username_edit_alert_dialog)) .getText().toString(); String password = ((EditText) mActivity .findViewById(R.id.password_edit_alert_dialog)) .getText().toString(); Credentials cred = new CredentialsL1(userName, password); mSmeppService.joinGroup(mGroupId, cred); mHandler.sendMessage(Message.obtain(mHandler, GroupsActivity.JOIN_SUCCESSFUL)); }); builder.setNegativeButton(R.string.cancel_text, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dialog.cancel(); mHandler.sendMessage(Message.obtain(mHandler, GroupsActivity.DISMISS_PROGRESS_DIALOG)); } }); dialog = builder.create(); /* I found this somewhere, but didn't work either */ // Window window = dialog.getWindow(); // WindowManager.LayoutParams lp = window.getAttributes(); // lp.token = textEntryView.getWindowToken(); // lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; // window.setAttributes(lp); // window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); dialog.show(); }
Estoy recibiendo esta excepción:
12-13 19:18:31.823: ERROR/AndroidRuntime(1702): FATAL EXCEPTION: Thread-38 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): android.view.InflateException: Binary XML file line #17: Error inflating class android.widget.EditText 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.createView(LayoutInflater.java:513) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.rInflate(LayoutInflater.java:618) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.inflate(LayoutInflater.java:407) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.inflate(LayoutInflater.java:276) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at org.pfc.threads.GroupJoinerThread.showUserPasswordDialog(GroupJoinerThread.java:76) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at org.pfc.threads.GroupJoinerThread.run(GroupJoinerThread.java:52) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): Caused by: java.lang.reflect.InvocationTargetException 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.widget.EditText.<init>(EditText.java:51) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at java.lang.reflect.Constructor.constructNative(Native Method) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at java.lang.reflect.Constructor.newInstance(Constructor.java:446) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.view.LayoutInflater.createView(LayoutInflater.java:500) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): ... 8 more 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.os.Handler.<init>(Handler.java:121) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.text.method.MetaKeyKeyListener$MetaKeyDropbackHandler.<init>(MetaKeyKeyListener.java:605) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.text.method.MetaKeyKeyListener.<init>(MetaKeyKeyListener.java:96) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.text.method.BaseKeyListener.<init>(BaseKeyListener.java:25) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.text.method.TextKeyListener.<init>(TextKeyListener.java:66) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.text.method.TextKeyListener.getInstance(TextKeyListener.java:83) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.widget.TextView.<init>(TextView.java:806) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): at android.widget.EditText.<init>(EditText.java:55) 12-13 19:18:31.823: ERROR/AndroidRuntime(1702): ... 12 more
El archivo de diseño XML es:
<EditText android:id="@+id/username_edit_alert_dialog" android:enabled="false" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_marginLeft="20dip" android:layout_marginRight="20dip" android:scrollHorizontally="true" android:autoText="false" android:capitalize="none" android:gravity="fill_horizontal" android:textAppearance="?android:attr/textAppearanceMedium" /> <!-- Password --> <TextView android:id="@+id/password_view" android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_marginLeft="20dip" android:layout_marginRight="20dip" android:text="@string/password_view_text" android:gravity="left" android:textAppearance="?android:attr/textAppearanceMedium" /> <EditText android:id="@+id/password_edit_alert_dialog" android:enabled="false" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_marginLeft="20dip" android:layout_marginRight="20dip" android:scrollHorizontally="true" android:autoText="false" android:capitalize="none" android:gravity="fill_horizontal" android:password="true" android:textAppearance="?android:attr/textAppearanceMedium" />
- En Android, ¿cómo mostrar el diálogo de alerta con esquinas cuadradas como en Google Maps?
- AlertDialog no muestra dos botones
- ¿Es posible hacer un botón en un AlertDialog que no cierre automáticamente el diálogo?
- El tema del diálogo Android hace que el icono sea demasiado claro
- Cómo llamar a constantes en java?
- AlertDialog.Builder abre otro AlertDialog.Builder
- ¿Cuál es la diferencia entre AlertDialog.builder.setView y Dialog.setContentView?
- Tema de AlertDialog
Está correcto que no puede realizar operaciones de interfaz de usuario desde un subproceso de fondo. La forma de hacerlo es usar el Handler
que ya ha implementado para abrir el diálogo. Así que algo como:
private Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch(msg.what){ case GroupsActivity.DISMISS_PROGRESS_DIALOG: //your existing dismiss code break; case GroupsActivity.CREATE_PROGRESS_DIALOG: //create the dialog break; } } };
Entonces su método de ejecución sería:
public void run() { secInf = mGroupId.getSecurityInformation(); if (secInf.getAdmissionLevel() == CreateGroupDialog.PRIVATE_KEY_ACCESS) { // do stuff mHandler.sendMessage(Message.obtain(mHandler, GroupsActivity.CREATE_PROGRESS_DIALOG)); // do more stuff } else { mService.joinGroup(mGroupId); // Notifies handler to dismiss ProgresDialog and start activity mHandler.sendMessage(Message.obtain(mHandler, GroupsActivity.JOIN_SUCCESSFUL)); } }
Estás en lo correcto. Los subprocesos de fondo no pueden mostrar diálogos. Lo que necesitas es un Handler
en tu interfaz de usuario para que aparezca el diálogo para ti.
- Error al instalar los complementos de ADT en Eclipse
- Cómo descodificar la cadena base64 y convertirla en pdf / jpg y guardarla en almacenamiento