com.sim2dial.dialer.HistoryFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.sim2dial.dialer.HistoryFragment.java

Source

package com.sim2dial.dialer;

/*
 HistoryFragment.java
 Copyright (C) 2012  Belledonne Communications, Grenoble, France
    
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.
    
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
    
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.sim2dial.dialer.R;
import com.sim2dial.dialer.R.anim;
import com.sim2dial.dialer.R.bool;
import com.sim2dial.dialer.R.drawable;
import com.sim2dial.dialer.R.id;
import com.sim2dial.dialer.R.layout;
import com.sim2dial.dialer.R.string;
import org.linphone.core.CallDirection;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCallLog;
import org.linphone.core.LinphoneCallLog.CallStatus;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.util.SparseArray;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ExpandableListView.OnGroupClickListener;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * @author Sylvain Berfini
 */
public class HistoryFragment extends Fragment
        implements OnClickListener, OnChildClickListener, OnGroupClickListener {
    private Handler mHandler = new Handler();
    private ExpandableListView historyList;
    private LayoutInflater mInflater;
    private TextView allCalls, missedCalls, edit, ok, deleteAll, noCallHistory, noMissedCallHistory;
    private boolean onlyDisplayMissedCalls, isEditMode;
    private SparseArray<List<LinphoneCallLog>> mLogs;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mInflater = inflater;
        View view = inflater.inflate(R.layout.history, container, false);

        noCallHistory = (TextView) view.findViewById(R.id.noCallHistory);
        noMissedCallHistory = (TextView) view.findViewById(R.id.noMissedCallHistory);

        historyList = (ExpandableListView) view.findViewById(R.id.historyList);
        historyList.setOnChildClickListener(this);
        historyList.setOnGroupClickListener(this);

        deleteAll = (TextView) view.findViewById(R.id.deleteAll);
        deleteAll.setOnClickListener(this);
        deleteAll.setVisibility(View.INVISIBLE);

        allCalls = (TextView) view.findViewById(R.id.allCalls);
        allCalls.setOnClickListener(this);

        missedCalls = (TextView) view.findViewById(R.id.missedCalls);
        missedCalls.setOnClickListener(this);

        allCalls.setEnabled(false);
        onlyDisplayMissedCalls = false;

        edit = (TextView) view.findViewById(R.id.edit);
        edit.setOnClickListener(this);

        ok = (TextView) view.findViewById(R.id.ok);
        ok.setOnClickListener(this);

        return view;
    }

    private boolean hideHistoryListAndDisplayMessageIfEmpty() {
        if (mLogs.size() == 0) {
            if (onlyDisplayMissedCalls) {
                noMissedCallHistory.setVisibility(View.VISIBLE);
            } else {
                noCallHistory.setVisibility(View.VISIBLE);
            }
            historyList.setVisibility(View.GONE);
            return true;
        } else {
            noCallHistory.setVisibility(View.GONE);
            noMissedCallHistory.setVisibility(View.GONE);
            historyList.setVisibility(View.VISIBLE);
            return false;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (LinphoneActivity.isInstanciated())
            LinphoneActivity.instance().selectMenu(FragmentsAvailable.HISTORY);

        initLogsLists(Arrays.asList(LinphoneManager.getLc().getCallLogs()));
        if (!hideHistoryListAndDisplayMessageIfEmpty()) {
            historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
        }
        expandAllGroups();
    }

    private void initLogsLists(List<LinphoneCallLog> logs) {
        mLogs = new SparseArray<List<LinphoneCallLog>>();
        String[] keys = new String[logs.size()];
        for (LinphoneCallLog log : logs) {
            String groupBy = getCorrespondentDisplayName(log);
            int key = -1;
            for (int k = 0; k < keys.length; k++) {
                if (keys[k] == null || keys[k].equals(groupBy)) {
                    key = k;
                    keys[k] = groupBy;
                    break;
                }
            }

            List<LinphoneCallLog> group = mLogs.get(key, new ArrayList<LinphoneCallLog>());
            group.add(log);
            if (group.size() == 1) {
                mLogs.append(key, group);
            }
        }
    }

    private void initMissedLogsLists(List<LinphoneCallLog> logs) {
        List<LinphoneCallLog> missedLogs = new ArrayList<LinphoneCallLog>();
        for (LinphoneCallLog log : logs) {
            if (log.getDirection() == CallDirection.Incoming && log.getStatus() == CallStatus.Missed) {
                missedLogs.add(log);
            }
        }
        initLogsLists(missedLogs);
    }

    private void expandAllGroups() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                for (int groupToExpand = 0; groupToExpand < historyList.getExpandableListAdapter()
                        .getGroupCount(); groupToExpand++) {
                    if (!historyList.isGroupExpanded(groupToExpand)) {
                        historyList.expandGroup(groupToExpand);
                    }
                }
            }
        });
    }

    private String getCorrespondentDisplayName(LinphoneCallLog log) {
        String displayName;
        LinphoneAddress address;
        if (log.getDirection() == CallDirection.Incoming) {
            address = log.getFrom();
        } else {
            address = log.getTo();
        }

        LinphoneUtils.findUriPictureOfContactAndSetDisplayName(address, getActivity().getContentResolver());
        displayName = address.getDisplayName();
        String sipUri = address.asStringUriOnly();
        if (displayName == null) {
            if (getResources().getBoolean(R.bool.only_display_username_if_unknown)
                    && LinphoneUtils.isSipAddress(sipUri)) {
                displayName = LinphoneUtils.getUsernameFromAddress(sipUri);
            } else {
                displayName = sipUri;
            }
        }

        return displayName;
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.add(0, v.getId(), 0, getString(R.string.delete));
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();

        if (id == R.id.allCalls) {
            allCalls.setEnabled(false);
            missedCalls.setEnabled(true);
            onlyDisplayMissedCalls = false;

            initLogsLists(Arrays.asList(LinphoneManager.getLc().getCallLogs()));
        } else if (id == R.id.missedCalls) {
            allCalls.setEnabled(true);
            missedCalls.setEnabled(false);
            onlyDisplayMissedCalls = true;

            initMissedLogsLists(Arrays.asList(LinphoneManager.getLc().getCallLogs()));
        } else if (id == R.id.ok) {
            edit.setVisibility(View.VISIBLE);
            ok.setVisibility(View.GONE);
            hideDeleteAllButton();
            isEditMode = false;
        } else if (id == R.id.edit) {
            edit.setVisibility(View.GONE);
            ok.setVisibility(View.VISIBLE);
            showDeleteAllButton();
            isEditMode = true;
        } else if (id == R.id.deleteAll) {
            LinphoneManager.getLc().clearCallLogs();
            initLogsLists(new ArrayList<LinphoneCallLog>());
        }

        if (!hideHistoryListAndDisplayMessageIfEmpty()) {
            historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
        }
        expandAllGroups();
    }

    @Override
    public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
        if (isEditMode) {
            for (LinphoneCallLog log : mLogs.get(groupPosition)) {
                LinphoneManager.getLc().removeCallLog(log);
            }

            initLogsLists(Arrays.asList(LinphoneManager.getLc().getCallLogs()));
            if (!hideHistoryListAndDisplayMessageIfEmpty()) {
                historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
            }
            expandAllGroups();
        }
        return false;
    }

    @Override
    public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
        LinphoneCallLog log = mLogs.get(groupPosition).get(childPosition);
        if (isEditMode) {
            LinphoneManager.getLc().removeCallLog(log);
            initLogsLists(Arrays.asList(LinphoneManager.getLc().getCallLogs()));
            if (!hideHistoryListAndDisplayMessageIfEmpty()) {
                historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
            }
            expandAllGroups();
        } else {
            LinphoneAddress address;
            if (log.getDirection() == CallDirection.Incoming) {
                address = log.getFrom();
            } else {
                address = log.getTo();
            }
            LinphoneActivity.instance().setAddresGoToDialerAndCall(address.asStringUriOnly(),
                    address.getDisplayName(), null);
        }
        return false;
    }

    private void hideDeleteAllButton() {
        if (deleteAll == null || deleteAll.getVisibility() != View.VISIBLE) {
            return;
        }

        if (LinphoneActivity.instance().isAnimationDisabled()) {
            deleteAll.setVisibility(View.INVISIBLE);
        } else {
            Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_out_right_to_left);
            animation.setAnimationListener(new AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    deleteAll.setVisibility(View.INVISIBLE);
                    animation.setAnimationListener(null);
                }
            });
            deleteAll.startAnimation(animation);
        }
    }

    private void showDeleteAllButton() {
        if (deleteAll == null || deleteAll.getVisibility() == View.VISIBLE) {
            return;
        }

        if (LinphoneActivity.instance().isAnimationDisabled()) {
            deleteAll.setVisibility(View.VISIBLE);
        } else {
            Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_in_left_to_right);
            animation.setAnimationListener(new AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    deleteAll.setVisibility(View.VISIBLE);
                    animation.setAnimationListener(null);
                }
            });
            deleteAll.startAnimation(animation);
        }
    }

    class CallHistoryAdapter extends BaseExpandableListAdapter {
        private Bitmap missedCall, outgoingCall, incomingCall;

        CallHistoryAdapter(Context aContext) {
            missedCall = BitmapFactory.decodeResource(getResources(), R.drawable.call_status_missed);

            if (!onlyDisplayMissedCalls) {
                outgoingCall = BitmapFactory.decodeResource(getResources(), R.drawable.call_status_outgoing);
                incomingCall = BitmapFactory.decodeResource(getResources(), R.drawable.call_status_incoming);
            }
        }

        @Override
        public Object getChild(int groupPosition, int childPosition) {
            return mLogs.get(groupPosition).get(childPosition);
        }

        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return childPosition;
        }

        @Override
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
                ViewGroup parent) {
            View view = null;
            if (convertView != null) {
                view = convertView;
            } else {
                view = mInflater.inflate(R.layout.history_cell, parent, false);
            }

            final LinphoneCallLog log = (LinphoneCallLog) getChild(groupPosition, childPosition);
            final LinphoneAddress address;

            TextView dateAndTime = (TextView) view.findViewById(R.id.dateAndTime);
            ImageView detail = (ImageView) view.findViewById(R.id.detail);
            ImageView delete = (ImageView) view.findViewById(R.id.delete);
            ImageView callDirection = (ImageView) view.findViewById(R.id.icon);

            if (log.getDirection() == CallDirection.Incoming) {
                address = log.getFrom();
                if (log.getStatus() == CallStatus.Missed) {
                    callDirection.setImageBitmap(missedCall);
                } else {
                    callDirection.setImageBitmap(incomingCall);
                }
            } else {
                address = log.getTo();
                callDirection.setImageBitmap(outgoingCall);
            }

            LinphoneUtils.findUriPictureOfContactAndSetDisplayName(address, view.getContext().getContentResolver());
            String sipUri = address.asStringUriOnly();
            dateAndTime.setText(log.getStartDate() + " " + log.getCallDuration());
            view.setTag(sipUri);

            if (isEditMode) {
                delete.setVisibility(View.VISIBLE);
                detail.setVisibility(View.GONE);
            } else {
                delete.setVisibility(View.GONE);
                detail.setVisibility(View.VISIBLE);
                detail.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (LinphoneActivity.isInstanciated()) {
                            LinphoneActivity.instance().displayHistoryDetail(address.asStringUriOnly(), log);
                        }
                    }
                });
            }

            return view;
        }

        @Override
        public int getChildrenCount(int groupPosition) {
            return mLogs.get(groupPosition).size();
        }

        @Override
        public Object getGroup(int groupPosition) {
            return mLogs.get(groupPosition);
        }

        @Override
        public int getGroupCount() {
            return mLogs.size();
        }

        @Override
        public long getGroupId(int groupPosition) {
            return groupPosition;
        }

        @Override
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
            View view = null;
            if (convertView != null) {
                view = convertView;
            } else {
                view = mInflater.inflate(R.layout.history_group, parent, false);
            }

            LinphoneCallLog log = (LinphoneCallLog) getChild(groupPosition, 0);
            LinphoneAddress address;

            TextView contact = (TextView) view.findViewById(R.id.sipUri);
            ImageView delete = (ImageView) view.findViewById(R.id.delete);

            if (log.getDirection() == CallDirection.Incoming) {
                address = log.getFrom();
            } else {
                address = log.getTo();
            }

            LinphoneUtils.findUriPictureOfContactAndSetDisplayName(address, view.getContext().getContentResolver());
            String displayName = getCorrespondentDisplayName(log);
            String sipUri = address.asStringUriOnly();
            contact.setText(displayName + " (" + getChildrenCount(groupPosition) + ")");
            view.setTag(sipUri);

            if (isEditMode) {
                delete.setVisibility(View.VISIBLE);
            } else {
                delete.setVisibility(View.GONE);
            }

            return view;
        }

        @Override
        public boolean hasStableIds() {
            return false;
        }

        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }
    }
}