我正在开发Android应用程序。
在我的第一个Activity
我列出的对话和对话点击中,应用会启动其他活动,其中包含对话的短信列表。
但是,在背面按下时,我得到了那个例外:
java.lang.RuntimeException: Unable to resume activity {com.example/com.example.activity.TalksActivity_}: android.database.StaleDataException: Attempted to access a cursor after it has been closed.
列出对话:
public static List<Talk> getTalks(Activity context) {
List<Talk> listTalk = new ArrayList<>();
Talk objTalk;
Cursor cur= context.getContentResolver().query(Uri.parse("content://mms-sms/conversations?simple=true"), null, null, null, null);
context.startManagingCursor(cur);
Log.w(TAG, "getTalks");
int total = cur.getCount();
if(cur.moveToFirst())
{
for (int i = 0; i < total; i++) {
objTalk = new Talk();
String snippet = cur.getString(cur.getColumnIndexOrThrow("snippet"));
if (snippet.length() > 30) {
objTalk.setSnippet(snippet.substring(0, 27)+"...");
} else {
objTalk.setSnippet(snippet);
}
Date date = DateHelper.getDate(Long.parseLong(cur.getString(1)));
objTalk.setDate(date);
objTalk.setDateString(DateHelper.formatDate(date));
String id = cur.getString(cur.getColumnIndexOrThrow("_id")).toString();
objTalk.setId(id);
String recipientId = cur.getString(cur.getColumnIndexOrThrow("recipient_ids")).toString();
Cursor c2= context.getContentResolver().query(Uri.parse("content://mms-sms/canonical-addresses"), null, "_id = " + recipientId, null, null);
context.startManagingCursor(c2);
if(c2.moveToFirst())
{
String phoneNumber = c2.getString(1);
objTalk.setContact(getContact(context, phoneNumber));
listTalk.add(objTalk);
}
c2.close();
cur.moveToNext();
}
}
cur.close();
return listTalk;
}
列出短信:
public static Contact getContact(Activity context, String phoneNumber) {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
String name;
long id;
Contact contact = new Contact();
ContentResolver contentResolver = context.getContentResolver();
Cursor contactLookup = contentResolver.query(uri, new String[] {ContactsContract.PhoneLookup._ID,
ContactsContract.PhoneLookup.DISPLAY_NAME, ContactsContract.PhoneLookup.PHOTO_FILE_ID }, null, null, null);
try {
if (contactLookup != null && contactLookup.getCount() > 0) {
contactLookup.moveToNext();
name = contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
id = contactLookup.getLong(contactLookup.getColumnIndex(ContactsContract.PhoneLookup._ID));
contact.setId(id);
contact.setName(name);
}
else
{
contact.setId(-1);
contact.setName(phoneNumber);
}
} finally {
if (contactLookup != null) {
contactLookup.close();
}
}
return contact;
}
public static List<Sms> getAllSms(Activity context, String talkId) {
List<Sms> receivedSmsList = getSmsList(context, "content://sms/inbox", talkId, false);
List<Sms> sentSmsList = getSmsList(context,"content://sms/sent", talkId, true);
List<Sms> allSms = new ArrayList<>();
allSms.addAll(receivedSmsList);
allSms.addAll(sentSmsList);
Collections.sort(allSms);
return allSms;
}
private static List<Sms> getSmsList(Activity context, String uri, String talkId, boolean isSent) {
List<Sms> smsList = new ArrayList<>();
Sms objSms;
Log.w(TAG, "getSmsList talkId="+talkId);
ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(Uri.parse(uri), null, "thread_id="+talkId, null, null);
context.startManagingCursor(c);
if (c == null || c.getCount() == 0) {
c.close();
Log.w(TAG, "getSmsList cursor is null");
return new ArrayList<>();
}
int totalSMS = c.getCount();
if (c.moveToFirst()) {
for (int i = 0; i < totalSMS; i++) {
Log.w(TAG, i+" -> getSmsList sms id="+c.getString(c.getColumnIndexOrThrow("_id"))+" msg="+c.getString(c.getColumnIndexOrThrow("body")));
objSms = new Sms();
objSms.setId(c.getString(c.getColumnIndexOrThrow("_id")));
objSms.setAddress(c.getString(c.getColumnIndexOrThrow("address")));
objSms.setMsg(c.getString(c.getColumnIndexOrThrow("body")));
objSms.setSent(isSent);
Date date = DateHelper.getDate(Long.parseLong(c.getString(c.getColumnIndexOrThrow("date"))));
objSms.setDate(date);
objSms.setDateString(DateHelper.formatDate(date));
smsList.add(objSms);
c.moveToNext();
}
}
c.close();
return smsList;
}
修改
对话活动代码(短信活动相同):
public class ConversationsActivity extends AppCompatActivity {
@AfterViews
void afterViews() {
// [...init adapter...]
mAdapter.addAll(SmsHelper.getTalks(this));
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
mRecyclerView.setAdapter(mAdapter);
}
编辑2
如果我没有在游标上调用.close()
,它就不会崩溃!
但......难道不是太老了吗?