14cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann/* 2ef3f8f045ed4150caa64749742227acd0e6b85d8Daniel Lehmann * Copyright (C) 2010 The Android Open Source Project 34cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * 44cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * Licensed under the Apache License, Version 2.0 (the "License"); 54cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * you may not use this file except in compliance with the License. 64cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * You may obtain a copy of the License at 74cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * 84cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * http://www.apache.org/licenses/LICENSE-2.0 94cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * 104cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * Unless required by applicable law or agreed to in writing, software 114cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * distributed under the License is distributed on an "AS IS" BASIS, 124cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * See the License for the specific language governing permissions and 144cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann * limitations under the License 154cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann */ 164cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann 174cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannpackage com.android.contacts.activities; 184cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann 192eb969cc399d87b659a45568fa951d394c216917Katherine Kuanimport android.app.ActionBar; 2079700889dad553dcde9e22a2fd23df768f68080fKatherine Kuanimport android.app.Fragment; 2160be1a1e8639a58d16f58686f8a89747d6079cc7Daniel Lehmannimport android.content.ActivityNotFoundException; 22caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikovimport android.content.ContentValues; 23078d08f5e497231cbe7fb520b5a4e42a398201a6Chiao Chengimport android.content.Context; 2418f104fa8c167a510b2cca3c15a43833c9a54c7cDaniel Lehmannimport android.content.Intent; 25c2687c3c38d8fb5f34ad6d8fb5c33e16f335183cDaniel Lehmannimport android.net.Uri; 264cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.os.Bundle; 272eb969cc399d87b659a45568fa951d394c216917Katherine Kuanimport android.os.Handler; 28d6272412cdf3fdda90e835ec5b0cd1e15a0c97c9Daisuke Miyakawaimport android.text.TextUtils; 294cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.util.Log; 304cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmannimport android.view.KeyEvent; 31942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuanimport android.view.Menu; 32942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuanimport android.view.MenuInflater; 33942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuanimport android.view.MenuItem; 342a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmannimport android.view.MenuItem.OnMenuItemClickListener; 352eb969cc399d87b659a45568fa951d394c216917Katherine Kuanimport android.view.View; 36d6272412cdf3fdda90e835ec5b0cd1e15a0c97c9Daisuke Miyakawaimport android.view.accessibility.AccessibilityEvent; 37d6272412cdf3fdda90e835ec5b0cd1e15a0c97c9Daisuke Miyakawaimport android.view.accessibility.AccessibilityManager; 38caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikovimport android.widget.Toast; 39caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov 40e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.ContactSaveService; 41e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.ContactsActivity; 42e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R; 43e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.detail.ContactDetailDisplayUtils; 44e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.detail.ContactDetailFragment; 45e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.detail.ContactDetailLayoutController; 46e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.detail.ContactLoaderFragment; 47e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.detail.ContactLoaderFragment.ContactLoaderFragmentListener; 48e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.interactions.ContactDeletionInteraction; 49851222a96b5d68602fb361ea3527101e893f67e3Maurice Chuimport com.android.contacts.model.Contact; 50428f008513d1591cc08fcfe2cf0c9237fb313241Chiao Chengimport com.android.contacts.common.model.account.AccountWithDataSet; 51e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.util.PhoneCapabilityTester; 52e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng 53caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikovimport java.util.ArrayList; 544cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann 556f667b55687bf9193323802e8f3234f0ab254388Dmitri Plotnikovpublic class ContactDetailActivity extends ContactsActivity { 564cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann private static final String TAG = "ContactDetailActivity"; 574cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann 582a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann /** Shows a toogle button for hiding/showing updates. Don't submit with true */ 592a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann private static final boolean DEBUG_TRANSITIONS = false; 602a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann 61851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu private Contact mContactData; 62942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan private Uri mLookupUri; 63942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan 6451f1071a1dc91dace0de73be1c5fbba4f091f054Katherine Kuan private ContactDetailLayoutController mContactDetailLayoutController; 652eb969cc399d87b659a45568fa951d394c216917Katherine Kuan private ContactLoaderFragment mLoaderFragment; 662eb969cc399d87b659a45568fa951d394c216917Katherine Kuan 672eb969cc399d87b659a45568fa951d394c216917Katherine Kuan private Handler mHandler = new Handler(); 682eb969cc399d87b659a45568fa951d394c216917Katherine Kuan 694cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann @Override 706fa7384a1a5576ace18159de61af91c8b7c34dc6Dave Santoro protected void onCreate(Bundle savedState) { 714cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann super.onCreate(savedState); 72c90c705db8b3665ba9c8d8ce4b8ab3a03e38ddc7Daniel Lehmann if (PhoneCapabilityTester.isUsingTwoPanes(this)) { 73c90c705db8b3665ba9c8d8ce4b8ab3a03e38ddc7Daniel Lehmann // This activity must not be shown. We have to select the contact in the 745e684a424e7036ba3d379221d1889b4dd7265021Dave Santoro // PeopleActivity instead ==> Create a forward intent and finish 75c90c705db8b3665ba9c8d8ce4b8ab3a03e38ddc7Daniel Lehmann final Intent originalIntent = getIntent(); 76c90c705db8b3665ba9c8d8ce4b8ab3a03e38ddc7Daniel Lehmann Intent intent = new Intent(); 77c90c705db8b3665ba9c8d8ce4b8ab3a03e38ddc7Daniel Lehmann intent.setAction(originalIntent.getAction()); 78c90c705db8b3665ba9c8d8ce4b8ab3a03e38ddc7Daniel Lehmann intent.setDataAndType(originalIntent.getData(), originalIntent.getType()); 79d0414e5bd478444a9360c95258c267373f02554bDaniel Lehmann 80d0414e5bd478444a9360c95258c267373f02554bDaniel Lehmann // If we are launched from the outside, we should create a new task, because the user 81d0414e5bd478444a9360c95258c267373f02554bDaniel Lehmann // can freely navigate the app (this is different from phones, where only the UP button 82d0414e5bd478444a9360c95258c267373f02554bDaniel Lehmann // kicks the user into the full app) 83d0414e5bd478444a9360c95258c267373f02554bDaniel Lehmann if (shouldUpRecreateTask(intent)) { 84d0414e5bd478444a9360c95258c267373f02554bDaniel Lehmann intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | 85d0414e5bd478444a9360c95258c267373f02554bDaniel Lehmann Intent.FLAG_ACTIVITY_TASK_ON_HOME); 86d0414e5bd478444a9360c95258c267373f02554bDaniel Lehmann } else { 87d0414e5bd478444a9360c95258c267373f02554bDaniel Lehmann intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | 88d0414e5bd478444a9360c95258c267373f02554bDaniel Lehmann Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_SINGLE_TOP | 89d0414e5bd478444a9360c95258c267373f02554bDaniel Lehmann Intent.FLAG_ACTIVITY_CLEAR_TOP); 90d0414e5bd478444a9360c95258c267373f02554bDaniel Lehmann } 91c90c705db8b3665ba9c8d8ce4b8ab3a03e38ddc7Daniel Lehmann 929856fcee477d04f51bdbcbfdf632876c6b8a1173Katherine Kuan intent.setClass(this, PeopleActivity.class); 93c90c705db8b3665ba9c8d8ce4b8ab3a03e38ddc7Daniel Lehmann startActivity(intent); 94c90c705db8b3665ba9c8d8ce4b8ab3a03e38ddc7Daniel Lehmann finish(); 95c90c705db8b3665ba9c8d8ce4b8ab3a03e38ddc7Daniel Lehmann return; 96c90c705db8b3665ba9c8d8ce4b8ab3a03e38ddc7Daniel Lehmann } 97c90c705db8b3665ba9c8d8ce4b8ab3a03e38ddc7Daniel Lehmann 9825a0282e968ebcdec6510bdb766ffba79b6fb8c4Daniel Lehmann setContentView(R.layout.contact_detail_activity); 99db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan 10051f1071a1dc91dace0de73be1c5fbba4f091f054Katherine Kuan mContactDetailLayoutController = new ContactDetailLayoutController(this, savedState, 1012f41fe6bcc8d055bf53ad070425552fad57dff21Daniel Lehmann getFragmentManager(), null, findViewById(R.id.contact_detail_container), 10251f1071a1dc91dace0de73be1c5fbba4f091f054Katherine Kuan mContactDetailFragmentListener); 103cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 10413fd2d99efcafa86c117855aafaf9fca445d38dbMakoto Onuki // We want the UP affordance but no app icon. 10513fd2d99efcafa86c117855aafaf9fca445d38dbMakoto Onuki // Setting HOME_AS_UP, SHOW_TITLE and clearing SHOW_HOME does the trick. 10613fd2d99efcafa86c117855aafaf9fca445d38dbMakoto Onuki ActionBar actionBar = getActionBar(); 1074ec198790236ab4be6bc5d73441215b684832618Isaac Katzenelson if (actionBar != null) { 10813fd2d99efcafa86c117855aafaf9fca445d38dbMakoto Onuki actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_TITLE, 10913fd2d99efcafa86c117855aafaf9fca445d38dbMakoto Onuki ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_TITLE 11013fd2d99efcafa86c117855aafaf9fca445d38dbMakoto Onuki | ActionBar.DISPLAY_SHOW_HOME); 11113fd2d99efcafa86c117855aafaf9fca445d38dbMakoto Onuki actionBar.setTitle(""); 1124ec198790236ab4be6bc5d73441215b684832618Isaac Katzenelson } 1134ec198790236ab4be6bc5d73441215b684832618Isaac Katzenelson 114cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann Log.i(TAG, getIntent().getData().toString()); 1154cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann } 1164cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann 11779700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan @Override 11879700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan public void onAttachFragment(Fragment fragment) { 119db0d8669cd1ffaa45827edb65b2b0eecb27561f5Katherine Kuan if (fragment instanceof ContactLoaderFragment) { 1202eb969cc399d87b659a45568fa951d394c216917Katherine Kuan mLoaderFragment = (ContactLoaderFragment) fragment; 1212eb969cc399d87b659a45568fa951d394c216917Katherine Kuan mLoaderFragment.setListener(mLoaderFragmentListener); 1222eb969cc399d87b659a45568fa951d394c216917Katherine Kuan mLoaderFragment.loadUri(getIntent().getData()); 12379700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan } 12479700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan } 12579700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan 1264cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann @Override 127942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan public boolean onCreateOptionsMenu(Menu menu) { 128942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan super.onCreateOptionsMenu(menu); 129942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan MenuInflater inflater = getMenuInflater(); 130942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan inflater.inflate(R.menu.star, menu); 1312a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann if (DEBUG_TRANSITIONS) { 1322a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann final MenuItem toggleSocial = 1332a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann menu.add(mLoaderFragment.getLoadStreamItems() ? "less" : "more"); 1342a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann toggleSocial.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); 1352a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann toggleSocial.setOnMenuItemClickListener(new OnMenuItemClickListener() { 1362a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann @Override 1372a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann public boolean onMenuItemClick(MenuItem item) { 1382a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann mLoaderFragment.toggleLoadStreamItems(); 1392a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann invalidateOptionsMenu(); 1402a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann return false; 1412a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann } 1422a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann }); 1432a45e35ab3273c8901d9df3671e51614dc0250c6Daniel Lehmann } 144942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan return true; 145942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan } 146942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan 147942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan @Override 148942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan public boolean onPrepareOptionsMenu(Menu menu) { 149c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann final MenuItem starredMenuItem = menu.findItem(R.id.menu_star); 150c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann starredMenuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() { 151942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan @Override 152c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann public boolean onMenuItemClick(MenuItem item) { 153942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan // Toggle "starred" state 154942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan // Make sure there is a contact 155942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan if (mLookupUri != null) { 156c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann // Read the current starred value from the UI instead of using the last 157c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann // loaded state. This allows rapid tapping without writing the same 158c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann // value several times 159c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann final boolean isStarred = starredMenuItem.isChecked(); 160c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann 161c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann // To improve responsiveness, swap out the picture (and tag) in the UI already 162c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann ContactDetailDisplayUtils.configureStarredMenuItem(starredMenuItem, 163c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann mContactData.isDirectoryEntry(), mContactData.isUserProfile(), 164c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann !isStarred); 165c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann 166c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann // Now perform the real save 167942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan Intent intent = ContactSaveService.createSetStarredIntent( 168c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann ContactDetailActivity.this, mLookupUri, !isStarred); 169942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan ContactDetailActivity.this.startService(intent); 170942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan } 171c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann return true; 172942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan } 173942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan }); 174942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan // If there is contact data, update the starred state 175942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan if (mContactData != null) { 176c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann ContactDetailDisplayUtils.configureStarredMenuItem(starredMenuItem, 177c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann mContactData.isDirectoryEntry(), mContactData.isUserProfile(), 178c42ea4eca298419484444a57bfc2da2c83e7adb7Daniel Lehmann mContactData.getStarred()); 179942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan } 180942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan return true; 181942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan } 182942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan 183942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan @Override 1844cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann public boolean onKeyDown(int keyCode, KeyEvent event) { 18558fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan // First check if the {@link ContactLoaderFragment} can handle the key 186f6141f1bc0116dd5c9dc399567502d74300326b6Katherine Kuan if (mLoaderFragment != null && mLoaderFragment.handleKeyDown(keyCode)) return true; 18758fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan 18858fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan // Otherwise find the correct fragment to handle the event 18951f1071a1dc91dace0de73be1c5fbba4f091f054Katherine Kuan FragmentKeyListener mCurrentFragment = mContactDetailLayoutController.getCurrentPage(); 190f6141f1bc0116dd5c9dc399567502d74300326b6Katherine Kuan if (mCurrentFragment != null && mCurrentFragment.handleKeyDown(keyCode)) return true; 1914cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann 19258fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan // In the last case, give the key event to the superclass. 1934cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann return super.onKeyDown(keyCode, event); 1944cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann } 19518f104fa8c167a510b2cca3c15a43833c9a54c7cDaniel Lehmann 1962eb969cc399d87b659a45568fa951d394c216917Katherine Kuan @Override 1972eb969cc399d87b659a45568fa951d394c216917Katherine Kuan protected void onSaveInstanceState(Bundle outState) { 1982eb969cc399d87b659a45568fa951d394c216917Katherine Kuan super.onSaveInstanceState(outState); 19951f1071a1dc91dace0de73be1c5fbba4f091f054Katherine Kuan if (mContactDetailLayoutController != null) { 20051f1071a1dc91dace0de73be1c5fbba4f091f054Katherine Kuan mContactDetailLayoutController.onSaveInstanceState(outState); 20151f1071a1dc91dace0de73be1c5fbba4f091f054Katherine Kuan } 2022eb969cc399d87b659a45568fa951d394c216917Katherine Kuan } 20318f104fa8c167a510b2cca3c15a43833c9a54c7cDaniel Lehmann 2042eb969cc399d87b659a45568fa951d394c216917Katherine Kuan private final ContactLoaderFragmentListener mLoaderFragmentListener = 2052eb969cc399d87b659a45568fa951d394c216917Katherine Kuan new ContactLoaderFragmentListener() { 20669e7fec6dd8a3d24054863c6c648512577fce35cDaniel Lehmann @Override 20758fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan public void onContactNotFound() { 20858fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan finish(); 20958fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan } 21058fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan 21158fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan @Override 212851222a96b5d68602fb361ea3527101e893f67e3Maurice Chu public void onDetailsLoaded(final Contact result) { 213942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan if (result == null) { 214942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan return; 215942cec2d8a248b1a22e95f4d573d235e281ee91aKatherine Kuan } 2162eb969cc399d87b659a45568fa951d394c216917Katherine Kuan // Since {@link FragmentTransaction}s cannot be done in the onLoadFinished() of the 2172eb969cc399d87b659a45568fa951d394c216917Katherine Kuan // {@link LoaderCallbacks}, then post this {@link Runnable} to the {@link Handler} 2182eb969cc399d87b659a45568fa951d394c216917Katherine Kuan // on the main thread to execute later. 2192eb969cc399d87b659a45568fa951d394c216917Katherine Kuan mHandler.post(new Runnable() { 2202eb969cc399d87b659a45568fa951d394c216917Katherine Kuan @Override 2212eb969cc399d87b659a45568fa951d394c216917Katherine Kuan public void run() { 222bed71bedbaae4d6b26b2b64db476bffa710753e5Makoto Onuki // If the activity is destroyed (or will be destroyed soon), don't update the UI 223bed71bedbaae4d6b26b2b64db476bffa710753e5Makoto Onuki if (isFinishing()) { 224bed71bedbaae4d6b26b2b64db476bffa710753e5Makoto Onuki return; 225bed71bedbaae4d6b26b2b64db476bffa710753e5Makoto Onuki } 2262eb969cc399d87b659a45568fa951d394c216917Katherine Kuan mContactData = result; 2272eb969cc399d87b659a45568fa951d394c216917Katherine Kuan mLookupUri = result.getLookupUri(); 2282eb969cc399d87b659a45568fa951d394c216917Katherine Kuan invalidateOptionsMenu(); 2292eb969cc399d87b659a45568fa951d394c216917Katherine Kuan setupTitle(); 23051f1071a1dc91dace0de73be1c5fbba4f091f054Katherine Kuan mContactDetailLayoutController.setContactData(mContactData); 2312eb969cc399d87b659a45568fa951d394c216917Katherine Kuan } 2322eb969cc399d87b659a45568fa951d394c216917Katherine Kuan }); 2332eb969cc399d87b659a45568fa951d394c216917Katherine Kuan } 23458fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan 23558fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan @Override 23658fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan public void onEditRequested(Uri contactLookupUri) { 2375c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan Intent intent = new Intent(Intent.ACTION_EDIT, contactLookupUri); 2385c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan intent.putExtra( 2395c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan ContactEditorActivity.INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, true); 2405c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan // Don't finish the detail activity after launching the editor because when the 2415c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan // editor is done, we will still want to show the updated contact details using 2425c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan // this activity. 2435c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan startActivity(intent); 24458fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan } 24558fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan 24658fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan @Override 24758fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan public void onDeleteRequested(Uri contactUri) { 24858fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan ContactDeletionInteraction.start(ContactDetailActivity.this, contactUri, true); 24958fc577bd7966e6566cdcac09589a0d3e05128e7Katherine Kuan } 2502eb969cc399d87b659a45568fa951d394c216917Katherine Kuan }; 2512eb969cc399d87b659a45568fa951d394c216917Katherine Kuan 2522eb969cc399d87b659a45568fa951d394c216917Katherine Kuan /** 2532eb969cc399d87b659a45568fa951d394c216917Katherine Kuan * Setup the activity title and subtitle with contact name and company. 2542eb969cc399d87b659a45568fa951d394c216917Katherine Kuan */ 2552eb969cc399d87b659a45568fa951d394c216917Katherine Kuan private void setupTitle() { 2562eb969cc399d87b659a45568fa951d394c216917Katherine Kuan CharSequence displayName = ContactDetailDisplayUtils.getDisplayName(this, mContactData); 2572eb969cc399d87b659a45568fa951d394c216917Katherine Kuan String company = ContactDetailDisplayUtils.getCompany(this, mContactData); 2582eb969cc399d87b659a45568fa951d394c216917Katherine Kuan 2592eb969cc399d87b659a45568fa951d394c216917Katherine Kuan ActionBar actionBar = getActionBar(); 2602eb969cc399d87b659a45568fa951d394c216917Katherine Kuan actionBar.setTitle(displayName); 2612eb969cc399d87b659a45568fa951d394c216917Katherine Kuan actionBar.setSubtitle(company); 262d6272412cdf3fdda90e835ec5b0cd1e15a0c97c9Daisuke Miyakawa 263e38ac4f95f032e065594109b14c9c196704437bdChiao Cheng final StringBuilder talkback = new StringBuilder(); 264078d08f5e497231cbe7fb520b5a4e42a398201a6Chiao Cheng if (!TextUtils.isEmpty(displayName)) { 265e38ac4f95f032e065594109b14c9c196704437bdChiao Cheng talkback.append(displayName); 266e38ac4f95f032e065594109b14c9c196704437bdChiao Cheng } 267e38ac4f95f032e065594109b14c9c196704437bdChiao Cheng if (!TextUtils.isEmpty(company)) { 268e38ac4f95f032e065594109b14c9c196704437bdChiao Cheng if (talkback.length() != 0) { 269e38ac4f95f032e065594109b14c9c196704437bdChiao Cheng talkback.append(", "); 270e38ac4f95f032e065594109b14c9c196704437bdChiao Cheng } 271e38ac4f95f032e065594109b14c9c196704437bdChiao Cheng talkback.append(company); 272e38ac4f95f032e065594109b14c9c196704437bdChiao Cheng } 273e38ac4f95f032e065594109b14c9c196704437bdChiao Cheng 274e38ac4f95f032e065594109b14c9c196704437bdChiao Cheng if (talkback.length() != 0) { 275078d08f5e497231cbe7fb520b5a4e42a398201a6Chiao Cheng AccessibilityManager accessibilityManager = 276078d08f5e497231cbe7fb520b5a4e42a398201a6Chiao Cheng (AccessibilityManager) this.getSystemService(Context.ACCESSIBILITY_SERVICE); 277078d08f5e497231cbe7fb520b5a4e42a398201a6Chiao Cheng if (accessibilityManager.isEnabled()) { 278078d08f5e497231cbe7fb520b5a4e42a398201a6Chiao Cheng View decorView = getWindow().getDecorView(); 279e38ac4f95f032e065594109b14c9c196704437bdChiao Cheng decorView.setContentDescription(talkback); 280078d08f5e497231cbe7fb520b5a4e42a398201a6Chiao Cheng decorView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 281078d08f5e497231cbe7fb520b5a4e42a398201a6Chiao Cheng } 282d6272412cdf3fdda90e835ec5b0cd1e15a0c97c9Daisuke Miyakawa } 2832eb969cc399d87b659a45568fa951d394c216917Katherine Kuan } 2842eb969cc399d87b659a45568fa951d394c216917Katherine Kuan 28551f1071a1dc91dace0de73be1c5fbba4f091f054Katherine Kuan private final ContactDetailFragment.Listener mContactDetailFragmentListener = 2862eb969cc399d87b659a45568fa951d394c216917Katherine Kuan new ContactDetailFragment.Listener() { 2872eb969cc399d87b659a45568fa951d394c216917Katherine Kuan @Override 288cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann public void onItemClicked(Intent intent) { 28908bcf715d5ea7f07ce18a282d9850ac70552ca9dKatherine Kuan if (intent == null) { 29008bcf715d5ea7f07ce18a282d9850ac70552ca9dKatherine Kuan return; 29108bcf715d5ea7f07ce18a282d9850ac70552ca9dKatherine Kuan } 29260be1a1e8639a58d16f58686f8a89747d6079cc7Daniel Lehmann try { 29360be1a1e8639a58d16f58686f8a89747d6079cc7Daniel Lehmann startActivity(intent); 29460be1a1e8639a58d16f58686f8a89747d6079cc7Daniel Lehmann } catch (ActivityNotFoundException e) { 29560be1a1e8639a58d16f58686f8a89747d6079cc7Daniel Lehmann Log.e(TAG, "No activity found for intent: " + intent); 29660be1a1e8639a58d16f58686f8a89747d6079cc7Daniel Lehmann } 29718f104fa8c167a510b2cca3c15a43833c9a54c7cDaniel Lehmann } 298cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann 29969e7fec6dd8a3d24054863c6c648512577fce35cDaniel Lehmann @Override 300caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov public void onCreateRawContactRequested( 3012b3f3c54d3beb017b2f59f19e9ce0ecc3e039dbcDave Santoro ArrayList<ContentValues> values, AccountWithDataSet account) { 302caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov Toast.makeText(ContactDetailActivity.this, R.string.toast_making_personal_copy, 303caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov Toast.LENGTH_LONG).show(); 304caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov Intent serviceIntent = ContactSaveService.createNewRawContactIntent( 3059d730dd9d9efe125c9102b298f897577157ffecdDmitri Plotnikov ContactDetailActivity.this, values, account, 3069d730dd9d9efe125c9102b298f897577157ffecdDmitri Plotnikov ContactDetailActivity.class, Intent.ACTION_VIEW); 307caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov startService(serviceIntent); 308caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov 309caf0bc759c4ef96dde5bb0a5256c1dcb51b6ccc4Dmitri Plotnikov } 310cdef2b60aa87b1178033fdc964a3402386c03d7cDaniel Lehmann }; 31179700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan 31279700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan /** 31379700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan * This interface should be implemented by {@link Fragment}s within this 31479700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan * activity so that the activity can determine whether the currently 31579700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan * displayed view is handling the key event or not. 31679700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan */ 31779700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan public interface FragmentKeyListener { 31879700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan /** 31979700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan * Returns true if the key down event will be handled by the implementing class, or false 32079700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan * otherwise. 32179700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan */ 32279700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan public boolean handleKeyDown(int keyCode); 32379700889dad553dcde9e22a2fd23df768f68080fKatherine Kuan } 3244cd94419d615e5513849516dfcbf0ce4cd08ecd0Daniel Lehmann} 325