2014-12-21 3 views
2

У меня возникают проблемы с этим NumberFormatException Недопустимый длинный. Лог-кошка показывает, что ошибка исходит от части метода Long.parseLong.NumberFormatException Invalid Long с календарем

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 пожалуйста?

Edit: Вот остальная часть кода ...

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

    } 


} 

Edit 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); 
+0

невозможно знать, не зная, что p_time_in_millis есть. Попробуйте записать значение этой строки, и вы, вероятно, получите свой собственный ответ. – Bruce

+0

Привет, Bruce, исходящий из этих строк кода l_begin = getDateTimeStr (l_managedCursor.getString (l_colBegin)); l_end = getDateTimeStr (l_managedCursor.getString (l_colEnd)); мысли? – Charlie

+1

ошибка заключается в том, что строка p_time_in_millis в getDateTimestr содержит другие символы, а не только числовые, поэтому, когда u разберем строку в длинной JVM, она не найдет строку как полную числовую строку. Посмотрите этот вопрос http://stackoverflow.com/questions/21896610/why-is-this-code-throwing-numberformatexception-invalid-int?rq=1 – varun

ответ

2

Может кто-нибудь сказать мне, почему этот код работает нормально, когда я извлекаю и показываю данные в определенных календарях, а затем в других календарях на моем устройстве I получите это NumberFormatException Недопустимое?

Дата l_time = new Дата (Long.parseLong (p_time_in_millis));

ИМО. Этот код является «плохим» кодом.

Почему? Вы пытаетесь извлечь неизвестные данные из непроверенных источников

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

Почти каждый может получить доступ к календарям и сохранить то, что он, как ... К сожалению, нет никакого правила, там с помощью этого! Поэтому, делая дикое предположение, приложение использует этот столбец событий, чтобы сохранить данные в другом ожидаемом формате.

Что касается проверки l_cnt < 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! Теперь у вас будет лучший обзор того, что происходит, а также ваши плохие даты данных будут 1/1/1970 (из-за 0 временных меток) код может быть изменен в ответ, чтобы обрабатывать даты, которые не имеют ожидаемого формата ,

Некоторые идеи для обработки ошибок:

  • Сделать getDateTimeStr бросить исключение из getEvents(), которые могли бы поймать его и игнорировать событие с неожиданными данными. (Обработка логики, игнорируя то, что я не могу понять.)
  • Признайте формат p_time_in_millis в каждом конкретном случае и используйте разные типы DATE_TIME_FORMAT относительно точного формата каждого события. Okey, это требует большого расследования и все еще может потерпеть неудачу. Также вы должны добавить случай, что формат до сих пор неизвестен, поэтому, возможно, его игнорировать или использовать значение по умолчанию, чтобы не сбой.

Как правило, вы всегда стараюсь писать стабильное приложение, которое не подведет, если другое приложение сохраняет данные в другом формате (потому что он, как так или из-за собственной ошибки)

+0

Спасибо Madlymad, я новичок в этом и только программировал в течение полутора лет, так что я полностью потерялся, когда вы говорите «Почему? Вы пытаетесь получить неизвестные данные из непроверенных источников. «content: //com.android.calendar/events» и «content: // calendar/events» и yep полностью согласны с тем, что это плохой код, потому что я получил его из другого источника и попытался повторно использовать его для моего собственного приложения. Спасибо за ваш ответ, это помогло много =), это на самом деле решило мою проблему ... – Charlie

+0

Всегда примеры не обеспечивают проверки ошибок, чтобы быть более ясными, что с ними делается;) Но в реальных приложениях вам обычно приходится проверять каждый данные либо из Интернета, либо из внешней БД. – madlymad

+0

Удивительная благодарность за это .. будет помнить об этом. знак равно – Charlie

Смежные вопросы