我有一个列表视图,显示我填充了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。但我认为还有更好的方法吗?
答案 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);
瞧瞧......