Android 在手机上运行时出现NullPointerException(但不是在emulator上)
我想显示来自SMS收件箱和发件箱的联系人姓名列表(就像在本机消息应用程序中一样)。我想出了以下代码:Android 在手机上运行时出现NullPointerException(但不是在emulator上),android,Android,我想显示来自SMS收件箱和发件箱的联系人姓名列表(就像在本机消息应用程序中一样)。我想出了以下代码: public void onCreate(Bundle icicle) { super.onCreate(icicle); Uri messagesUri = Uri.parse("content://sms/"); Cursor cursor = getContentResolver().query(messagesUri,new String[] { "_id", "thread_id"
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);
}
这里有什么问题?我的第一个猜测是cs是空的。至于为什么它是空的,我想运营商/制造商可能已经改变了如何在您的设备上实现这一点。在不太了解这些系统如何工作的情况下,看起来您正在查询某种数据库,然后使用游标在数据上进行迭代。如果表示已更改,光标将断开。我的建议是看看是否有其他更受Google/API驱动的解决方案(而不是读取原始数据)。来自ContentResolver.query(…)的文档 光标对象,位于第一个条目之前,或null 使用ContentResolver查询数据时,必须始终检查null 也来自相同的文档 在选择参数中使用问号参数标记,例如“phone=?”,而不是显式值,以便仅因这些值不同的查询将被识别为相同的查询,以用于缓存目的 因此,不是:
Cursor cs= getContentResolver().query(uri, new String[ {PhoneLookup.DISPLAY_NAME},PhoneLookup.NUMBER+"='"+address+"'",null,null);
做:
检查
cs
本身是否有效?检查指针是否为null解决了问题,非常感谢:)关于缓存,如果我没有在查询中显式写入查询参数,如何传递查询参数?很抱歉这个愚蠢的问题,但我只是从Android开发开始:)奇怪的是,现在即使我不检查指针是否为空^^^它也能工作。使用ContentResolver访问提供者,就像OP所做的那样,是访问作为另一个应用程序的一部分发布的数据的正确方法。它始终表示为游标,即使其背后的实现决定执行其他操作。
Cursor cs= getContentResolver().query(uri, new String[ {PhoneLookup.DISPLAY_NAME},PhoneLookup.NUMBER+"='"+address+"'",null,null);
Cursor cs= getContentResolver().query(uri, new String[]{PhoneLookup.DISPLAY_NAME},PhoneLookup.NUMBER+"=?",new String[]{address},null);