restringir para insertar formulario fechas español calendarios calendario android datepicker crash device

android - para - DatePicker se bloquea en mi dispositivo cuando hace clic(con la aplicación personal)



insertar calendario en formulario html (7)

En base a la respuesta mreichelts , creé un gist.github.com/tobiasschuerg/5dd116e1e0bb874038d84fd98cc333c3 que envuelve a DatePickerDialog y corrige automáticamente el contexto para android 5.0 y 5.1.

Ver gist.github.com/tobiasschuerg/5dd116e1e0bb874038d84fd98cc333c3

Editar: comprobé que el problema solo aparece cuando el teléfono está configurado con el idioma "francés".

Actualmente estoy compilando mi propia aplicación y tengo un problema cuando uso el widget DatePicker en mi teléfono (teléfono con modo de depuración: Samsung S5).

El conjunto de errores es: java.util.IllegalFormatConversionException

Agrego más detalles sobre el problema reunido en logcat:

02-20 10:37:18.255 13029-13029/avappmobile.mytasks E/AndroidRuntime﹕ FATAL EXCEPTION: main Process: avappmobile.mytasks, PID: 13029 java.util.IllegalFormatConversionException: %d can''t format java.lang.String arguments at java.util.Formatter.badArgumentType(Formatter.java:1489) at java.util.Formatter.transformFromInteger(Formatter.java:1689) at java.util.Formatter.transform(Formatter.java:1461) at java.util.Formatter.doFormat(Formatter.java:1081) at java.util.Formatter.format(Formatter.java:1042) at java.util.Formatter.format(Formatter.java:1011) at java.lang.String.format(String.java:1803) at android.content.res.Resources.getString(Resources.java:1453) at android.content.Context.getString(Context.java:397) at android.widget.SimpleMonthView$MonthViewTouchHelper.getItemDescription(SimpleMonthView.java:684) at android.widget.SimpleMonthView$MonthViewTouchHelper.onPopulateNodeForVirtualView(SimpleMonthView.java:628) at com.android.internal.widget.ExploreByTouchHelper.createNodeForChild(ExploreByTouchHelper.java:377) at com.android.internal.widget.ExploreByTouchHelper.createNode(ExploreByTouchHelper.java:316) at com.android.internal.widget.ExploreByTouchHelper.access$100(ExploreByTouchHelper.java:50) at com.android.internal.widget.ExploreByTouchHelper$ExploreByTouchNodeProvider.createAccessibilityNodeInfo(ExploreByTouchHelper.java:711) at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfVirtualNode(AccessibilityInteractionController.java:1179) at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfRealNode(AccessibilityInteractionController.java:1091) at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfRealNode(AccessibilityInteractionController.java:1087) at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfRealNode(AccessibilityInteractionController.java:1087) at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfRealNode(AccessibilityInteractionController.java:1087) at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfRealNode(AccessibilityInteractionController.java:1087) at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfRealNode(AccessibilityInteractionController.java:1087) at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfRealNode(AccessibilityInteractionController.java:1087) at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfRealNode(AccessibilityInteractionController.java:1087) at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfRealNode(AccessibilityInteractionController.java:1087) at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchDescendantsOfRealNode(AccessibilityInteractionController.java:1087) at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchAccessibilityNodeInfos(AccessibilityInteractionController.java:888) at android.view.AccessibilityInteractionController.findAccessibilityNodeInfoByAccessibilityIdUiThread(AccessibilityInteractionController.java:155) at android.view.AccessibilityInteractionController.access$400(AccessibilityInteractionController.java:53) at android.view.AccessibilityInteractionController$PrivateHandler.handleMessage(AccessibilityInteractionController.java:1236) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:145) at android.app.ActivityThread.main(ActivityThread.java:5834) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)

Aquí está mi código DialogFragment:

public class DatePFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener { DatePicker dp; OnDatePickedListener mCallback; Integer mLayoutId = null; // Interface definition public interface OnDatePickedListener { public void onDatePicked(int textId, int year, int month, int day); } // make sure the Activity implement the OnDatePickedListener public void onAttach(Activity activity) { super.onAttach(activity); try { mCallback = (OnDatePickedListener)activity; } catch (final ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnDatePickedListener"); } } @Override public Dialog onCreateDialog(Bundle savedInstanceState){ mCallback = (OnDatePickedListener)getActivity(); Calendar cal = Calendar.getInstance(); Bundle bundle = this.getArguments(); mLayoutId = bundle.getInt("layoutId"); int year = cal.get(Calendar.YEAR); int month = cal.get(Calendar.MONTH); int day = cal.get(Calendar.DAY_OF_MONTH); View view = getActivity().getLayoutInflater().inflate(R.layout.datepfragment, null); dp = (DatePicker) view.findViewById(R.id.datePicker); // Create a new instance of DatePickerDialog and return it return new DatePickerDialog(getActivity(),this,year, month, day); } @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { if (mCallback != null) { // Use the date chosen by the user. mCallback.onDatePicked(mLayoutId, year, monthOfYear+1, dayOfMonth); } } }

Y aquí está el diseño xml asociado:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/txtDPTitle" android:id="@+id/txtDPTitle" android:layout_gravity="center_horizontal" android:gravity="center" android:layout_alignParentTop="true" android:layout_alignParentStart="true" android:layout_marginTop="35dp" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/btnDPValidate" android:id="@+id/btnDPValidate" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="35dp" /> <DatePicker android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/datePicker" android:layout_gravity="center_horizontal" android:layout_marginLeft="0dp" android:datePickerMode="spinner" android:calendarViewShown="false" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> </RelativeLayout>

El hecho es que tuve dos tipos de problemas (que conducen al bloqueo de la aplicación de todos modos):

  1. Cuando ingreso mi aplicación y voy directamente al widget DatePicker, el calendario se muestra correctamente y, tan pronto como selecciono un día (digo un día, porque no hay problemas para cambiar el año, por ejemplo), la aplicación se cuelga.
  2. Si voy a otra función, haga clic para mostrar DatePicker, se bloquea directamente.

Vi otros hilos como: Accidente de DatePicker en Samsung con Android 5.0

En este hilo no recibo suficiente información, ya que la solución dada permite mostrar solo la vista de giro del calendario y, además, la flecha que se muestra no está centrada y presentada como mía (colocada directamente en la parte superior de la pantalla).

Si necesita más detalles, pregúnteme.

Gracias. Alex.


Encuentro una solución, jugando con la configuración y las variables Locale.

Yo simplemente modificaré el idioma si detecto que es un idioma francés ("fr") y lo reemplazo por un idioma inglés ("en"), luego lo volveré a configurar una vez fuera del DialogFragment de DatePicker.

public void showDatePickerDialog(int layoutId) { Integer year = cal.get(Calendar.YEAR); Integer month = cal.get(Calendar.MONTH); Integer day = cal.get(Calendar.DAY_OF_MONTH); // Due to an issue with DatePicker and fr language (locale), if locale language is french, this is changed to us to make the DatePicker working if(Locale.getDefault().getLanguage().toString().equals(FR_LANG_CONTEXT)){ Configuration config = new Configuration(); config.locale = new Locale(US_LANG_CONTEXT); getApplicationContext().getResources().updateConfiguration(config, null); } Bundle bundle = createDatePickerBundle(layoutId, year, month, day); DialogFragment newFragment = new DatePFragment(); newFragment.setArguments(bundle); newFragment.show(fm, Integer.toString(layoutId)); }

Y una vez que estoy fuera

@Override public void onDatePicked(int LayoutId, int year, int month, int day){ // Once out from the DatePicker, if we were working on a fr language, we update back the configuration with fr language. if(Locale.getDefault().getLanguage().toString().equals(FR_LANG_CONTEXT)){ Configuration config = new Configuration(); config.locale = new Locale(FR_LANG_CONTEXT); getApplicationContext().getResources().updateConfiguration(config, null); } String date = day + "/" + month + "/" + year; txtTaskDate.setText(date); }


Es un error de Samsung en su implementación de IU Lollipop. Afecta a Galaxy S4, S5, Note 3 y probablemente a más dispositivos. Para nosotros ocurre en los lenguajes de_DE y de_AT, pero parece ser un problema que afecta a varios idiomas.

Lo arreglé forzando a los dispositivos de Samsung a usar el tema Holo para el selector de fecha. En nuestro DatePickerFragment:

@NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { /* calendar code here */ Context context = getActivity(); if (isBrokenSamsungDevice()) { context = new ContextThemeWrapper(getActivity(), android.R.style.Theme_Holo_Light_Dialog); } return new DatePickerDialog(context, this, year, month, day); } private static boolean isBrokenSamsungDevice() { return (Build.MANUFACTURER.equalsIgnoreCase("samsung") && isBetweenAndroidVersions( Build.VERSION_CODES.LOLLIPOP, Build.VERSION_CODES.LOLLIPOP_MR1)); } private static boolean isBetweenAndroidVersions(int min, int max) { return Build.VERSION.SDK_INT >= min && Build.VERSION.SDK_INT <= max; }

Gracias a Samsung, sus usuarios no obtendrán el buen selector de fecha diseñado por materiales.


Observé un problema menor con la solución de @ mreichelt. El cuadro de diálogo se representó sin que el título mostrara la fecha actualmente seleccionada (incluido el día de la semana). Configurar explícitamente el título y volver a establecer la fecha de inmediato resolvió ese problema para mí.

Context context = getActivity(); if (isBrokenSamsungDevice()) { context = new ContextThemeWrapper(getActivity(), android.R.style.Theme_Holo_Light_Dialog); } DatePickerDialog datePickerDialog = new DatePickerDialog(context, this, year, month, day); if (isBrokenSamsungDevice()) { datePickerDialog.setTitle(""); datePickerDialog.updateDate(year, month, day); } return datePickerDialog;


Olvídate del selector de fechas incorporado. En mi humilde opinión cambiar la configuración regional no es una solución, porque quiero tener el selector en la configuración regional actual. Solo hay una forma de deshacerse del bloqueo: use una biblioteca que proporcione una implementación independiente.

Para un fragmento de selector de fecha: https://github.com/flavienlaurent/datetimepicker

Para un widget selector de fecha: https://github.com/SingleCycleKing/CustomTimePicker (esto es más un punto de partida que una solución lista para usar)


Tengo un posible PARCHE DE ARREGLO que permitirá que el usuario continúe usando la biblioteca de Lollipop.

Solo pude reproducir el bloqueo activando TalkBack en un S4 con Android 5.0.1 en francés, parece que Samsung está pasando toda la fecha a la cadena de selección de elementos utilizada para la accesibilidad en lugar del número del día.

Basándonos en la solución de @mreichelt para envolver el contexto, podemos anular la función getString (id, args) y solucionar el problema.

context = new ContextWrapper(getActivity()) { private Resources wrappedResources; @Override public Resources getResources() { Resources r = super.getResources(); if(wrappedResources == null) { wrappedResources = new Resources(r.getAssets(), r.getDisplayMetrics(), r.getConfiguration()) { @NonNull @Override public String getString(int id, Object... formatArgs) throws NotFoundException { try { return super.getString(id, formatArgs); } catch (IllegalFormatConversionException ifce) { Log.e("DatePickerDialogFix", "IllegalFormatConversionException Fixed!", ifce); String template = super.getString(id); template = template.replaceAll("%" + ifce.getConversion(), "%s"); return String.format(getConfiguration().locale, template, formatArgs); } } }; } return wrappedResources; } };

Entonces, si proporcionamos este contexto al constructor DatePickerDialog, se solucionará el problema.

ACTUALIZACIÓN: Este problema también aparece en la vista web cuando las páginas contienen campos de entrada de fecha, la mejor manera que encontré que resuelve ambos problemas (diálogo y vista web) es anular la función Actividad getResources como esta:

@Override public Resources getResources() { if (wrappedResources == null) { wrappedResources = wrapResourcesFixDateDialogCrash(super.getResources()); } return wrappedResources; } public Resources wrapResourcesFixDateDialogCrash(Resources r) { return new Resources(r.getAssets(), r.getDisplayMetrics(), r.getConfiguration()) { @NonNull @Override public String getString(int id, Object... formatArgs) throws NotFoundException { try { return super.getString(id, formatArgs); } catch (IllegalFormatConversionException ifce) { Log.i("DatePickerDialogFix", "IllegalFormatConversionException Fixed!", ifce); String template = super.getString(id); template = template.replaceAll("%" + ifce.getConversion(), "%s"); return String.format(getConfiguration().locale, template, formatArgs); } } }; }

Nota: La solución incluye recursos almacenados en caché, lo que significa que si tiene eventos en la aplicación que cambian los recursos (como el cambio de idioma) de lo que podría necesitar para actualizar los recursos almacenados en caché.


esto también ocurre cuando defines programáticamente una min date más allá de la max date

datePicker.getDatePicker().setMaxDate(15000000); datePicker.getDatePicker().setMinDate(16000000);