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