android - 在 sqlite 数据库更改时自动刷新 ListView - Android 聊天应用程序

标签 android sqlite broadcastreceiver intentservice android-cursoradapter

我正在构建一个聊天应用程序,我在 BroadcastReceiver 中收到响应。我将该数据发送到 IntentService,在那里我成功地将数据插入到 Sqlite 数据库。现在我想根据数据库更改自动刷新 fragment 中的 ListView 。我的列表是使用 CursorAdapter 填充的。

我的 MassageView Fragment 代码如下:

public class MessageView_Fragment extends Fragment {

View rootView;
ListView lv;
ChatListAdapter chatAdapter;
ArrayList<Message_Master> arr;
MatrixCursor cr;
DBHelper db;
static String rMob;
ActionMode actionMode;
SharedPreferences prefs;
SimpleDateFormat sdf,sdf_old,sdf_today;
FrameLayout attacher;

boolean isBottom = true;

@SuppressLint("DefaultLocale")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
    // TODO Auto-generated method stub
    rootView = inflater.inflate(R.layout.fragment_message, container, false);
    getActivity().getWindow().setBackgroundDrawableResource(R.drawable.chat_back);
    rMob = getArguments().getString("rmob");
    Log.e("rMob", rMob);
    lv= (ListView)rootView.findViewById(R.id.chat_msg_list);
    db = new DBHelper(getActivity());
    db.UpdateUnseenToSeen(Long.valueOf(rMob));
    Contact_Master cm = db.getContactDetails(rMob);
    ActionBar mActionBar = ((ActionBarActivity)getActivity()).getSupportActionBar();
    mActionBar.setDisplayShowHomeEnabled(true);
    mActionBar.setDisplayShowTitleEnabled(false);
    LayoutInflater mInflater = LayoutInflater.from(getActivity());
    View mCustomView = mInflater.inflate(R.layout.custom_action_bar_chat, null);
    RoundedImageView prof_pic = (RoundedImageView)mCustomView.findViewById(R.id.imageView1);
    TextView tv_name = (TextView)mCustomView.findViewById(R.id.textView1);
    if(cm.getName() == null)
    {
        tv_name.setText(rMob);
    }
    else
    {
        tv_name.setText(cm.getName());
    }

    TextView tv_details = (TextView)mCustomView.findViewById(R.id.textView2);
    tv_details.setText(cm.getStatus());
    mActionBar.setCustomView(mCustomView);
    mActionBar.setDisplayShowCustomEnabled(true);
    attacher = (FrameLayout)rootView.findViewById(R.id.attacher);
    prefs = getActivity().getSharedPreferences(SplashScreen_Activity.MyPrefs, Context.MODE_PRIVATE);
    sdf = new SimpleDateFormat("dd MMM");
    sdf_old = new SimpleDateFormat("MMMM dd, yyyy");
    sdf_today = new SimpleDateFormat("h:mm a");
    arr = db.getMessages(rMob);
    cr = new MatrixCursor(new String[]{"_id","msg","type","dt","stat"});
    boolean timeAdded = false;
    if(arr.size()>0)
    {
        Calendar c = Calendar.getInstance();
        for(int i = 0; i<arr.size();i++)
        {       
            if(arr.get(i).getType() == 0)
            {
                cr.addRow(new String[]{String.valueOf(arr.get(i).getId()),arr.get(i).getMsg(),"0", sdf.format(arr.get(i).getMsgtime()),arr.get(i).getStatus()});
            }
            else
            {
                cr.addRow(new String[]{String.valueOf(arr.get(i).getId()),arr.get(i).getMsg(),"1",sdf.format(arr.get(i).getMsgtime()),arr.get(i).getStatus()});
            }
        }
    }
    chatAdapter = new ChatListAdapter(getActivity(),cr);

    lv.setAdapter(chatAdapter);
    chatAdapter.notifyDataSetChanged();

    final EmojiconEditText emojiconEditText = (EmojiconEditText) rootView.findViewById(R.id.msg_edit);
    final ImageButton emojiButton = (ImageButton) rootView.findViewById(R.id.smiley_btn);
    final ImageButton submitButton = (ImageButton) rootView.findViewById(R.id.send_btn);



    //On submit, add the edittext text to listview and clear the edittext
    submitButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            String newText = emojiconEditText.getText().toString();
            if(newText.trim().length()>0)
            {

                emojiconEditText.getText().clear();
                long _id = db.insertMessage(1, newText, prefs.getString("regMobile", "0"), rMob);
//              mAdapter.add(newText);
                send(newText,_id,getActivity().getApplicationContext(),prefs.getString("regMobile", "0"));
                cr.addRow(new String[]{String.valueOf(_id),newText,"1", sdf.format(Calendar.getInstance().getTime()),"W"});
                chatAdapter.notifyDataSetChanged();
                lv.setSelection(lv.getAdapter().getCount() - 1);

            }
        }   
    });


    setHasOptionsMenu(true);
    return rootView;
}

@SuppressLint("SimpleDateFormat")
public void RefreshList(long id,String msg)
{
    SimpleDateFormat sdf = new SimpleDateFormat("dd MMM");
    cr.addRow(new String[]{String.valueOf(id),msg,"0", sdf.format(Calendar.getInstance().getTime()),"W"});
    chatAdapter.notifyDataSetChanged();
    lv.setSelection(lv.getAdapter().getCount() - 1);
}

private void send(final String txt, final long _id, final Context context, final String myNumber) {
    new AsyncTask<Void, Void, String>() {
        @Override
        protected String doInBackground(Void... params) {
            String msg = "";
            try {
                ServerUtilities.send(txt, rMob,_id,context,myNumber);

            } catch (IOException ex) {
                msg = "Message could not be sent";
            }
            return msg;
        }

        @Override
        protected void onPostExecute(String msg) {
            if (!TextUtils.isEmpty(msg)) {
                //Toast.makeText(getActivity(), msg, Toast.LENGTH_LONG).show();
            }
        }
    }.execute(null, null, null);        
}}

BroadcastReceiver如下:

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

private static final String TAG = "GcmBroadcastReceiver";
public static final String CONSTANT_FOR_RECEIVER = "msg_type";
private Context ctx;    
DBHelper db;

@Override
public void onReceive(Context context, Intent intent) {
    ctx = context;
    db = new DBHelper(ctx);
    PowerManager mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    WakeLock mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
    mWakeLock.acquire();
    try {
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
        String messageType = gcm.getMessageType(intent);
        if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) 
        {
            //sendNotification("Send error", false);
        }
        else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) 
        {
            //sendNotification("Deleted messages on server", false);
        }
        else 
        {
            ComponentName comp = new ComponentName(context.getPackageName(),MessageView_Fragment.ESendService.class.getName());
                startWakefulService(context, (intent.setComponent(comp)));
                setResultCode(Activity.RESULT_OK);

        }
        setResultCode(Activity.RESULT_OK);
    } finally {
        mWakeLock.release();
    }
}}

发送服务如下:

public class SendService extends IntentService
{
DBHelper db;
Context ctx;
public SendService() {
    // TODO Auto-generated constructor stub
    super("name");
}

public SendService(String name)
{
    super(name);
    // TODO Auto-generated constructor stub
}

@Override
protected void onHandleIntent(Intent intent)
{
    db = new DBHelper(getApplicationContext());
    ctx = getApplicationContext();
    // TODO Auto-generated method stub
    String msg = intent.getStringExtra(DBHelper.MESSAGES_COLUMN_MESSAGE);
    String senderMob = intent.getStringExtra(DBHelper.MESSAGES_COLUMN_SENDER_MOBILE);
    String receiverMob = intent.getStringExtra(DBHelper.MESSAGES_COLUMN_RECEIVER_MOBILE);
    String chattype = intent.getStringExtra("chattype");
    Log.e("rMob", receiverMob);
    Log.e("sMob", senderMob);
    db.insertMessage(0, msg,receiverMob ,senderMob,"open");
    Contact_Master cm = db.getContactDetails(senderMob);
    String sender_name = "";
    if(cm !=null)
    {
         sender_name = cm.getName();
    }
    else
    {
        sender_name = senderMob;
    }


    db.close();

}}

目前接收邮件流程如下:

GCM -> BroadcardReceiver -> SendService -> MessageViewFragment

提前致谢。

最佳答案

您必须使用您的 IntentService 来更新 ListView UI。

Override the onReceiveResult(int, Bundle)

请参阅 SO 的回答:

Check this link for answer

解决方案的示例代码:

@Override
protected void onReceiveResult (int resultCode, Bundle resultData) {

    cttObjects.clear();
    CTTObjectsDataSource dataSource = new CTTObjectsDataSource(context);
    dataSource.open();
    cttObjects.addAll(dataSource.getAllObjects());
    dataSource.close();
    arrayAdapter.notifyDataSetChanged();

}

当您初始化 ResultReceiver 时,您必须传递 Activity 的上下文。

示例代码:

public class MainActivity extends Activity {

....
....
....

    public void showResults() {
        cttObjects.clear();
        CTTObjectsDataSource dataSource = new CTTObjectsDataSource(MainActivity.this);
        dataSource.open();
        cttObjects.addAll(dataSource.getAllObjects());
        dataSource.close();
        arrayAdapter.notifyDataSetChanged();
    }

....
....
....



    class UpdateObjectResultReceiver extends ResultReceiver {

    ....
    ....
    ....

        @Override
        protected void onReceiveResult (int resultCode, Bundle resultData) {
            MainActivity.this.showResults();
        }

    }
}

关于android - 在 sqlite 数据库更改时自动刷新 ListView - Android 聊天应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32198350/

相关文章:

java - Android 2.3.3 和 google map api v2 启动 Activity 时出错

delphi - TFDQuery 和 SQLite : Type mismatch for field, 期望:LargeInt 实际:WideString

java - 从广播接收器以编程方式连接 Android 中的蓝牙设备

android - 如何在两个不同的端口接收数据短信

android - 单击并按住耳机按钮无任何 Action

Android 异步任务进度条 onProgressUpdate

android - 使用 linux 终端或 python 复制 Android MTP 文件;不支持错误操作

android - 检查 GCM 消息的状态

sqlite - sqlite 支持 linq-to-SQL 吗?

c++ - 为什么将 strlen 重新实现为循环+减法?