在光标关闭后尝试访问 - 按下后退

时间:2015-04-28 19:10:02

标签: android sms android-cursor

我正在开发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(),它就不会崩溃!

但......难道不是太老了吗?

0 个答案:

没有答案