简体   繁体   中英

How to Update the Fragment ListView from Service in android?

I am trying to build a chatting app using GCM .Now i could successfully receive and send data between two users.When i am chatting i have a chatwindow open only for me and myfriend.Now the problem is that i have a listview for the conversation between me and my friend.I am little bit confused how to update the listview while i am chatting with my friend, actually when my friend send me message.Now the scenarios in my app is:

1. If chat window is open for me and Mr A and Mr A sends me a message then i want to update the listview .My ChatWindow is in a fragment .Now i don't know how to update the fragment UI from the service.The below ShowToast() method can give me the message.Now what i want is to just append this message to my listview in the chatFragment .

public class GcmIntentService extends IntentService {

    public GcmIntentService() {
        super("GcmIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        // The getMessageType() intent parameter must be the intent you received
        // in your BroadcastReceiver.
        String messageType = gcm.getMessageType(intent);

        if (extras != null && !extras.isEmpty()) {  // has effect of unparcelling Bundle
            // Since we're not using two way messaging, this is all we really to check for
            if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
                Logger.getLogger("GCM_RECEIVED").log(Level.INFO, extras.toString());

                showToast(extras.getString("message"));
            }
        }
        GcmBroadcastReceiver.completeWakefulIntent(intent);
    }

    protected void showToast(final String message) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();

            }
        });
    }
}

ChatFragment:

public class ChatFragment extends Fragment {

    private EditText et_chat;
    Bundle mailData;
    String caller_mail;
    private ListView chatListview;
    private ChatWindowAdapter chatWindowAdapter;
    private List<ChatSession>PreviousChatSession;
    private List<ChatInfo> chatListItems;
    Button chat_send;
    public ChatFragment() {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.chat_window, null, false);
        et_chat = (EditText) v.findViewById(R.id.et_chat);
        chat_send = (Button) v.findViewById(R.id.bt_chat_send);
        chatListview = (ListView)v.findViewById(R.id.chat_listView);
        chatListItems = new ArrayList<ChatInfo>();
        chatWindowAdapter = new ChatWindowAdapter(getActivity(),chatListItems);
        chatListview.setAdapter(chatWindowAdapter);
        mailData=getArguments();
        caller_mail = mailData.getString(PropertyNames.Userinfo_Mail.getProperty());

        retrieveChats();

        chat_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ChatInfo chatInfo= new ChatInfo();
                chatInfo.setChat_text(et_chat.getText().toString());
                chatInfo.setDirection("right");
                chatListItems.add(chatInfo);
                chatWindowAdapter.notifyDataSetChanged();

                fetchID(caller_mail);
            }
        });

        return v;
    }


    public void fetchID(String mail) {
        Data d = new Data();
        d.setUsermail(mail);
        d.setCommand(Commands.GCM_getRegID.getCommand());

        new GCMRegIDCheckerEndpointCommunicator() {
            @Override
            protected void onPostExecute(GCMEndpointReturnData result) {

                super.onPostExecute(result);

                insertMsg(result.getRegID());
            }
        }.execute(d);
    }

    public void insertMsg(String DestinationID){

        Data d = new Data();
        d.setCommand(Commands.ChatSession_insert.getCommand());
        d.setExtra(DestinationID);

        String sessionName = null;
        if(caller_mail.compareTo(getMymail()) < 0){
            sessionName = caller_mail + getMymail();
        }
        else //greater
        {
            sessionName = getMymail() + caller_mail;
        }

        d.setStringKey(sessionName);
        d.setExtramsg(et_chat.getText().toString());
        d.setUsername(getMyName());

        new ChatSessionEndpointCommunicator().execute(d);
    }



    public String getMymail() {
        Bundle mailBundle = ((SlidingDrawerActivity) getActivity()).getEmail();
        String mail = mailBundle.getString(PropertyNames.Userinfo_Mail.getProperty());
        return mail;
    }

    public String getMyName() {
        Bundle nameBundle = ((SlidingDrawerActivity) getActivity()).getEmail();
        String name = nameBundle.getString(PropertyNames.Userinfo_Username.getProperty());
        return name;
    }

    private void retrieveChats() {
        String sessionName = null;
        if(caller_mail.compareTo(getMymail()) < 0){
            sessionName = caller_mail + getMymail();
        }
        else //greater
        {
            sessionName = getMymail() + caller_mail;
        }

        Data d = new Data();
        d.setUsername(getMyName());
        d.setCommand(Commands.ChatSession_fetch.getCommand());
        d.setStringKey(sessionName);

        new ChatSessionEndpointCommunicator(){
            @Override
            protected void onPostExecute(List<ChatSession> result) {

                super.onPostExecute(result);
                PreviousChatSession = result;
                populateChats(PreviousChatSession);
                }
        }.execute(d);
    }

    private void populateChats(List<ChatSession> previousChatSession) {
        for(int i=0;i<previousChatSession.size();i++){
            ChatSession c = previousChatSession.get(i);
            ChatInfo chatInfo = new ChatInfo();
            chatInfo.setChat_text(c.getMsg());
            try {
                chatInfo.setChat_time(convertDate(c.getDate()));
            } catch (ParseException e) {

            }
            if (c.getNameofPerson().equals(getMyName())){
                chatInfo.setDirection("right");
            }else{
                chatInfo.setDirection("left");
            }
            chatListItems.add(chatInfo);
        }
        chatWindowAdapter.notifyDataSetChanged();
    }

2. If the message came from my other friend whom i am not chatting now then i will create a notification.At this time no need to update the listview of the chatFragment .I can handle this as i am saving every message in my database.

As i am saving it in my database i can retrive the data from database after some time interval but it will drain my battery and also not good approach.I just want to update the chatwindow when message comes from my friend and at that time chatWindow was open..

Now how can i reference the Fragment listview to update the listview when message comes??

Try this,

Register a broadcast receiver in all your fragments... like this

create a class which extends a broadcast receiver in all the classes, for eg:

public class FragmentReceiver1 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    }    
}

and register this receiver in you fragment's onCreate ...

for eg. getActivity().registerReceiver(new FragmentReceiver1(), new IntentFilter("fragmentupdater"));

Now assign a unique id to each of you fragment like 1 for Fragment1, 2 for Fragment2 and likewise

now whenever you want to pass any data and update any of the fragment just send a broadcast with the data in intent and "fragmentupdater" as the intent-filter...

For eg:

Intent data = new Intent("fragmentupdater");
data.putString("key","data");
data.putInt("fragmentno",1); // Pass the unique id of fragment we talked abt earlier
activity.sendBroadcast(intent);

Now each of your fragment will receive the data but you can verify if the data if for the same fragment by the unique id we passed in it in the onReceive function..., the intent which you get, is the intent we passed above

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM