org.xingjitong.ContactsFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.xingjitong.ContactsFragment.java

Source

package org.xingjitong;

/*
 ContactsFragment.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.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.linphone.core.LinphoneFriend;
import org.linphone.core.LinphoneProxyConfig;
import org.linphone.core.OnlineStatus;
import org.wecarephone.R;
import org.xingjitong.LinphoneManager.AddressType;
import org.xingjitong.compatibility.Compatibility;
import org.xingjitong.tang.db.AssetsDatabaseManager;
import org.xingjitong.tang.db.ContactDB;
import org.xingjitong.tang.db.DatabaseDAO;
import org.xingjitong.tang.set.UserConfig;
import org.xingjitong.ui.AddressText;
import org.xingjitong.ui.ContactView;
import org.xingjitong.ui.SearchText;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.AlphabetIndexer;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SectionIndexer;
import android.widget.TextView;
import android.widget.Toast;

/**
 * @author Sylvain Berfini
 *  ?
 */
public class ContactsFragment extends Fragment implements OnClickListener, OnItemClickListener {
    private Handler mHandler = new Handler();

    private LayoutInflater mInflater;
    private ListView contactsList;// ---------
    private TextView allContacts, linphoneContacts, newContact, noSipContact, noContact, show_img;
    private boolean onlyDisplayLinphoneContacts;
    private AlphabetIndexer indexer;
    private boolean editOnClick = false, editConsumed = false, onlyDisplayChatAddress = false;
    private String sipAddressToAdd;
    private Map<String, Integer> ints;
    private SearchText search_text;
    private Runnable thread;
    private List<String> list_str;
    int ttype;
    private Object[] os;
    private ContactView abc;
    private String str = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private int margin;
    private Bitmap bitmapUnknown;
    private String reg = "^[A-Za-z]+$";
    //yyppdialog add
    private App app;
    int mSingleChoiceID = -1;
    final String[] mItems = { "", "?", "?", "?" };
    //yyppdilog end

    public SQLiteDatabase sqliteDB;
    public DatabaseDAO dao;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        if (LinphoneActivity.isInstanciated()) {
            LinphoneActivity.instance().changeContacts(this);
        }
        ContactDB.Instance().setContactsFragment(this);
        this.margin = LinphoneUtils.pixelsToDpi(getResources(), 10);
        this.bitmapUnknown = BitmapFactory.decodeResource(getResources(), R.drawable.unknown_small);

        app = (App) getActivity().getApplication(); //yyppdial
        AssetsDatabaseManager.initManager(app);
        AssetsDatabaseManager mg = AssetsDatabaseManager.getAssetsDatabaseManager();
        sqliteDB = mg.getDatabase("number_location.zip");
        dao = new DatabaseDAO(sqliteDB);
    }

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

        if (getArguments() != null) {
            editOnClick = getArguments().getBoolean("EditOnClick");
            sipAddressToAdd = getArguments().getString("SipAddress");

            onlyDisplayChatAddress = getArguments().getBoolean("ChatAddressOnly");
        }

        noSipContact = (TextView) view.findViewById(R.id.noSipContact);
        noContact = (TextView) view.findViewById(R.id.noContact);

        contactsList = (ListView) view.findViewById(R.id.contactsList);

        contactsList.setOnItemClickListener(this);
        allContacts = (TextView) view.findViewById(R.id.allContacts);
        allContacts.setOnClickListener(this);
        allContacts.setVisibility(View.GONE);//yujingjie add //yyppset
        abc = (ContactView) view.findViewById(R.id.contacts_list_abc);
        linphoneContacts = (TextView) view.findViewById(R.id.linphoneContacts);
        linphoneContacts.setOnClickListener(this);
        linphoneContacts.setVisibility(View.GONE);//yujingjie add //yyppset

        newContact = (TextView) view.findViewById(R.id.newContact);
        newContact.setOnClickListener(this);
        newContact.setEnabled(LinphoneManager.getLc().getCallsNb() == 0);

        allContacts.setEnabled(onlyDisplayLinphoneContacts);
        linphoneContacts.setEnabled(!allContacts.isEnabled());
        list_str = new ArrayList<String>();
        search_text = (SearchText) view.findViewById(R.id.contacts_list_search_text);
        search_text.setFragment(this);
        show_img = (TextView) view.findViewById(R.id.contasts_img);
        show_img.setVisibility(View.INVISIBLE);
        thread = new Runnable() {
            @Override
            public void run() {
                show_img.setVisibility(View.GONE);
            }
        };
        abc.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getMetaState() == MotionEvent.ACTION_DOWN) {
                    int h = abc.getHeight();
                    int t = h % 27 == 0 ? h / 27 : h / 27 + 1;
                    float s = event.getY();
                    int i = (int) (s % t == 0 ? s / t : s / t + 1);
                    if (i > 26) {
                        i = 26;
                    } else if (i < 0) {
                        i = 0;
                    }
                    String key = str.substring(i, i + 1);
                    showImg(key);
                    if ("#".equals(key)) {
                        contactsList.setSelection(0);
                        return true;
                    }
                    if (list_str.contains(key)) {
                        // adapter_abc.setOnClick(arg2);
                        if ("@".equals(key)) {
                            key = "#";
                        }
                        contactsList.setSelection(ints.get(key));
                    }
                }
                return true;
            }

        });
        onLongClickListView(); //yyppdialog add
        return view;
    }

    //yyypp add
    private int getnumtype(String numstr) {
        if (numstr == null || numstr.length() == 0) {
            //("??!");
            return 1;
        }
        if (numstr.length() < 6) {

            //("???!");
            return 2;
        }
        if (!numstr.toString().startsWith("0") && !numstr.toString().startsWith("1")
                && !numstr.toString().startsWith("+")) {
            //("??!");
            return 3;
        } else
            return 0;

        //("??!");   
        //("???!");
        //("??!");
    }

    //yypp end   
    //yyppdialog add
    //yyppcall add
    public void setAddresGoToDialerAndCall(String number, String name, Uri photo) {
        String reg = "^[\\+]?[0-9\\-\\ ]{6,32}$";
        if (!number.matches(reg)) {
            Toast.makeText(getActivity(), "??!", Toast.LENGTH_SHORT).show();
            return;
        }
        //yyppnotice add
        if (UserConfig.getInstance().loginstatus != 0) {
            Toast.makeText(getActivity(), "?!", Toast.LENGTH_SHORT).show();
        }

        Bundle extras = new Bundle();
        extras.putString("SipUri", number);
        extras.putString("DisplayName", name);
        extras.putString("Photo", photo == null ? null : photo.toString());
        Log.i("alexkaer", "wecareSipUri=" + number + "DisplayName=" + name);
        AddressType address = new AddressText(getActivity(), null);
        address.setDisplayedName(name);
        address.setText(number);
        if (LinphoneManager.getLc().getCallsNb() == 0) {
            LinphoneManager.getInstance().newOutgoingCall(address);
            app.setCallNum(number);
        }
    }

    //yyppcall end
    OnItemLongClickListener itemLongClick = new OnItemLongClickListener() {

        @SuppressLint("NewApi")
        @Override
        public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id) {
            Log.v("yyppdebug", "yyppdialog: longclick 0000");
            //show dialog
            /* 
            new AlertDialog.Builder(getActivity()).setTitle("?").setMultiChoiceItems(
            new String[] { "", "?","?","?" }, null, null)
            .setPositiveButton("", null)
            .setNegativeButton("?", null).show();
            */
            final Contact mcontact = (Contact) adapter.getItemAtPosition(position);

            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(),
                    AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);

            String tmpnum = null;

            for (String numberOrAddress : mcontact.getNumerosOrAddresses()) {
                //yyppdialog

                tmpnum = numberOrAddress;
            }
            final String finalNumberOrAddress = tmpnum;
            //          Log.v("yyppdebug", "yyppdialog num:"+finalNumberOrAddress);
            //          Log.v("yyppdebug", "yyppdialog mcontact.getNum():"+mcontact.getNum());
            //--------------------

            //--------------------      

            mSingleChoiceID = -1;
            //builder.setIcon(R.drawable.icon);  
            builder.setTitle(mcontact.getName()); //"?"
            builder.setSingleChoiceItems(mItems, 0, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {
                    mSingleChoiceID = whichButton;
                    //Toast.makeText(getActivity(), ""+mSingleChoiceID+"",Toast.LENGTH_LONG).show();
                    dialog.dismiss();
                    switch (mSingleChoiceID) {
                    case 0: //

                        //Contact contact = (Contact) adapter.getItemAtPosition(position);

                        //lastKnownPosition = contactsList.getFirstVisiblePosition();

                        LinphoneActivity.instance().displayContact(mcontact, onlyDisplayChatAddress);

                        Log.v("yyppdebug", "yyppdialog 111:" + "");

                        break;
                    case 1: //?    
                        //("??!");   
                        //("???!");
                        //("??!");
                        if (getnumtype(mcontact.getNum()) == 1) {
                            Toast.makeText(getActivity(), "??!!!", Toast.LENGTH_LONG).show();
                        } else if (getnumtype(mcontact.getNum()) == 2) {
                            Toast.makeText(getActivity(), "???!", Toast.LENGTH_LONG).show();
                        } else if (getnumtype(mcontact.getNum()) == 3) {
                            Toast.makeText(getActivity(), "??!", Toast.LENGTH_LONG).show();

                        } else if (LinphoneActivity.isInstanciated() && getnumtype(mcontact.getNum()) == 0) {

                            //LinphoneActivity.instance().
                            setAddresGoToDialerAndCall(mcontact.getNum(), mcontact.getName(),
                                    mcontact.getPhotoUri());
                            return;
                        }

                        break;
                    case 2: //?

                        LinphoneActivity.instance().editContact(mcontact);
                        break;
                    case 3: //?
                        //??
                        AlertDialog.Builder buildernew = new AlertDialog.Builder(getActivity(),
                                AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
                        String tmpmsg = "?";
                        buildernew.setIconAttribute(android.R.attr.alertDialogIcon);
                        buildernew.setTitle(mcontact.getName());
                        buildernew.setMessage(tmpmsg);

                        buildernew.setPositiveButton("", new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                //-------------------------------
                                //
                                int contactID;
                                contactID = Integer.parseInt(mcontact.getID());
                                final String where = ContactsContract.Data.CONTACT_ID + " = ?";
                                final String[] selectionArgs = new String[] { String.valueOf(contactID) };
                                try {
                                    new Thread() {
                                        public void run() {
                                            ContactDB.Instance().removeContact(mcontact);
                                            getActivity().getContentResolver().delete(
                                                    ContactsContract.RawContacts.CONTENT_URI, where, selectionArgs);
                                        };
                                    }.start();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }

                                LinphoneActivity.instance().displayContacts(false);
                                //-------------------------------                                 // TODO Auto-generated method stub

                            }
                        }).setNegativeButton("?", new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                // TODO Auto-generated method stub

                            }
                        });

                        buildernew.create().show();

                        //---------------------------------------------------------
                        //---------------------------------------------------------                             

                        break;
                    default: //?

                        break;
                    }

                }
            });
            /*
            builder.setPositiveButton("", new DialogInterface.OnClickListener() {  
               public void onClick(DialogInterface dialog, int whichButton) {  
                   if(mSingleChoiceID > 0) {  
                       
                
                   }  
               }  
            });  
            */
            builder.setNegativeButton("?", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int whichButton) {

                }
            });
            builder.create().show();

            return false;//let the window create menu
        }
    };

    void onLongClickListView() {
        contactsList.setOnItemLongClickListener(itemLongClick);
        registerForContextMenu(contactsList);
    }

    //yyppdialog end

    @SuppressWarnings("unchecked")
    private void setAbcAdapter(int type) {
        switch (type) {
        case 0:
            os = ContactDB.Instance().getAllOb();
            break;
        case 1:
            os = ContactDB.Instance().getSipOb();
            break;
        }
        if (os == null) {
            os = new Object[3];
            os[0] = new LinkedList<String>();
            os[1] = new HashMap<String, Integer>();
            os[2] = new LinkedList<Contact>();
        }
        ints = (Map<String, Integer>) os[1];
        list_str = (List<String>) os[0];
        if (abc != null)
            abc.setData(ints);
    }

    public synchronized void changeData() {
        if (onlyDisplayLinphoneContacts)
            ttype = 1;
        else
            ttype = 0;
        mHandler.post(new Runnable() {

            @Override
            public void run() {
                changeContactsAdapter();
            }
        });
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
        case R.id.allContacts:
            if (search_text != null)
                search_text.setText("");
            onlyDisplayLinphoneContacts = false;
            changeContactsAdapter();
            break;
        case R.id.linphoneContacts:
            if (search_text != null)
                search_text.setText("");
            onlyDisplayLinphoneContacts = true;
            changeContactsAdapter();
            break;
        case R.id.newContact:
            editConsumed = true;
            LinphoneActivity.instance().addContact(null, sipAddressToAdd);
            break;
        }
    }

    @SuppressLint("DefaultLocale")
    @SuppressWarnings("unchecked")
    public synchronized void search(String str) {
        if (str == null || "".equals(str)) {
            changeData();
            return;
        }
        if (str.matches(reg)) {
            if (ints.containsKey(str.toUpperCase())) {
                contactsList.setSelection(ints.get(str.toUpperCase()));
                return;
            }
        }
        List<Contact> list = new ArrayList<Contact>();
        List<Contact> lists = new ArrayList<Contact>();
        if (os != null) {
            list = (List<Contact>) os[2];
        }
        if (list.size() == 0) {
            return;
        }
        for (Contact contact : list) {
            if (contact.name.indexOf(str) > -1) {
                if (!lists.contains(contact)) {
                    lists.add(contact);
                    continue;
                }
            } else if (contact.num.indexOf(str) > -1) {
                if (!lists.contains(contact)) {
                    lists.add(contact);
                    continue;
                }
            }
        }
        ContactsListAdapter adapter = new ContactsListAdapter(lists, this.bitmapUnknown, margin);
        contactsList.setAdapter(adapter);
    }

    @SuppressWarnings("unchecked")
    private void changeContactsAdapter() {
        changeContactsToggle();
        // ------------
        Cursor allContactsCursor = null, sipContactsCursor = null;
        if (LinphoneActivity.isInstanciated())
            allContactsCursor = LinphoneActivity.instance().getAllContactsCursor();
        if (LinphoneActivity.isInstanciated())
            sipContactsCursor = LinphoneActivity.instance().getSIPContactsCursor();
        if (allContactsCursor == null || sipContactsCursor == null) {
            return;
        }
        if (noSipContact != null)
            noSipContact.setVisibility(View.GONE);
        if (noContact != null)
            noContact.setVisibility(View.GONE);
        if (contactsList != null)
            contactsList.setVisibility(View.VISIBLE);

        if (onlyDisplayLinphoneContacts) {
            if (sipContactsCursor.getCount() == 0) {
                if (noSipContact != null)
                    noSipContact.setVisibility(View.VISIBLE);
                if (abc != null)
                    abc.setVisibility(View.GONE);
                if (contactsList != null)
                    contactsList.setVisibility(View.GONE);
            } else {
                if (abc != null)
                    abc.setVisibility(View.VISIBLE);
                indexer = new AlphabetIndexer(sipContactsCursor,
                        Compatibility.getCursorDisplayNameColumnIndex(sipContactsCursor),
                        " ABCDEFGHIJKLMNOPQRSTUVWXYZ");
                setAbcAdapter(1);
                List<Contact> lists;
                if (os != null)
                    lists = (List<Contact>) os[2];
                else
                    lists = new ArrayList<Contact>();
                ContactsListAdapter adapter = new ContactsListAdapter(lists, this.bitmapUnknown, margin);
                if (contactsList != null)
                    contactsList.setAdapter(adapter);// sipContactsCursor
            }
        } else {
            if (allContactsCursor.getCount() == 0) {
                if (noContact != null)
                    noContact.setVisibility(View.VISIBLE);
                if (contactsList != null)
                    contactsList.setVisibility(View.GONE);
                if (abc != null)
                    abc.setVisibility(View.GONE);
            } else {
                if (abc != null)
                    abc.setVisibility(View.VISIBLE);
                indexer = new AlphabetIndexer(allContactsCursor,
                        Compatibility.getCursorDisplayNameColumnIndex(allContactsCursor),
                        " ABCDEFGHIJKLMNOPQRSTUVWXYZ");
                setAbcAdapter(0);
                List<Contact> lists;
                if (os != null)
                    lists = (List<Contact>) os[2];
                else
                    lists = new ArrayList<Contact>();
                ContactsListAdapter adapter = new ContactsListAdapter(lists, this.bitmapUnknown, margin);
                if (contactsList != null)
                    contactsList.setAdapter(adapter);// , allContactsCursor
            }
        }
        LinphoneActivity.instance().setLinphoneContactsPrefered(onlyDisplayLinphoneContacts);
        allContactsCursor.close();
        sipContactsCursor.close();
    }

    private void changeContactsToggle() {
        if (onlyDisplayLinphoneContacts) {
            if (allContacts != null)
                allContacts.setEnabled(true);
            if (linphoneContacts != null)
                linphoneContacts.setEnabled(false);
        } else {
            if (allContacts != null)
                allContacts.setEnabled(false);
            if (linphoneContacts != null)
                linphoneContacts.setEnabled(true);
        }
    }

    private void showImg(final String str) {
        show_img.setText(str);
        show_img.setVisibility(View.VISIBLE);
        mHandler.removeCallbacks(thread);
        mHandler.postDelayed(thread, 1500);
    }

    @Override
    public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
        Contact contact = (Contact) adapter.getItemAtPosition(position);
        final Contact finalcontact = contact; //yyppdialog//yyppdial
        if (editOnClick) {
            editConsumed = true;
            LinphoneActivity.instance().editContact(contact, sipAddressToAdd);
        } else {
            //yyppcall del begin
            /*
            //lastKnownPosition = contactsList.getFirstVisiblePosition();
            Log.v("yyppdebug", "yyppdialog 555:"+position);
            LinphoneActivity.instance().displayContact(contact,
                  onlyDisplayChatAddress);
                  */
            //yyppcall del end

            //---------------------------------------------------------
            //---------------------------------------------------------                  
            //String tmpmsg="?,?????????4000251688?";
            String tmpmsg = getResources().getString(R.string.calldialog_hint);

            final customdialog ad = new customdialog(getActivity());
            ad.setTitle(contact.getName());
            String tmpstr1 = ad.ToDBC(tmpmsg);
            String tmpstr2 = ad.ToDBC(tmpstr1);
            if (contact.photo != null) {
                ad.setHead(contact.photo);
            }
            //                           ad.setMessage(ad.StringFilter(tmpstr2));

            ad.setPositiveButton("?", new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    ad.dismiss();
                    //Toast.makeText(getActivity(), "", Toast.LENGTH_LONG).show();
                    //?

                    String number = finalcontact.getNum();
                    String name = finalcontact.getName();
                    if (getnumtype(number) == 1) {
                        Toast.makeText(getActivity(), "??!!!", Toast.LENGTH_LONG).show();
                    } else if (getnumtype(number) == 2) {
                        Toast.makeText(getActivity(), "???!", Toast.LENGTH_LONG).show();
                    } else if (getnumtype(number) == 3) {
                        Toast.makeText(getActivity(), "??!", Toast.LENGTH_LONG).show();
                    } else if (getnumtype(number) == 0) {

                        //LinphoneActivity.instance().
                        setAddresGoToDialerAndCall(number, name, null);
                    }
                    //??         
                    //-------------------------------
                }
            });

            ad.setNegativeButton("?", new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    ad.dismiss();
                    //Toast.makeText(getActivity(), "?", Toast.LENGTH_LONG).show();
                }
            });
            //---------------------------------------------------------                       
            //---------------------------------------------------------               

        }
    }

    @Override
    public void onResume() {
        super.onResume();

        if (editConsumed) {
            editOnClick = false;
            sipAddressToAdd = null;
        }

        if (LinphoneActivity.isInstanciated()) {
            LinphoneActivity.instance().selectMenu(FragmentsAvailable.CONTACTS);
            onlyDisplayLinphoneContacts = LinphoneActivity.instance().isLinphoneContactsPrefered();
        }
        invalidate();

    }

    public void invalidate() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                changeContactsAdapter();
                //contactsList.setSelectionFromTop(lastKnownPosition, 0);
            }
        });
    }

    class ContactsListAdapter extends BaseAdapter implements SectionIndexer {
        private int margin;
        private Bitmap bitmapUnknown;
        private List<Contact> contacts;

        ContactsListAdapter(List<Contact> contactsList, Bitmap bitmapUnknown, int margin) {
            contacts = contactsList;
            this.margin = margin;
            // margin = LinphoneUtils.pixelsToDpi(context.getResources(), 10);
            this.bitmapUnknown = bitmapUnknown;
        }

        public Object getItem(int position) {
            return contacts.get(position);
        }

        public long getItemId(int position) {
            return position;
        }

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return contacts.size();
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            Contact contact = null;
            ViewHolder holder;
            if (convertView != null) {
                holder = (ViewHolder) convertView.getTag();
            } else {
                convertView = mInflater.inflate(R.layout.contact_cell, parent, false);
                holder = new ViewHolder();
                holder.name = (TextView) convertView.findViewById(R.id.name);
                holder.separator = (TextView) convertView.findViewById(R.id.separator);
                holder.addr = (TextView) convertView.findViewById(R.id.contact_cell_addr);
                holder.layout = (LinearLayout) convertView.findViewById(R.id.layout);
                holder.num = (TextView) convertView.findViewById(R.id.contact_cell_num);
                holder.icon = (ImageView) convertView.findViewById(R.id.icon);
                holder.friendStatus = (ImageView) convertView.findViewById(R.id.friendStatus);
                convertView.setTag(holder);
            }
            contact = contacts.get(position);
            holder.name.setText(contact.name);
            holder.num.setText(contact.num);

            Map<String, String> map = new HashMap<String, String>();
            String prefix, center;
            String[] arr = contact.num.split(" ");
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < arr.length; i++) {
                sb.append(arr[i]);
            }
            String namexx = sb.toString();
            if (isZeroStarted(namexx) && getNumLength(namexx) > 2) {
                prefix = getAreaCodePrefix(namexx);
                map = dao.queryAeraCode(prefix);

            } else if (!isZeroStarted(namexx) && getNumLength(namexx) > 6) {
                prefix = getMobilePrefix(namexx).trim();
                center = getCenterNumber(namexx).trim();
                map = dao.queryNumber(prefix, center);
            }

            if (map != null) {
                String province = map.get("province");
                String city = map.get("city");

                if (province == null || city == null || province.isEmpty() || city.isEmpty()) {
                    holder.addr.setText("");
                } else if (province.equals(city))
                    holder.addr.setText(province);
                else {
                    holder.addr.setText(province + " " + city);
                }
            } else {
                holder.addr.setText("");
            }

            String key = "";
            if ("@".equals(contact.sort_key)) {
                key = "#";
            } else {
                key = contact.sort_key;
            }
            if (position == ints.get(key)) {
                holder.separator.setVisibility(View.VISIBLE);
                holder.separator.setText(key);// -------------;
                holder.layout.setPadding(0, 0, 0, margin);
            } else {
                holder.separator.setVisibility(View.GONE);
                holder.layout.setPadding(0, margin, 0, margin);
            }

            if (contact.getPhoto() != null) {
                holder.icon.setImageBitmap(contact.getPhoto());
            } else if (contact.getPhotoUri() != null) {
                holder.icon.setImageURI(contact.getPhotoUri());
            } else {
                holder.icon.setImageBitmap(bitmapUnknown);
            }

            LinphoneFriend friend = contact.getFriend();
            if (!LinphoneActivity.instance().isContactPresenceDisabled() && friend != null) {
                holder.friendStatus.setVisibility(View.VISIBLE);
                if (friend.getStatus() == OnlineStatus.Online) {
                    //               holder.friendStatus
                    //                     .setImageResource(R.drawable.led_connected);
                } else if (friend.getStatus() == OnlineStatus.Busy
                        || friend.getStatus() == OnlineStatus.DoNotDisturb) {
                    //               holder.friendStatus.setImageResource(R.drawable.led_error);
                } else if (friend.getStatus() == OnlineStatus.Away
                        || friend.getStatus() == OnlineStatus.BeRightBack) {
                    //               holder.friendStatus
                    //                     .setImageResource(R.drawable.led_inprogress);
                } else if (friend.getStatus() == OnlineStatus.Offline) {
                    //               holder.friendStatus
                    //                     .setImageResource(R.drawable.led_disconnected);
                } else {
                    //               holder.friendStatus
                    //                     .setImageResource(R.drawable.call_quality_indicator_0);
                }
            }

            return convertView;
        }

        @Override
        public int getPositionForSection(int section) {
            return indexer.getPositionForSection(section);
        }

        @Override
        public int getSectionForPosition(int position) {
            return indexer.getSectionForPosition(position);
        }

        @Override
        public Object[] getSections() {
            return indexer.getSections();
        }
    }

    private class ViewHolder {
        TextView name;
        TextView num;
        TextView addr;
        TextView separator;
        LinearLayout layout;
        ImageView icon;
        ImageView friendStatus;
    }

    //

    /**???????*/
    public String getAreaCodePrefix(String number) {
        if (number.charAt(1) == '1' || number.charAt(1) == '2')
            return number.substring(1, 3);
        return number.substring(1, 4);
    }

    /**????*/
    public String getMobilePrefix(String number) {
        return number.substring(0, 3);
    }

    /**????????*/
    public String getCenterNumber(String number) {
        return number.substring(3, 7);
    }

    /**???*/
    public boolean isZeroStarted(String number) {
        if (number == null || number.isEmpty()) {
            return false;
        }
        return number.charAt(0) == '0';
    }

    /**??*/
    public int getNumLength(String number) {
        if (number == null || number.isEmpty())
            return 0;
        return number.length();
    }
}