3

I got this crash report in Crashlytics:

SimpleMonthView.java line 684
android.widget.SimpleMonthView$MonthViewTouchHelper.getItemDescription
-----
Fatal Exception: java.util.IllegalFormatConversionException
%d can't format java.lang.String arguments

I've seen This Post but I couldn't do it in my custom class.

It's a Samsung bug in their Lollipop UI implementation. It affects Galaxy S4, S5, Note 3 and probably more devices.

I've seen This Post, too, but you can see that I've already set year range in newInstance static method.

This is My Custom DatePicker Class which is copied from Here:

public class MyDatePickerDialog extends DialogFragment implements OnClickListener {

private static final String TAG = "DatePickerDialog";
public static LinearLayout dayMonth;
public static int maxMonth;
static int minYear;
static int maxYear;
static int id;
private static TextView dayTV;
private static TextView monthTV;
private static TextView yearTV;
private static TextView dayNameTV;
private static int mColor = 0;
private static GradientDrawable circle;
private static Typeface mTypeFace = null;
private static OnDateSetListener mCallBack;
private TextView doneTV;
private TextView cancelTV;
FragmentManager fragmentManager;

public MyDatePickerDialog() {

}

public static MyDatePickerDialog newInstance(OnDateSetListener onDateSetListener, int requestID) {

    JDF jdf = new JDF();
    return newInstance(onDateSetListener, requestID, jdf.getIranianYear(), jdf.getIranianMonth(), jdf.getIranianDay());
}

public static MyDatePickerDialog newInstance(OnDateSetListener onDateSetListener, boolean darkTheme) {
    return newInstance(onDateSetListener, 0);
}

public static MyDatePickerDialog newInstance(OnDateSetListener onDateSetListener) {
    return newInstance(onDateSetListener, 0);
}

public static MyDatePickerDialog newInstance(OnDateSetListener onDateSetListener, int requestID, int year, int month, int day) {

    MyDatePickerDialog datePickerDialog = new MyDatePickerDialog();

    mCallBack = onDateSetListener;
    Date.setDate(year, month, day, false);

    int thisYear = new JDF().getIranianYear();
    datePickerDialog.setYearRange(thisYear, thisYear + 1);

    id = requestID;
    mColor = 0;
    mTypeFace = null;
    maxMonth = 0;

    return datePickerDialog;
}

public static void updateDisplay(int year, int month, int day) {
    try {
        MyDatePickerDialog.dayTV.setText(String.valueOf(day));
        MyDatePickerDialog.monthTV.setText(JDF.monthNames[month - 1]);
        MyDatePickerDialog.yearTV.setText(String.valueOf(year));
        MyDatePickerDialog.dayNameTV.setText(new JDF().getIranianDayName(year, month, day));
    } catch (Exception e) {
        Log.i(TAG, "updateDisplay -----> " + e);
    }
}

@Override
public void onStart() {
    setRetainInstance(true);
    super.onStart();
}

@Override
public int getTheme() {
    return super.getTheme();
}

private android.app.DatePickerDialog.OnDateSetListener dateSetListener() {
    return new android.app.DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker datePicker, int i, int i1, int i2) {

        }
    };
}

@Override
public View onCreateView(LayoutInflater layoutInflater,
                         ViewGroup container, Bundle savedInstanceState) {

    getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);

    final View view = layoutInflater.inflate(R.layout.date_layout,
            container, false);

    if (mColor == 0)
        try {
            mColor = getResources().getColor(R.color.blue);
        } catch (Resources.NotFoundException e) {
            //Sentry MyLog.w(TAG, new Throwable().getStackTrace()[0].getLineNumber(), e);
            e.printStackTrace();
        }

    circle = new GradientDrawable();
    try {
        circle.setCornerRadius(getResources().getDimension(
                R.dimen.circle_radius));
        circle.setColor(mColor);
        circle.setAlpha(50);
    } catch (Resources.NotFoundException e) {
        e.printStackTrace();
    }

    fragmentManager = getChildFragmentManager();

    dayTV = view.findViewById(R.id.day);
    monthTV = view.findViewById(R.id.month);
    yearTV = view.findViewById(R.id.year);
    dayNameTV = view.findViewById(R.id.day_name);
    doneTV = view.findViewById(R.id.done);
    cancelTV = view.findViewById(R.id.cancel);
    dayMonth = view.findViewById(R.id.dayMonthBack);

    if (mTypeFace != null) {
        dayTV.setTypeface(mTypeFace);
        monthTV.setTypeface(mTypeFace);
        yearTV.setTypeface(mTypeFace);
        dayNameTV.setTypeface(mTypeFace);
        doneTV.setTypeface(mTypeFace);
        cancelTV.setTypeface(mTypeFace);
    }

    doneTV.setTextColor(mColor);
    cancelTV.setTextColor(mColor);

    view.findViewById(R.id.blue_card)
            .setBackgroundColor(mColor);

    dayMonth.setOnClickListener(this);
    yearTV.setOnClickListener(this);
    doneTV.setOnClickListener(this);
    cancelTV.setOnClickListener(this);

    updateDisplay(Date.getYear(), Date.getMonth(), Date.getDay());

    view.findViewById(R.id.dayMonthBack).performClick();

    return view;
}

@Override
public void onClick(View v) {
    if (v.getId() == R.id.year) {
        dayTV.setAlpha(0.5f);
        monthTV.setAlpha(0.5f);
        yearTV.setAlpha(1f);
        YearMainFragment yearMainFragment = new YearMainFragment();
        switchFragment(yearMainFragment.yearMainFragement(minYear, maxYear));
    } else if (v.getId() == R.id.dayMonthBack) {
        dayTV.setAlpha(1f);
        monthTV.setAlpha(1f);
        yearTV.setAlpha(0.5f);
        switchFragment(new MonthMainFragment());
    } else if (v.getId() == R.id.done) {
        if (mCallBack != null) {
            Calendar calendar = Calendar.getInstance();
            JDF j = new JDF();
            j.setIranianDate(Date.getYear(), Date.getMonth(), Date.getDay());
            try {
                calendar = j.getGregorianCalendar(Date.getYear(),
                        Date.getMonth(), Date.getDay());
            } catch (Exception e) {
                Log.i(TAG, "-----> Exception onClosedItemClick: " + e);
            }
            mCallBack.onDateSet(id, calendar, Date.getYear(), Date.getMonth(), Date.getDay(), dayNameTV.getText().toString());
        }
        dismissAllowingStateLoss();
    } else if (v.getId() == R.id.cancel) {
        dismissAllowingStateLoss();
    }
}

void switchFragment(final Fragment fragment) {
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.replace(R.id.frame_container, fragment);
    transaction.addToBackStack(null);
    try {
        transaction.commit();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

/*  ---------- Getters & Setters ----------  */

public static GradientDrawable getCircle() {
    return circle;
}

public static int getColor() {
    return mColor;
}

public static Typeface getTypeFace() {
    return mTypeFace;
}

public void setTypeFace(Typeface typeface) {
    mTypeFace = typeface;
}

public static int getRequestID() {
    return id;
}

public void setRequestID(int requestID) {
    id = requestID;
}

public void setMainColor(int color) {
    mColor = color;
}

public void setYearRange(int _minYear, int _maxYear) {
    minYear = _minYear;
    maxYear = _maxYear;
}

public void setInitialDate(int year, int month, int day) {
    Date.setDate(year, month, day, false);
}

public void setInitialDate(Calendar calendar) {
    JDF jdf = new JDF();
    jdf.setGregorianDate(calendar.get(Calendar.YEAR),
            calendar.get(Calendar.MONTH) + 1,
            calendar.get(Calendar.DAY_OF_MONTH));
    Date.setDate(jdf.getIranianYear(), jdf.getIranianMonth(),
            jdf.getIranianDay(), false);
}

public void setFutureDisabled(Boolean disabled) {
    if (disabled) {
        JDF jdf = new JDF();
        maxMonth = jdf.getIranianMonth() - 11;
        maxYear = jdf.getIranianYear();

        if (minYear > maxYear)
            minYear = maxYear - 1;

        if (Date.getMonth() > jdf.getIranianMonth())
            Date.setMonth(jdf.getIranianMonth());
        if (Date.getDay() > jdf.getIranianDay())
            Date.setDay(jdf.getIranianDay());
        if (Date.getYear() > jdf.getIranianYear())
            Date.setYear(jdf.getIranianYear());
    } else
        maxMonth = 0;
}

/*  ---------- End of Getters & Setters ----------  */

public interface OnDateSetListener {
    void onDateSet(int id, Calendar calendar, int year,
                   int month, int day, String dayName);
}
}

How can I solve this problem?

UPDATE

StackTrace:

# OS Version: 5.1.1
# Device: Galaxy Core Prime
# RAM Free: 38.8%
# Disk Free: 12.8%

#0. Crashed: main
at java.util.Formatter.badArgumentType + 1489(Formatter.java:1489)
at java.util.Formatter.transformFromInteger + 1689(Formatter.java:1689)
at java.util.Formatter.transform + 1461(Formatter.java:1461)
at java.util.Formatter.doFormat + 1081(Formatter.java:1081)
at java.util.Formatter.format + 1042(Formatter.java:1042)
at java.util.Formatter.format + 1011(Formatter.java:1011)
at java.lang.String.format + 1803(String.java:1803)
at android.content.res.Resources.getString + 668(Resources.java:668)
at android.content.Context.getString + 390(Context.java:390)
at android.widget.SimpleMonthView$MonthViewTouchHelper.getItemDescription + 684(SimpleMonthView.java:684)
at android.widget.SimpleMonthView$MonthViewTouchHelper.onPopulateNodeForVirtualView + 628(SimpleMonthView.java:628)
at com.android.internal.widget.ExploreByTouchHelper.createNodeForChild + 397(ExploreByTouchHelper.java:397)
at com.android.internal.widget.ExploreByTouchHelper.createNode + 324(ExploreByTouchHelper.java:324)
at com.android.internal.widget.ExploreByTouchHelper.access$100 + 49(ExploreByTouchHelper.java:49)
at com.android.internal.widget.ExploreByTouchHelper$ExploreByTouchNodeProvider.createAccessibilityNodeInfo + 741(ExploreByTouchHelper.java:741)
at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchAccessibilityNodeInfos + 805(AccessibilityInteractionController.java:805)
at android.view.AccessibilityInteractionController.findAccessibilityNodeInfoByAccessibilityIdUiThread + 155(AccessibilityInteractionController.java:155)
at android.view.AccessibilityInteractionController.access$400 + 53(AccessibilityInteractionController.java:53)
at android.view.AccessibilityInteractionController$PrivateHandler.handleMessage + 1146(AccessibilityInteractionController.java:1146)
at android.os.Handler.dispatchMessage + 102(Handler.java:102)
at android.os.Looper.loop + 135(Looper.java:135)
at android.app.ActivityThread.main + 5910(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke + 372(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run + 1405(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main + 1200(ZygoteInit.java:1200)

--

Fatal Exception: java.util.IllegalFormatConversionException: %d can't format java.lang.String arguments
at java.util.Formatter.badArgumentType + 1489(Formatter.java:1489)
at java.util.Formatter.transformFromInteger + 1689(Formatter.java:1689)
at java.util.Formatter.transform + 1461(Formatter.java:1461)
at java.util.Formatter.doFormat + 1081(Formatter.java:1081)
at java.util.Formatter.format + 1042(Formatter.java:1042)
at java.util.Formatter.format + 1011(Formatter.java:1011)
at java.lang.String.format + 1803(String.java:1803)
at android.content.res.Resources.getString + 668(Resources.java:668)
at android.content.Context.getString + 390(Context.java:390)
at android.widget.SimpleMonthView$MonthViewTouchHelper.getItemDescription + 684(SimpleMonthView.java:684)
at android.widget.SimpleMonthView$MonthViewTouchHelper.onPopulateNodeForVirtualView + 628(SimpleMonthView.java:628)
at com.android.internal.widget.ExploreByTouchHelper.createNodeForChild + 397(ExploreByTouchHelper.java:397)
at com.android.internal.widget.ExploreByTouchHelper.createNode + 324(ExploreByTouchHelper.java:324)
at com.android.internal.widget.ExploreByTouchHelper.access$100 + 49(ExploreByTouchHelper.java:49)
at com.android.internal.widget.ExploreByTouchHelper$ExploreByTouchNodeProvider.createAccessibilityNodeInfo + 741(ExploreByTouchHelper.java:741)
at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchAccessibilityNodeInfos + 805(AccessibilityInteractionController.java:805)
at android.view.AccessibilityInteractionController.findAccessibilityNodeInfoByAccessibilityIdUiThread + 155(AccessibilityInteractionController.java:155)
at android.view.AccessibilityInteractionController.access$400 + 53(AccessibilityInteractionController.java:53)
at android.view.AccessibilityInteractionController$PrivateHandler.handleMessage + 1146(AccessibilityInteractionController.java:1146)
at android.os.Handler.dispatchMessage + 102(Handler.java:102)
at android.os.Looper.loop + 135(Looper.java:135)
at android.app.ActivityThread.main + 5910(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke + 372(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run + 1405(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main + 1200(ZygoteInit.java:1200)

#0. Crashed: main
at java.util.Formatter.badArgumentType + 1489(Formatter.java:1489)
at java.util.Formatter.transformFromInteger + 1689(Formatter.java:1689)
at java.util.Formatter.transform + 1461(Formatter.java:1461)
at java.util.Formatter.doFormat + 1081(Formatter.java:1081)
at java.util.Formatter.format + 1042(Formatter.java:1042)
at java.util.Formatter.format + 1011(Formatter.java:1011)
at java.lang.String.format + 1803(String.java:1803)
at android.content.res.Resources.getString + 668(Resources.java:668)
at android.content.Context.getString + 390(Context.java:390)
at android.widget.SimpleMonthView$MonthViewTouchHelper.getItemDescription + 684(SimpleMonthView.java:684)
at android.widget.SimpleMonthView$MonthViewTouchHelper.onPopulateNodeForVirtualView + 628(SimpleMonthView.java:628)
at com.android.internal.widget.ExploreByTouchHelper.createNodeForChild + 397(ExploreByTouchHelper.java:397)
at com.android.internal.widget.ExploreByTouchHelper.createNode + 324(ExploreByTouchHelper.java:324)
at com.android.internal.widget.ExploreByTouchHelper.access$100 + 49(ExploreByTouchHelper.java:49)
at com.android.internal.widget.ExploreByTouchHelper$ExploreByTouchNodeProvider.createAccessibilityNodeInfo + 741(ExploreByTouchHelper.java:741)
at android.view.AccessibilityInteractionController$AccessibilityNodePrefetcher.prefetchAccessibilityNodeInfos + 805(AccessibilityInteractionController.java:805)
at android.view.AccessibilityInteractionController.findAccessibilityNodeInfoByAccessibilityIdUiThread + 155(AccessibilityInteractionController.java:155)
at android.view.AccessibilityInteractionController.access$400 + 53(AccessibilityInteractionController.java:53)
at android.view.AccessibilityInteractionController$PrivateHandler.handleMessage + 1146(AccessibilityInteractionController.java:1146)
at android.os.Handler.dispatchMessage + 102(Handler.java:102)
at android.os.Looper.loop + 135(Looper.java:135)
at android.app.ActivityThread.main + 5910(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke + 372(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run + 1405(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main + 1200(ZygoteInit.java:1200)
Alireza Noorali
  • 3,469
  • 2
  • 23
  • 60

1 Answers1

1

There is a bug in Samsung's Lollipop implementation. This happens on some Locale if Talkback is enabled. You can fix by forcing DatePicker on Samsung devices with Holo theme.

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (isBrokenSamsungDevice())
    setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Holo_Light_Dialog);
}

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;
}
nitinkumarp
  • 1,705
  • 1
  • 19
  • 25