ContactListActivity.java
上传用户:szyujian
上传日期:2016-09-20
资源大小:320k
文件大小:16k
源码类别:

android开发

开发平台:

C/C++

  1. /*
  2.  * Copyright (C) 2007-2008 Esmertec AG.
  3.  * Copyright (C) 2007-2008 The Android Open Source Project
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package com.android.im.app;
  18. import com.android.im.IImConnection;
  19. import com.android.im.R;
  20. import com.android.im.plugin.BrandingResourceIDs;
  21. import com.android.im.service.ImServiceConstants;
  22. import android.app.Activity;
  23. import android.content.ContentResolver;
  24. import android.content.ContentUris;
  25. import android.content.Intent;
  26. import android.database.Cursor;
  27. import android.net.Uri;
  28. import android.os.Bundle;
  29. import android.os.Message;
  30. import android.os.RemoteException;
  31. import android.provider.Im;
  32. import android.util.Log;
  33. import android.view.ContextMenu;
  34. import android.view.KeyEvent;
  35. import android.view.LayoutInflater;
  36. import android.view.Menu;
  37. import android.view.MenuInflater;
  38. import android.view.MenuItem;
  39. import android.view.View;
  40. import android.view.Window;
  41. import android.view.ContextMenu.ContextMenuInfo;
  42. import android.widget.AdapterView;
  43. import android.widget.AdapterView.AdapterContextMenuInfo;
  44. import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
  45. import java.util.Observable;
  46. import java.util.Observer;
  47. public class ContactListActivity extends Activity implements View.OnCreateContextMenuListener{
  48.     private static final int MENU_START_CONVERSATION = Menu.FIRST;
  49.     private static final int MENU_VIEW_PROFILE       = Menu.FIRST + 1;
  50.     private static final int MENU_BLOCK_CONTACT      = Menu.FIRST + 2;
  51.     private static final int MENU_DELETE_CONTACT     = Menu.FIRST + 3;
  52.     private static final int MENU_END_CONVERSATION   = Menu.FIRST + 4;
  53.     private static final String FILTER_STATE_KEY = "Filtering";
  54.     ImApp mApp;
  55.     long mProviderId;
  56.     long mAccountId;
  57.     IImConnection mConn;
  58.     ContactListView mContactListView;
  59.     ContactListFilterView mFilterView;
  60.     SimpleAlertHandler mHandler;
  61.     ContextMenuHandler mContextMenuHandler;
  62.     boolean mIsFiltering;
  63.     Im.ProviderSettings.QueryMap mSettingMap;
  64.     boolean mDestroyed;
  65.     @Override
  66.     protected void onCreate(Bundle icicle) {
  67.         super.onCreate(icicle);
  68.         getWindow().requestFeature(Window.FEATURE_LEFT_ICON);
  69.         LayoutInflater inflate = getLayoutInflater();
  70.         mContactListView = (ContactListView) inflate.inflate(
  71.                 R.layout.contact_list_view, null);
  72.         setContentView(mContactListView);
  73.         Intent intent = getIntent();
  74.         mAccountId = intent.getLongExtra(ImServiceConstants.EXTRA_INTENT_ACCOUNT_ID, -1);
  75.         if (mAccountId == -1) {
  76.             finish();
  77.             return;
  78.         }
  79.         mApp = ImApp.getApplication(this);
  80.         ContentResolver cr = getContentResolver();
  81.         Cursor c = cr.query(ContentUris.withAppendedId(Im.Account.CONTENT_URI, mAccountId),
  82.                 null, null, null, null);
  83.         if (c == null) {
  84.             finish();
  85.             return;
  86.         }
  87.         if (!c.moveToFirst()) {
  88.             c.close();
  89.             finish();
  90.             return;
  91.         }
  92.         mProviderId = c.getLong(c.getColumnIndexOrThrow(Im.Account.PROVIDER));
  93.         mHandler = new MyHandler(this);
  94.         String username = c.getString(c.getColumnIndexOrThrow(Im.Account.USERNAME));
  95.         BrandingResources brandingRes = mApp.getBrandingResource(mProviderId);
  96.         setTitle(brandingRes.getString(BrandingResourceIDs.STRING_BUDDY_LIST_TITLE, username));
  97.         getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON,
  98.                 brandingRes.getDrawable(BrandingResourceIDs.DRAWABLE_LOGO));
  99.         mSettingMap = new Im.ProviderSettings.QueryMap(getContentResolver(), mProviderId, true, null);
  100.         mApp.callWhenServiceConnected(mHandler, new Runnable(){
  101.             public void run() {
  102.                 if (!mDestroyed) {
  103.                     mApp.dismissNotifications(mProviderId);
  104.                     mConn = mApp.getConnection(mProviderId);
  105.                     mContactListView.setConnection(mConn);
  106.                     mContactListView.setHideOfflineContacts(mSettingMap.getHideOfflineContacts());
  107.                 }
  108.             }
  109.         });
  110.         mContextMenuHandler = new ContextMenuHandler();
  111.         mContactListView.getListView().setOnCreateContextMenuListener(this);
  112.         mSettingMap.addObserver(new Observer() {
  113.             public void update(Observable observed, Object updateData) {
  114.                 if (!mDestroyed) {
  115.                     mContactListView.setHideOfflineContacts(mSettingMap.getHideOfflineContacts());
  116.                 }
  117.             }
  118.         });
  119.     }
  120.     @Override
  121.     public boolean onCreateOptionsMenu(Menu menu) {
  122.         MenuInflater inflater = getMenuInflater();
  123.         inflater.inflate(R.menu.contact_list_menu, menu);
  124.         BrandingResources brandingRes = mApp.getBrandingResource(mProviderId);
  125.         menu.findItem(R.id.menu_invite_user).setTitle(
  126.             brandingRes.getString(BrandingResourceIDs.STRING_MENU_ADD_CONTACT));
  127.         return true;
  128.     }
  129.     @Override
  130.     public boolean onOptionsItemSelected(MenuItem item) {
  131.         switch (item.getItemId()) {
  132.             case R.id.menu_invite_user:
  133.                 Intent i = new Intent(ContactListActivity.this, AddContactActivity.class);
  134.                 i.putExtra(ImServiceConstants.EXTRA_INTENT_PROVIDER_ID, mProviderId);
  135.                 i.putExtra(ImServiceConstants.EXTRA_INTENT_LIST_NAME,
  136.                         mContactListView.getSelectedContactList());
  137.                 startActivity(i);
  138.                 return true;
  139.             case R.id.menu_blocked_contacts:
  140.                 Uri.Builder builder = Im.BlockedList.CONTENT_URI.buildUpon();
  141.                 ContentUris.appendId(builder, mProviderId);
  142.                 ContentUris.appendId(builder, mAccountId);
  143.                 startActivity(new Intent(Intent.ACTION_VIEW, builder.build()));
  144.                 return true;
  145.             case R.id.menu_view_accounts:
  146.                 Intent intent = new Intent(this, ChooseAccountActivity.class);
  147.                 startActivity(intent);
  148.                 finish();
  149.                 return true;
  150.             case R.id.menu_settings:
  151.                 intent = new Intent(this, SettingActivity.class);
  152.                 intent.putExtra(ImServiceConstants.EXTRA_INTENT_PROVIDER_ID, mProviderId);
  153.                 startActivity(intent);
  154.                 return true;
  155.             case R.id.menu_sign_out:
  156.                 try {
  157.                     mConn.logout();
  158.                 } catch (RemoteException e) {
  159.                 }
  160.                 return true;
  161.         }
  162.         return super.onOptionsItemSelected(item);
  163.     }
  164.     @Override
  165.     protected void onSaveInstanceState(Bundle outState) {
  166.         super.onSaveInstanceState(outState);
  167.         outState.putBoolean(FILTER_STATE_KEY, mIsFiltering);
  168.     }
  169.     @Override
  170.     protected void onRestoreInstanceState(Bundle savedInstanceState) {
  171.         boolean isFiltering = savedInstanceState.getBoolean(FILTER_STATE_KEY);
  172.         if (isFiltering) {
  173.             showFilterView();
  174.         }
  175.         super.onRestoreInstanceState(savedInstanceState);
  176.     }
  177.     @Override
  178.     public boolean dispatchKeyEvent(KeyEvent event) {
  179.         int keyCode = event.getKeyCode();
  180.         boolean handled = false;
  181.         if (mIsFiltering) {
  182.             handled = mFilterView.dispatchKeyEvent(event);
  183.             if (!handled && (KeyEvent.KEYCODE_BACK == keyCode)
  184.                     && (KeyEvent.ACTION_DOWN == event.getAction())) {
  185.                 showContactListView();
  186.                 handled = true;
  187.             }
  188.         } else {
  189.             handled = mContactListView.dispatchKeyEvent(event);
  190.             if (!handled && isReadable(keyCode, event)
  191.                     && (KeyEvent.ACTION_DOWN == event.getAction())) {
  192.                 showFilterView();
  193.                 handled = mFilterView.dispatchKeyEvent(event);
  194.             }
  195.         }
  196.         if (!handled) {
  197.             handled = super.dispatchKeyEvent(event);
  198.         }
  199.         return handled;
  200.     }
  201.     private static boolean isReadable(int keyCode, KeyEvent event) {
  202.         if (KeyEvent.isModifierKey(keyCode) || event.isSystem()) {
  203.             return false;
  204.         }
  205.         switch (keyCode) {
  206.         case KeyEvent.KEYCODE_DPAD_CENTER:
  207.         case KeyEvent.KEYCODE_DPAD_DOWN:
  208.         case KeyEvent.KEYCODE_DPAD_LEFT:
  209.         case KeyEvent.KEYCODE_DPAD_RIGHT:
  210.         case KeyEvent.KEYCODE_DPAD_UP:
  211.         case KeyEvent.KEYCODE_ENTER:
  212.             return false;
  213.         }
  214.         return true;
  215.     }
  216.     private void showFilterView() {
  217.         if (mFilterView == null ) {
  218.             mFilterView = (ContactListFilterView)getLayoutInflater().inflate(
  219.                     R.layout.contact_list_filter_view, null);
  220.             mFilterView.getListView().setOnCreateContextMenuListener(this);
  221.         }
  222.         Uri uri = mSettingMap.getHideOfflineContacts() ? Im.Contacts.CONTENT_URI_ONLINE_CONTACTS_BY
  223.                 : Im.Contacts.CONTENT_URI_CONTACTS_BY;
  224.         uri = ContentUris.withAppendedId(uri, mProviderId);
  225.         uri = ContentUris.withAppendedId(uri, mAccountId);
  226.         mFilterView.doFilter(uri, null);
  227.         setContentView(mFilterView);
  228.         mFilterView.requestFocus();
  229.         mIsFiltering = true;
  230.     }
  231.     void showContactListView() {
  232.         if (mIsFiltering) {
  233.             setContentView(mContactListView);
  234.             mContactListView.requestFocus();
  235.             mContactListView.invalidate();
  236.             mIsFiltering = false;
  237.         }
  238.     }
  239.     @Override
  240.     protected void onPause() {
  241.         super.onPause();
  242.         mApp.unregisterForConnEvents(mHandler);
  243.     }
  244.     @Override
  245.     protected void onResume() {
  246.         super.onResume();
  247.         mApp.registerForConnEvents(mHandler);
  248.     }
  249.     @Override
  250.     protected void onDestroy() {
  251.         mDestroyed = true;
  252.         // set connection to null to unregister listeners.
  253.         mContactListView.setConnection(null);
  254.         if (mSettingMap != null) {
  255.             mSettingMap.close();
  256.         }
  257.         super.onDestroy();
  258.     }
  259.     static void log(String msg) {
  260.         Log.d(ImApp.LOG_TAG, "<ContactListActivity> " +msg);
  261.     }
  262.     @Override
  263.     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
  264.         boolean chatSelected = false;
  265.         boolean contactSelected = false;
  266.         Cursor contactCursor;
  267.         if (mIsFiltering) {
  268.             AdapterView.AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
  269.             mContextMenuHandler.mPosition = info.position;
  270.             contactSelected = true;
  271.             contactCursor = mFilterView.getContactAtPosition(info.position);
  272.         } else {
  273.             ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuInfo;
  274.             mContextMenuHandler.mPosition = info.packedPosition;
  275.             contactSelected = mContactListView.isContactAtPosition(info.packedPosition);
  276.             chatSelected = mContactListView.isConversationAtPosition(info.packedPosition);
  277.             contactCursor = mContactListView.getContactAtPosition(info.packedPosition);
  278.         }
  279.         boolean allowBlock = true;
  280.         if (contactCursor != null) {
  281.             //XXX HACK: Yahoo! doesn't allow to block a friend. We can only block a temporary contact.
  282.             ProviderDef provider = mApp.getProvider(mProviderId);
  283.             if (Im.ProviderNames.YAHOO.equals(provider.mName)) {
  284.                 int type = contactCursor.getInt(contactCursor.getColumnIndexOrThrow(Im.Contacts.TYPE));
  285.                 allowBlock = (type == Im.Contacts.TYPE_TEMPORARY);
  286.             }
  287.             int nickNameIndex = contactCursor.getColumnIndexOrThrow(Im.Contacts.NICKNAME);
  288.             menu.setHeaderTitle(contactCursor.getString(nickNameIndex));
  289.         }
  290.         BrandingResources brandingRes = mApp.getBrandingResource(mProviderId);
  291.         String menu_end_conversation = brandingRes.getString(
  292.                 BrandingResourceIDs.STRING_MENU_END_CHAT);
  293.         String menu_view_profile = brandingRes.getString(
  294.                 BrandingResourceIDs.STRING_MENU_VIEW_PROFILE);
  295.         String menu_block_contact = brandingRes.getString(
  296.                 BrandingResourceIDs.STRING_MENU_BLOCK_CONTACT);
  297.         String menu_start_conversation = brandingRes.getString(
  298.                 BrandingResourceIDs.STRING_MENU_START_CHAT);
  299.         String menu_delete_contact = brandingRes.getString(
  300.                 BrandingResourceIDs.STRING_MENU_DELETE_CONTACT);
  301.         if (chatSelected) {
  302.             menu.add(0, MENU_END_CONVERSATION, 0, menu_end_conversation)
  303.                     .setIcon(R.drawable.ic_menu_end_conversation)
  304.                     .setOnMenuItemClickListener(mContextMenuHandler);
  305.             menu.add(0, MENU_VIEW_PROFILE, 0, menu_view_profile)
  306.                     .setIcon(R.drawable.ic_menu_my_profile)
  307.                     .setOnMenuItemClickListener(mContextMenuHandler);
  308.             if (allowBlock) {
  309.                 menu.add(0, MENU_BLOCK_CONTACT, 0, menu_block_contact)
  310.                         .setIcon(R.drawable.ic_menu_block)
  311.                         .setOnMenuItemClickListener(mContextMenuHandler);
  312.             }
  313.         } else if (contactSelected) {
  314.             menu.add(0, MENU_START_CONVERSATION, 0, menu_start_conversation)
  315.                     .setIcon(R.drawable.ic_menu_start_conversation)
  316.                     .setOnMenuItemClickListener(mContextMenuHandler);
  317.             menu.add(0, MENU_VIEW_PROFILE, 0, menu_view_profile)
  318.                     .setIcon(R.drawable.ic_menu_view_profile)
  319.                     .setOnMenuItemClickListener(mContextMenuHandler);
  320.             if (allowBlock) {
  321.                 menu.add(0, MENU_BLOCK_CONTACT, 0, menu_block_contact)
  322.                         .setIcon(R.drawable.ic_menu_block)
  323.                         .setOnMenuItemClickListener(mContextMenuHandler);
  324.             }
  325.             menu.add(0, MENU_DELETE_CONTACT, 0, menu_delete_contact)
  326.                     .setIcon(android.R.drawable.ic_menu_delete)
  327.                     .setOnMenuItemClickListener(mContextMenuHandler);
  328.         }
  329.     }
  330.     final class ContextMenuHandler implements MenuItem.OnMenuItemClickListener {
  331.         long mPosition;
  332.         public boolean onMenuItemClick(MenuItem item) {
  333.             Cursor c;
  334.             if (mIsFiltering) {
  335.                 c = mFilterView.getContactAtPosition((int)mPosition);
  336.             } else {
  337.                 c = mContactListView.getContactAtPosition(mPosition);
  338.             }
  339.             switch (item.getItemId()) {
  340.             case MENU_START_CONVERSATION:
  341.                 mContactListView.startChat(c);
  342.                 break;
  343.             case MENU_VIEW_PROFILE:
  344.                 mContactListView.viewContactPresence(c);
  345.                 break;
  346.             case MENU_BLOCK_CONTACT:
  347.                 mContactListView.blockContact(c);
  348.                 break;
  349.             case MENU_DELETE_CONTACT:
  350.                 mContactListView.removeContact(c);
  351.                 break;
  352.             case MENU_END_CONVERSATION:
  353.                 mContactListView.endChat(c);
  354.                 break;
  355.             default:
  356.                 return false;
  357.             }
  358.             if (mIsFiltering) {
  359.                 showContactListView();
  360.             }
  361.             return true;
  362.         }
  363.     }
  364.     final class MyHandler extends SimpleAlertHandler {
  365.         public MyHandler(Activity activity) {
  366.             super(activity);
  367.         }
  368.         @Override
  369.         public void handleMessage(Message msg) {
  370.             if (msg.what == ImApp.EVENT_CONNECTION_DISCONNECTED) {
  371.                 if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)) {
  372.                     log("Handle event connection disconnected.");
  373.                 }
  374.                 promptDisconnectedEvent(msg);
  375.                 long providerId = ((long)msg.arg1 << 32) | msg.arg2;
  376.                 if (providerId == mProviderId) {
  377.                     if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)) {
  378.                         log("Current connection disconnected, finish");
  379.                     }
  380.                     finish();
  381.                 }
  382.                 return;
  383.             }
  384.             super.handleMessage(msg);
  385.         }
  386.     }
  387. }