Android 让listview知道contentprovider已更新

Android 让listview知道contentprovider已更新,android,android-contentprovider,Android,Android Contentprovider,我有一个列表视图,显示我用contentprovider(收件箱)填充的模型项。现在,当我在我的broadcastreceiver中得到更新时,我想让listview知道他必须更新他的模型列表并显示它 我已经看到你可以用notifyChanged做这件事,但我找不到一个好的例子 有人能帮我吗 编辑: SMSBroadcastReceiver: Object[] pdus = (Object[]) bundle.get("pdus"); final

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

我已经看到你可以用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);

然后在我的片段中,我听取了这个意图,并将其添加到smsList中,然后进行了更改。但我认为有更好的办法不这样做?

我解决了这个问题,在onreceive中启动一个意图,然后在main中听取该意图并更新列表

在onreceive中:

          Intent smsReceiveIntent = new Intent(BlacklistConstants.smsFilter);
            smsReceiveIntent.putExtra("newSMS",newSms.toString());
            context.sendBroadcast(smsReceiveIntent);
在可以更新listview的活动中:

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

我要做的是在承载列表的类中使用ContentObserver,如下所示 (注意:此代码位于片段内部)

。。。。。。这是内容观察者

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

瞧…

您必须通知支持listView的适配器。setNotifyOnChange(true)告诉适配器像swapCursor这样的操作应该触发更新。您的listView将随适配器中的更改而更改。若要请求适配器上的更新,请使用adapter.notifyDataSetChanged();在您实际更改适配器中的数据之后。但是,我仍然需要从我的broadcastreceiver启动一个广播,以在我的mainfragment中通知数据已更改,然后插入新数据,然后调用notifyDataChanged。那么,contentproviders的好处是什么:s?显示您已经实现的代码,以便其他人可以帮助发布一些代码。ContentProvider允许您使用
CursorLoader
s,并允许其他应用程序访问您的数据(如果您这样说的话)。此外,ContentProvider允许您侦听数据的更改,SQLite不会这样做(如果我是对的)。这是否意味着我需要创建自己的自定义ContentProvider?当您使用内容提供商时,您需要一个URI,因此您需要在内容提供商中注册此URI,以便通知您的内容观察家。如下所示:getActivity().getContentResolver().registerContentObserver(URI-you\u use\u访问\u内容\u提供程序,true,mcontoObserver);我明白,但当我收到一条新消息时,我需要重新查询uri并找出发生了什么变化。如果使用android的默认contentprovider,您不会得到更改的uri吗?还是我错了?
    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);