错误:关闭后尝试访问游标?

时间:2014-04-17 11:25:38

标签: android android-listview cursor sms android-cursor

在我的应用程序中,我将inbox messages从本机应用程序提取到my application。还有复选框可以选择多条消息。但问题出现的是listview while running code中没有显示消息,也显示错误android.database.StaleDataException: Attempted to access a cursor after it has been closed.

ArrayAdapter<SMSListModel> adapter;
List<SMSListModel> list = new ArrayList<SMSListModel>();
TextView textViewSMSSender, textViewSMSBody

 public void getInboxSms() {
    //Uri message = Uri.parse("content://sms/inbox");
    ContentResolver cr = getContentResolver();
    c = cr.query(Uri.parse("content://sms/inbox"), null, null, null, null);
    //startManagingCursor(c);
     //totalSMS = c.getCount();
    if (c.moveToFirst()) {
        for (int i = 0; i < c.getCount(); i++) {

            Log.d("SMSss", "Contact number : "+ c.getString(c.getColumnIndexOrThrow("address"))+ "\n"
                            + "msg : " + c.getColumnIndexOrThrow("body")
                            + "\n"
                            + "Person : "
                            + getContactName(getApplicationContext(),c.getString(c.getColumnIndexOrThrow("address"))));
            c.moveToNext();
        }
    }
   c.close();

}

public String getContactName(Context context, String phoneNumber) {
    ContentResolver cr = context.getContentResolver();
    Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
            Uri.encode(phoneNumber));
    Cursor cursor = cr.query(uri,
            new String[] { PhoneLookup.DISPLAY_NAME }, null, null, null);
    if (cursor == null) {
        return null;
    }
    String contactName = null;
    if (cursor.moveToFirst()) {
        contactName = cursor.getString(cursor
                .getColumnIndex(PhoneLookup.DISPLAY_NAME));
    }
    if (cursor != null && !cursor.isClosed()) {
        cursor.close();
    }
    return contactName;
}
private List<SMSListModel> getModel() 
{
    if(c.getCount()>0)
    {
        for(int i=0;i<c.getCount();i++)
        {
            if(c.moveToPosition(i))
            {                   
                list.add(new SMSListModel(c.getString(c.getColumnIndex("address")),c.getString(c.getColumnIndex("body"))));

            }
        }
    }

    return list;

}

SmsListAdapter

public class SMSListAdapter extends ArrayAdapter<SMSListModel> {

private final List<SMSListModel> list;
private final Activity mContext;
boolean checkAll_flag = false;
boolean checkItem_flag = false;

public SMSListAdapter(Activity context,List<SMSListModel> list) 
{
    super(context, R.layout.listview_each_item, list);
    Log.d("size of list", ""+list.size());
    mContext = context;
    this.list = list;

}

static class ViewHolder {
    protected TextView textAddress;
    protected TextView textBody;
    protected CheckBox checkbox;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    ViewHolder viewHolder = null;
    if (convertView == null) {
        LayoutInflater inflator = mContext.getLayoutInflater();
        convertView = inflator.inflate(R.layout.listview_each_item, null);
        viewHolder = new ViewHolder();
        viewHolder.textAddress = (TextView) convertView.findViewById(R.id.tvSMSSend);
        viewHolder.textBody = (TextView) convertView.findViewById(R.id.tvSMSBody);
        viewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.cbSelect);
        viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        int getPosition = (Integer) buttonView.getTag();  // Here we get the position that we have set for the checkbox using setTag.
                        list.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.
                    }
                });
        convertView.setTag(viewHolder);
        convertView.setTag(R.id.tvSMSSend, viewHolder.textAddress);
        convertView.setTag(R.id.tvSMSBody, viewHolder.textBody);
        convertView.setTag(R.id.cbSelect, viewHolder.checkbox);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    viewHolder.checkbox.setTag(position); // This line is important.
    viewHolder.textAddress.setText(list.get(position).getAddress());
    viewHolder.textBody.setText(list.get(position).getBody());
    viewHolder.checkbox.setChecked(list.get(position).isSelected());    
    return convertView;
}}

SMSListModel

public class SMSListModel {

private String address;
String body;
private boolean selected;

public SMSListModel(String address, String body) {
    this.address = address;
    this.body = body;
}

public String getAddress() {
    return address;
}

public String getBody() {
    return body;
}

public boolean isSelected() {
    return selected;
}

public void setSelected(boolean selected) {
    this.selected = selected;
}}

Logcat

2 个答案:

答案 0 :(得分:1)

光标&#34; c&#34;是您在这两种方法中使用的全局变量

getModel();

getInboxSms();

但问题是您在getInboxSms()方法中关闭光标并尝试在getModel()方法中访问相同的光标。

所以从getInboxSms()方法中删除这一行并尝试。

 c.close();

更新此方法

private List<SMSListModel> getModel() {
        if (c.getCount() > 0) {
            c.moveToFirst();

            for (int i = 0; i < c.getCount(); i++) {
                list.add(new SMSListModel(c.getString(c.getColumnIndex("address")), c.getString(c.getColumnIndex("body"))));
                c.moveToNext();
            }
        }

        return list;

    }

更新你的onCreate()方法

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        context = this;
        listViewSMS = (ListView) findViewById(R.id.lvSMS);

        getInboxSms();
        textViewSMSSender = (TextView) findViewById(R.id.tvSMSSend);
        textViewSMSBody = (TextView) findViewById(R.id.tvSMSBody);
        smsListAdapter = new SMSListAdapter(this, getModel());

        listViewSMS.setAdapter(smsListAdapter); // you forget to add this line
        listViewSMS.setOnItemClickListener(this);

    }

答案 1 :(得分:0)

请勿尝试以

的方法关闭光标
public String getContactName(Context context, String phoneNumber) 
 public void getInboxSms()

您可以在完成所有操作后尝试关闭光标