【问题标题】:Automatically refresh listview on sqlite database change - Chat Application Android在 sqlite 数据库更改时自动刷新列表视图 - 聊天应用程序 Android
【发布时间】:2015-08-25 07:49:27
【问题描述】:

我正在构建一个聊天应用程序,我在 BroadcastReceiver 中获得响应。我将该数据发送到 IntentService,并在其中成功地将数据插入 Sqlite 数据库。现在我想根据数据库更改自动刷新我的片段中的列表视图。我的列表是使用 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

提前致谢。

【问题讨论】:

    标签: android sqlite broadcastreceiver intentservice android-cursoradapter


    【解决方案1】:

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

    重写 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 时传递活动的上下文。

    示例代码:

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

    【讨论】:

    • 对不起。我是新开发人员。您能否解释一下如何获取 Activity 的上下文,因为我使用的是片段。
    • 接收消息的流程是BroadcastReceiver -> IntentService -> 数据库插入。
    • 我有这样的广播接收器.. ComponentName comp = new ComponentName(context.getPackageName(),SendService.class.getName()); startWakefulService(context, (intent.setComponent(comp))); setResultCode(Activity.RESULT_OK);
    • 您能否解释一下如何获取 Activity 的上下文,因为我使用的是片段。 --> getActivity();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    相关资源
    最近更新 更多