错误:在游标关闭后尝试访问游标? [英] Error: Attempted to access a cursor after it has been closed?

查看:330
本文介绍了错误:在游标关闭后尝试访问游标?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我正在从本机应用程序提取收件箱消息我的应用程序。还有复选框可以选择多个消息。但是出现的问题是没有消息显示在 listview运行代码,还显示错误 android.database。 StaleDataException:在游标关闭后尝试访问游标。

In my application I'm fetching inbox messages from native application to my application. Also there are checkboxes to select multiple messages.But the problem arises are no messages are displaying in listview while running code and also showing error 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

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

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;
}}

推荐答案

cursorc是一个全局变量,两种方法

cursor "c" is a global variable which you use in these two methods

getModel();

getInboxSms();

但问题是关闭 getInboxSms c $ c>方法,并尝试在 getModel()方法中访问相同的游标。

But the problem is you close the cursor in getInboxSms() method and try to access same cursor in getModel() method.

getInboxSms()方法并尝试。

So remove this line from getInboxSms() method and try.

 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()方法

Update your onCreate() Method

@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);

    }

这篇关于错误:在游标关闭后尝试访问游标?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆