2012-03-29 3 views
0

Я хочу отобразить список имен контактов из входящих и исходящих сообщений SMS (например, в приложении для обмена сообщениями). Я придумал следующий код:NullPointerException при работе на телефоне (но не на эмуляторе)

public void onCreate(Bundle icicle) { 

super.onCreate(icicle); 

Uri messagesUri = Uri.parse("content://sms/"); 
Cursor cursor = getContentResolver().query(messagesUri,new String[] { "_id", "thread_id", "address", "person", "date", "body", "type" }, null, null, null); 
startManagingCursor(cursor); 
String[] columns = new String[] { "address", "person", "date", "body", "type" }; 
String sms = ""; 
if (cursor.getCount() > 0) { 
    while (cursor.moveToNext()){ 
     String address = cursor.getString(cursor.getColumnIndex(columns[0])); 
     sms += address + " "; 
     String contact=address; 
     Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address)); 
     Cursor cs= getContentResolver().query(uri, new String[]{PhoneLookup.DISPLAY_NAME},PhoneLookup.NUMBER+"='"+address+"'",null,null); 
     startManagingCursor(cs); 
     if(cs.getCount()>0) 
     { 
     cs.moveToFirst(); 
     contact=cs.getString(cs.getColumnIndex(PhoneLookup.DISPLAY_NAME)); 
     } 
     listItems.add(contact); 
    } 
} 
adapter=new ArrayAdapter<String>(this, 
    android.R.layout.simple_list_item_1, 
    listItems); 
setListAdapter(adapter); 
} 

Это работает, когда я запустить приложение в эмуляторе, но когда я пытаюсь запустить его на телефоне я получаю NullPointerException. Если я дважды щелкните на сообщении об ошибке в LogCat следующая строка подсвечивается:

if(cs.getCount()>0) 

Что здесь проблема?

+0

Проверьте 'cs' сам по себе является действительным? – Mahesh

+0

Как мне это сделать? – user1301428

ответ

1

Из документации ContentResolver.query (...)

объекта Cursor, который расположен перед первой записью, или нуля

Вы всегда должны проверить на нуль при использовании ContentResolver для запроса данных.

Также из той же документации.

Использовать маркеры параметров вопроса, такие как 'phone =?' вместо явных значений в параметре выбора, так что запросы, которые отличаются только этими значениями, будут признаны одинаковыми для целей кеширования.

Таким образом, вместо:

Cursor cs= getContentResolver().query(uri, new String[ {PhoneLookup.DISPLAY_NAME},PhoneLookup.NUMBER+"='"+address+"'",null,null); 

Do:

Cursor cs= getContentResolver().query(uri, new String[]{PhoneLookup.DISPLAY_NAME},PhoneLookup.NUMBER+"=?",new String[]{address},null); 
+0

Проверка того, был ли указатель нулевым, проблема, спасибо большое :) О кэшировании сейчас, как я могу передать параметр запроса, если я явно не пишу его в запросе? Извините за глупый вопрос, но я только начинаю с разработки Android :) – user1301428

+0

Странно, теперь он работает, даже если я не проверю, не указана ли указатель не на уровне ^^ – user1301428

0

Мое первое предположение было бы то, что cs имеет значение null. Что касается того, почему это null, я полагаю, что оператор/производитель мог изменить, как это реализовано на вашем устройстве. Не зная слишком много о том, как работают эти системы, похоже, что вы запрашиваете какую-то базу данных, а затем используете курсор для перебора данных. Если представление было изменено, курсор сломается. Мое предложение состояло бы в том, чтобы увидеть, есть ли другое решение, которое больше управляется Google/API (в отличие от чтения необработанных данных).

+0

Использование ContentResolver доступа Поставщик, как это делает OP, является правильным подходом к доступу к данным, опубликованным как часть другого приложения. Он всегда представлен как Курсор, даже если реализация за ним решает сделать что-то еще. – cistearns

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