NumberFormatException与日历无效

时间:2014-12-21 05:13:27

标签: android exception calendar numberformatexception

我遇到此NumberFormatException无效的问题。日志cat显示错误来自方法的Long.parseLong部分。

  public static String getDateTimeStr(String p_time_in_millis) {
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);
    Date l_time = new Date(Long.parseLong(p_time_in_millis));
    return sdf.format(l_time);
}

有人可以告诉我为什么当我在某些日历中获取并显示数据时,此代码正常工作,然后在我的设备上的其他日历中,我得到这个NumberFormatException Invalid Long吗?

修改:以下是代码的其余部分......

private void getEvents() {

    Uri l_eventUri;
    ArrayList<Map<String, String>> allStudents = new ArrayList<Map<String, String>>();

    if (Build.VERSION.SDK_INT >= 8) {
        l_eventUri = Uri.parse("content://com.android.calendar/events");
    } else {
        l_eventUri = Uri.parse("content://calendar/events");
    }

    String[] l_projection = new String[]{"title", "dtstart", "dtend"};

    @SuppressWarnings("deprecation")
    Cursor l_managedCursor = this.managedQuery(l_eventUri, l_projection, "calendar_id=" + m_selectedCalendarId, null, "dtstart DESC, dtend DESC");

    if (l_managedCursor.moveToFirst()) {


        int l_colTitle = l_managedCursor.getColumnIndex(l_projection[0]);
        int l_colBegin = l_managedCursor.getColumnIndex(l_projection[1]);
        int l_colEnd = l_managedCursor.getColumnIndex(l_projection[2]);

        String l_title = String.valueOf(l_colTitle);
        String l_begin = Integer.toString(l_colBegin);
        String l_end = Integer.toString(l_colEnd);

        do {

            Map<String, String> map = new HashMap<String, String>();    

            l_title = l_managedCursor.getString(l_colTitle);
            l_begin = getDateTimeStr(l_managedCursor.getString(l_colBegin));
            l_end = getDateTimeStr(l_managedCursor.getString(l_colEnd));

            map.put("eventTitles", l_title);
            map.put("event_begin", l_begin);
            map.put("event_end", l_end);
            allStudents.add(map);


        } while (l_managedCursor.moveToNext());

        l_managedCursor.close();

        SimpleAdapter adapter = new SimpleAdapter(this, allStudents, R.layout.notice_layout, new String[] { "eventTitles", "event_begin", "event_end" }, new int[] { R.id.tvTitle, R.id.tvBody, R.id.tvTeacherCode}); 
        listViewCalendar.setAdapter(adapter);

    }


}

编辑2:

由于某种原因,代码在没有这行代码的情况下工作正常,所以我把它钉在了这行代码上。

l_end = getDateTimeStr(l_managedCursor.getString(l_colEnd));

为什么l_colEnd会被NumberFormatExcetion追上?当以下代码行也可以在同一个NumberFormatException中捕获时,因为它询问相同的int格式?

l_begin = getDateTimeStr(l_managedCursor.getString(l_colBegin));

也感谢所有帮助过的人。另一个有趣的事情是我添加这个

int l_cnt = 0;
do {
   ++l_cnt;
} while (l_managedCursor.moveToNext() && l_cnt < 100);

while子句,如下面代码末尾所示,应用程序运行良好,没有代码行抛出NumberFormatException ..

if (l_managedCursor.moveToFirst()) {

        int l_cnt = 0;

        int l_colTitle = l_managedCursor.getColumnIndex(l_projection[0]);
        int l_colBegin = l_managedCursor.getColumnIndex(l_projection[1]);
        int l_colEnd = l_managedCursor.getColumnIndex(l_projection[2]);

        String l_title = String.valueOf(l_colTitle);
        String l_begin = Integer.toString(l_colBegin);
        String l_end = Integer.toString(l_colEnd);

        do {

            Map<String, String> map = new HashMap<String, String>();    

            l_title = l_managedCursor.getString(l_colTitle);
            l_begin = getDateTimeStr(l_managedCursor.getString(l_colBegin));
            l_end = getDateTimeStr(l_managedCursor.getString(l_colEnd));

            map.put("eventTitles", l_title);
            map.put("event_begin", l_begin);
            map.put("event_end", l_end);
            allStudents.add(map);

            ++l_cnt;

        } while (l_managedCursor.moveToNext() && l_cnt < 100);

1 个答案:

答案 0 :(得分:2)

  

有人可以告诉我为什么这个代码在我获取和显示时工作正常   某些日历中的数据,然后是我设备上的其他日历   得到这个NumberFormatException无效长吗?

     

日期l_time =新日期(Long.parseLong(p_time_in_millis));

IMO。这段代码是“坏”代码。

为什么呢?您尝试从未经检查的来源获取未知数据

"content://com.android.calendar/events""content://calendar/events"

几乎每个人都可以访问日历并保存他喜欢的任何东西......可悲的是,没有任何规则可以使用它!因此,猜测一个应用程序正在使用此事件列将数据保存到另一个预期格式的数据中。

  

关于检查l_cnt&lt; 100,失败停止

它没有失败,因为错误发生在101事件或更晚的事件中!


我的解决方案是检查我的数据,并且永远不要相信其他应用会按照我的预期或应有的方式行事。

所以我建议按如下方式更改getDateTimeStr方法:

   public static String getDateTimeStr(String p_time_in_millis) {
      SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);
      long timestamp = 0;
      try {
         timestamp = Long.parseLong(p_time_in_millis)
      } catch(NumberFormatException e) {
         Log.w("getDateTimeStr", "Cannot convert '"+p_time_in_millis+"' to long");
         e.printStackTrace(); // Prints full error exception
      }
      Date l_time = new Date(timestamp);
      return sdf.format(l_time);
   }

删除l_cnt < 100检查并保留代码以运行检查logcat!您现在可以更好地了解正在发生的事情,并且您的错误数据日期将是1970年1月1日(由于0时间戳)代码可以响应地更改以便处理那些日期没有预期的格式。

处理错误的一些想法:

  • getDateTimeStrgetEvents()抛出一个可以捕获它的异常,并忽略具有意外数据的事件。 (处理逻辑,忽略我无法理解的东西。)
  • 在每种不同的情况下识别p_time_in_millis的格式,并针对每个事件的确切格式使用不同的DATE_TIME_FORMAT类型。哦,这需要大量调查,但仍然可能失败。此外,您必须添加格式仍然未知的情况,因此可能会忽略它或使用默认值以免崩溃。

一般情况下,如果另一个应用程序以不同的格式保存数据(因为它是这样或由于其自身的错误),您总是尝试编写一个不会失败的稳定应用程序