com.orangelabs.rcs.ri.messaging.chat.group.GroupChatList.java Source code

Java tutorial

Introduction

Here is the source code for com.orangelabs.rcs.ri.messaging.chat.group.GroupChatList.java

Source

/*******************************************************************************
 * Software Name : RCS IMS Stack
 *
 * Copyright (C) 2010 France Telecom S.A.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package com.orangelabs.rcs.ri.messaging.chat.group;

import com.gsma.services.rcs.RcsPermissionDeniedException;
import com.gsma.services.rcs.RcsServiceException;
import com.gsma.services.rcs.chat.ChatLog;
import com.gsma.services.rcs.chat.ChatLog.Message.Content;
import com.gsma.services.rcs.chat.ChatService;
import com.gsma.services.rcs.chat.GroupChat;
import com.gsma.services.rcs.chat.GroupChat.ParticipantStatus;
import com.gsma.services.rcs.chat.GroupChatListener;
import com.gsma.services.rcs.contact.ContactId;
import com.gsma.services.rcs.groupdelivery.GroupDeliveryInfo;

import com.orangelabs.rcs.api.connection.ConnectionManager.RcsServiceName;
import com.orangelabs.rcs.api.connection.utils.ExceptionUtil;
import com.orangelabs.rcs.api.connection.utils.RcsFragmentActivity;
import com.orangelabs.rcs.ri.R;
import com.orangelabs.rcs.ri.RiApplication;
import com.orangelabs.rcs.ri.utils.LogUtils;
import com.orangelabs.rcs.ri.utils.Utils;

import android.content.Context;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.TextView;

import java.util.Arrays;
import java.util.Map;
import java.util.Set;

/**
 * List group chats from the content provider
 * 
 * @author YPLO6403
 */
public class GroupChatList extends RcsFragmentActivity implements LoaderManager.LoaderCallbacks<Cursor> {

    // @formatter:off
    String[] PROJECTION = new String[] { ChatLog.GroupChat.BASECOLUMN_ID, ChatLog.GroupChat.CHAT_ID,
            ChatLog.GroupChat.SUBJECT, ChatLog.GroupChat.STATE, ChatLog.GroupChat.REASON_CODE,
            ChatLog.GroupChat.TIMESTAMP, ChatLog.GroupChat.PARTICIPANTS };
    // @formatter:on

    private static final String SORT_ORDER = new StringBuilder(ChatLog.GroupChat.TIMESTAMP).append(" DESC")
            .toString();

    private ListView mListView;

    private ChatService mChatService;

    private GroupChatListAdapter mAdapter;

    private boolean mGroupChatListenerSet = false;

    private Handler mHandler = new Handler();

    /**
     * List of items for contextual menu
     */
    private static final int CHAT_MENU_ITEM_DELETE = 1;
    private static final int CHAT_MENU_ITEM_OPEN = 0;

    private static final String LOGTAG = LogUtils.getTag(GroupChatList.class.getSimpleName());

    /**
     * The loader's unique ID. Loader IDs are specific to the Activity in which they reside.
     */
    private static final int LOADER_ID = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /* Set layout */
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(R.layout.chat_list);

        mChatService = getChatApi();

        /* Set list adapter */
        mListView = (ListView) findViewById(android.R.id.list);
        TextView emptyView = (TextView) findViewById(android.R.id.empty);
        mListView.setEmptyView(emptyView);
        registerForContextMenu(mListView);

        mAdapter = new GroupChatListAdapter(this);
        mListView.setAdapter(mAdapter);
        /*
         * Initialize the Loader with id '1' and callbacks 'mCallbacks'.
         */
        getSupportLoaderManager().initLoader(LOADER_ID, null, this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mChatService == null || !mGroupChatListenerSet) {
            return;
        }
        try {
            mChatService.removeEventListener(mGroupChatListener);
        } catch (RcsServiceException e) {
            Log.w(LOGTAG, ExceptionUtil.getFullStackTrace(e));
        }
    }

    /**
     * Group chat list adapter
     */
    private class GroupChatListAdapter extends CursorAdapter {

        private LayoutInflater mInflater;

        /**
         * Constructor
         * 
         * @param context Context
         */
        public GroupChatListAdapter(Context context) {
            super(context, null, 0);
            mInflater = LayoutInflater.from(context);
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            final View view = mInflater.inflate(R.layout.chat_group_list_item, parent, false);
            view.setTag(new GroupChatListItemViewHolder(view, cursor));
            return view;
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            final GroupChatListItemViewHolder holder = (GroupChatListItemViewHolder) view.getTag();
            long date = cursor.getLong(holder.columnDate);
            holder.dateText.setText(DateUtils.getRelativeTimeSpanString(date, System.currentTimeMillis(),
                    DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE));

            String subject = cursor.getString(holder.columnSubject);
            if (TextUtils.isEmpty(subject)) {
                holder.subjectText.setText(context.getString(R.string.label_subject_notif,
                        "<" + context.getString(R.string.label_no_subject) + ">"));
            } else {
                holder.subjectText.setText(context.getString(R.string.label_subject_notif, subject));
            }
            int state = cursor.getInt(holder.columnState);
            if (state < RiApplication.sGroupChatStates.length) {
                holder.stateText.setText(RiApplication.sGroupChatStates[state]);
            }
            int reason = cursor.getInt(holder.columnReasonCode);
            if (reason < RiApplication.sGroupChatReasonCodes.length) {
                if (GroupChat.ReasonCode.UNSPECIFIED == GroupChat.ReasonCode.valueOf(reason)) {
                    holder.reasonText.setVisibility(View.GONE);
                } else {
                    holder.reasonText.setVisibility(View.VISIBLE);
                    holder.reasonText.setText(RiApplication.sGroupChatReasonCodes[reason]);
                }
            }

            try {
                Map<ContactId, ParticipantStatus> mapOfparticipants = ChatLog.GroupChat
                        .getParticipants(GroupChatList.this, cursor.getString(holder.columnParticipants));
                StringBuilder sb = null;
                for (ContactId participant : mapOfparticipants.keySet()) {
                    if (sb == null) {
                        sb = new StringBuilder(participant.toString());
                    } else {
                        sb.append("\n");
                        sb.append(participant.toString());
                    }
                }
                if (sb != null) {
                    holder.participantsText.setText(sb.toString());
                }
            } catch (RcsPermissionDeniedException e) {
                if (LogUtils.isActive) {
                    Log.e(LOGTAG, "getParticipants failed", e);
                }
            }

        }
    }

    /**
     * A ViewHolder class keeps references to children views to avoid unnecessary calls to
     * findViewById() or getColumnIndex() on each row.
     */
    private class GroupChatListItemViewHolder {
        TextView subjectText;

        TextView dateText;

        TextView stateText;

        TextView reasonText;

        int columnSubject;

        TextView participantsText;

        int columnDate;

        int columnState;

        int columnParticipants;

        int columnReasonCode;

        GroupChatListItemViewHolder(View base, Cursor cursor) {
            columnSubject = cursor.getColumnIndexOrThrow(ChatLog.GroupChat.SUBJECT);
            columnDate = cursor.getColumnIndexOrThrow(ChatLog.GroupChat.TIMESTAMP);
            columnState = cursor.getColumnIndexOrThrow(ChatLog.GroupChat.STATE);
            columnParticipants = cursor.getColumnIndexOrThrow(ChatLog.GroupChat.PARTICIPANTS);
            columnReasonCode = cursor.getColumnIndexOrThrow(ChatLog.GroupChat.REASON_CODE);
            subjectText = (TextView) base.findViewById(R.id.subject);
            dateText = (TextView) base.findViewById(R.id.date);
            stateText = (TextView) base.findViewById(R.id.state);
            participantsText = (TextView) base.findViewById(R.id.participants);
            reasonText = (TextView) base.findViewById(R.id.reason);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = new MenuInflater(getApplicationContext());
        inflater.inflate(R.menu.menu_log, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_clear_log:
            /* Delete all group chats */
            if (!isServiceConnected(RcsServiceName.CHAT)) {
                showMessage(R.string.label_service_not_available);
                break;
            }
            if (LogUtils.isActive) {
                Log.d(LOGTAG, "delete all group chat sessions");
            }
            try {
                if (!mGroupChatListenerSet) {
                    mChatService.addEventListener(mGroupChatListener);
                    mGroupChatListenerSet = true;
                }
                mChatService.deleteGroupChats();
            } catch (RcsServiceException e) {
                showExceptionThenExit(e);
            }
            break;
        }
        return true;
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        /* Check file transfer API is connected */
        if (!isServiceConnected(RcsServiceName.CHAT)) {
            showMessage(R.string.label_service_not_available);
            return;
        }
        menu.add(0, CHAT_MENU_ITEM_OPEN, CHAT_MENU_ITEM_OPEN, R.string.menu_open_chat_session);
        menu.add(0, CHAT_MENU_ITEM_DELETE, CHAT_MENU_ITEM_DELETE, R.string.menu_delete_chat_session);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        /* Get selected item */
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        Cursor cursor = (Cursor) (mListView.getAdapter()).getItem(info.position);
        String chatId = cursor.getString(cursor.getColumnIndexOrThrow(ChatLog.GroupChat.CHAT_ID));
        if (LogUtils.isActive) {
            Log.d(LOGTAG, "onContextItemSelected chatId=".concat(chatId));
        }
        switch (item.getItemId()) {
        case CHAT_MENU_ITEM_OPEN:
            if (!isServiceConnected(RcsServiceName.CHAT)) {
                showMessage(R.string.label_service_not_available);
                return true;
            }
            if (LogUtils.isActive) {
                Log.d(LOGTAG, "Open group chat for chatId=".concat(chatId));
            }
            /* Open group chat view */
            GroupChatView.openGroupChat(this, chatId);
            return true;

        case CHAT_MENU_ITEM_DELETE:
            if (!isServiceConnected(RcsServiceName.CHAT)) {
                showMessage(R.string.label_service_not_available);
                return true;
            }
            /* Delete messages for chat ID */
            if (LogUtils.isActive) {
                Log.d(LOGTAG, "Delete messages for chatId=".concat(chatId));
            }
            try {
                if (!mGroupChatListenerSet) {
                    mChatService.addEventListener(mGroupChatListener);
                    mGroupChatListenerSet = true;
                }
                mChatService.deleteGroupChat(chatId);
            } catch (RcsServiceException e) {
                showExceptionThenExit(e);
            }
            return true;
        default:
            return super.onContextItemSelected(item);
        }
    }

    private GroupChatListener mGroupChatListener = new GroupChatListener() {

        @Override
        public void onMessagesDeleted(String chatId, Set<String> msgIds) {
            if (LogUtils.isActive) {
                Log.d(LOGTAG, "onMessagesDeleted chatId=" + chatId + " for message IDs="
                        + Arrays.toString(msgIds.toArray()));
            }
        }

        @Override
        public void onDeleted(Set<String> chatIds) {
            if (LogUtils.isActive) {
                Log.i(LOGTAG, "onDeleted chatIds=".concat(Arrays.toString(chatIds.toArray())));
            }
            mHandler.post(new Runnable() {
                public void run() {
                    Utils.displayLongToast(GroupChatList.this, getString(R.string.label_delete_gchat_success));
                }
            });
        }

        @Override
        public void onComposingEvent(String chatId, ContactId contact, boolean status) {
        }

        @Override
        public void onMessageGroupDeliveryInfoChanged(String chatId, ContactId contact, String mimeType,
                String msgId, GroupDeliveryInfo.Status status, GroupDeliveryInfo.ReasonCode reasonCode) {
        }

        @Override
        public void onMessageStatusChanged(String chatId, String mimeType, String msgId, Content.Status status,
                Content.ReasonCode reasonCode) {
        }

        @Override
        public void onParticipantStatusChanged(String chatId, ContactId contact, ParticipantStatus status) {
        }

        @Override
        public void onStateChanged(String chatId, final GroupChat.State state, GroupChat.ReasonCode reasonCode) {
        }

    };

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        /* Create a new CursorLoader with the following query parameters. */
        return new CursorLoader(this, ChatLog.GroupChat.CONTENT_URI, PROJECTION, null, null, SORT_ORDER);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        /* A switch-case is useful when dealing with multiple Loaders/IDs */
        switch (loader.getId()) {
        case LOADER_ID:
            /*
             * The asynchronous load is complete and the data is now available for use. Only now
             * can we associate the queried Cursor with the CursorAdapter.
             */
            mAdapter.swapCursor(cursor);
            break;
        }
        /* The listview now displays the queried data. */
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        /*
         * For whatever reason, the Loader's data is now unavailable. Remove any references to the
         * old data by replacing it with a null Cursor.
         */
        mAdapter.swapCursor(null);
    }
}