让listview知道contentprovider已更新

时间:2014-05-09 10:32:42

标签: android android-contentprovider

我有一个列表视图,显示我填充了contentprovider(收件箱)的模型项。现在,当我在我的广播接收器中并得到更新时,我想让列表视图知道他必须更新他的列表模型并显示它。

我已经看到你可以用notifyChanged做到这一点,但我找不到一个好的例子。

有人可以帮我解决这个问题吗?

编辑:

SMSBroadcastReceiver:

            Object[] pdus = (Object[]) bundle.get("pdus");
            final SmsMessage[] messages = new SmsMessage[pdus.length];
            for (int i = 0; i < pdus.length; i++) {
                messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
            }

            if (messages.length < 0) {
                return;
            }

            SmsMessage sms = messages[0];
            String body = "";
            String sender = sms.getOriginatingAddress().toString();
            Long time_rcv = sms.getTimestampMillis();

            try {
                if (messages.length == 1 || sms.isReplace()) {
                    body = sms.getDisplayMessageBody();
                } else {
                    StringBuilder bodyText = new StringBuilder();
                    for (int i = 0; i < messages.length; i++) {
                        bodyText.append(messages[i].getMessageBody());
                    }
                    body = bodyText.toString();
                }
            } catch (Exception e) {

            }

            ContentValues smsValues = new ContentValues();
            smsValues.put("address", sender);
            smsValues.put("body", body);
            smsValues.put("date_sent", time_rcv);
            context.getContentResolver().insert(BlacklistConstants.smsInboxUri, smsValues);

从这里我想让我的片段知道添加了一个新的短信。 那个.insert让我回来了。

这是该函数填充包含模型的smsList的片段。

private void fetchBox(Conversations smsConversation, String thread_id, Uri threadUri) {
    //Cursor smsInThreads = getActivity().getContentResolver().query(threadUri, null, "thread_id = ?", new String[]{thread_id}, null);

    CursorLoader cursorLoader = new CursorLoader(getActivity(), threadUri,
            null, // the columns to retrieve (all)
            "thread_id = ?", // the selection criteria (none)
            new String[]{thread_id}, // the selection args (none)
            null // the sort order (default)
    );

    Cursor smsInThreads = cursorLoader.loadInBackground();

    if (smsInThreads.moveToFirst()) {
        smsConversation.setNumber(smsInThreads.getString(smsInThreads.getColumnIndexOrThrow("address")));
        for (int x = 0; x < smsInThreads.getCount(); x++) {
            smsObjects msg = new smsObjects();
            msg.setBody(smsInThreads.getString(smsInThreads.getColumnIndexOrThrow("body")));
            msg.setNumber(smsInThreads.getString(smsInThreads.getColumnIndexOrThrow("address")));
            msg.setId(smsInThreads.getString(smsInThreads.getColumnIndexOrThrow("_id")));
            msg.setTimeStampReceived(smsInThreads.getString(smsInThreads.getColumnIndexOrThrow("date_sent")));
            smsConversation.addTextMessage(msg);
            smsInThreads.moveToNext();
        }
    }
    //smsList.add(smsConversation);
    smsInThreads.close();
}

最后这是我的自定义适配器:

public class ListAdapter extends ArrayAdapter<Conversations> {

private String TAG = ListAdapter.class.getName();

private final Context context;
private final List<Conversations> smsList;

public ListAdapter(Context context, List<Conversations> smsList) {
    super(context, R.layout.sms_inbox, smsList);
    this.context = context;
    this.smsList = smsList;
}

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

    if(convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.sms_inbox, parent, false);

        holder = new ViewHolder();
        holder.senderNumber = (TextView) convertView.findViewById(R.id.smsNumberText);

        convertView.setTag(holder);
    }
    else
        holder = (ViewHolder) convertView.getTag();

    holder.senderNumber.setText(smsList.get(position).getNumber());

    return convertView;
}

private static class ViewHolder
{
    public TextView senderNumber;
}

@Override
public int getCount() {
    return smsList != null ? smsList.size() : 0;
}

}

现在我不知道如何轻松让片段知道有一个新的插入,并且listview需要更新他的模型并显示它。

我过去这样做过:

  Uri newSms = context.getContentResolver().insert(BlacklistConstants.smsInboxUri, smsValues);
            Log.d(TAG,newSms.toString());

            Intent smsReceiveIntent = new Intent(BlacklistConstants.smsFilter);
            smsReceiveIntent.putExtra("newSMS",newSms);
            context.sendBroadcast(smsReceiveIntent);

然后在我的片段上我听到了这个意图并将其添加到smsList然后执行了notifyDataChanged。但我认为还有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

我通过在onreceive中启动intent然后在main中听取该intent并更新列表来解决这个问题。

在onreceive中:

          Intent smsReceiveIntent = new Intent(BlacklistConstants.smsFilter);
            smsReceiveIntent.putExtra("newSMS",newSms.toString());
            context.sendBroadcast(smsReceiveIntent);

并在您可以更新列表视图的活动中:

    // Sets up the smsreceiver broadcastreceiver
private void setupSmsReceiver() {
    smsReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, final Intent intent) {

            Log.d(TAG, "onReceive smsReceiver");

            if (getActivity() != null) {
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Log.d(TAG, "runOnUiThread");
                        String uri = intent.getStringExtra("newSMS");
                        addToList(uri);
                        smsAdapter.notifyDataSetChanged();
                    }
                });
            }
        }
    };
    getActivity().registerReceiver(smsReceiver, new IntentFilter(BlacklistConstants.smsFilter));
}

答案 1 :(得分:0)

我所做的是在托管列表的类中使用ContentObserver,就像这样 (注意:此代码在片段内部)

    private static final int REFRESH_PAGES = 1;
    private static final int CHANGE_CURRENT_SET = 2;
    private myCustomObserver mContentObserver;


 //utility function to set de observer
// register a un content observer to know that the content has changed
private void registerContentObserver(int myId) {
    Log.v(DEBUG_TAG, "registerContentObserver, myId=" + myId);
    if (mContentObserver != null) {
        getActivity().getContentResolver().unregisterContentObserver(
                mContentObserver);
    }
    mContentObserver = new MyCustomObserver (mHandler);
    getActivity().getContentResolver().registerContentObserver(
            yourUri, true,
            mContentObserver);
}

......这是内容观察员

class MyCustomObserver extends ContentObserver {
    public MyCustomObserver(Handler handler) {
        super(handler);
        Log.v(DEBUG_TAG, "MyCustomObserver");
    }

    @Override
    public void onChange(boolean selfChange) {
        Log.i(DEBUG_TAG, "onChange, selfChange==" + selfChange);
        super.onChange(selfChange);
        Message msg = mHandler.obtainMessage(REFRESH_PAGES);
        mHandler.sendMessage(msg);
    };

    @SuppressLint("NewApi")
    @Override
    public void onChange(boolean selfChange, Uri uri) {
        Log.v(DEBUG_TAG, "onChange, selfChange==" + selfChange + ", uri=="
                + uri.toString());
        final Message msg = mHandler.obtainMessage(REFRESH_PAGES);
        mHandler.sendMessage(msg);
        super.onChange(selfChange, uri);
    }

    @Override
    public boolean deliverSelfNotifications() {
        return true;
    }
}

我还需要一个处理程序:

public Handler mHandler = new Handler() {
    @Override
    public void handleMessage(android.os.Message msg) {
        Log.v(DEBUG_TAG, "mHandler");
        if (isAdded()) {//IMPORTANT if you are in a fragment
            switch (msg.what) {
                case REFRESH_PAGES:
                    getLoaderManager().getLoader(0).forceLoad();
                    break;
                case CHANGE_CURRENT_SET:
                    firstTime = true;
                    doYourStaff();
                    break;
            }
        }
    };
};

在内容提供商中,您需要以下内容:

                getContext().getContentResolver()
                    .notifyChange(yourUri, null);
瞧瞧......