ContactEditorBaseActivity.java revision 5a7a23bdb698b8e741a425c9617c5e33e6314cdd
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17package com.android.contacts.activities; 18 19import com.android.contacts.ContactSaveService; 20import com.android.contacts.ContactsActivity; 21import com.android.contacts.R; 22import com.android.contacts.common.model.AccountTypeManager; 23import com.android.contacts.common.model.account.AccountType; 24import com.android.contacts.common.model.account.AccountWithDataSet; 25import com.android.contacts.common.util.ImplicitIntentsUtil; 26import com.android.contacts.editor.ContactEditorBaseFragment; 27import com.android.contacts.editor.ContactEditorFragment; 28import com.android.contacts.editor.EditorIntents; 29import com.android.contacts.interactions.ContactDeletionInteraction; 30import com.android.contacts.util.DialogManager; 31 32import android.app.ActionBar; 33import android.app.Dialog; 34import android.content.ContentValues; 35import android.content.Intent; 36import android.net.Uri; 37import android.os.Bundle; 38import android.provider.ContactsContract; 39import android.provider.ContactsContract.Contacts; 40import android.provider.ContactsContract.RawContacts; 41import android.util.Log; 42 43import java.util.ArrayList; 44 45/** 46 * Base Activity for contact editors. 47 */ 48abstract public class ContactEditorBaseActivity extends ContactsActivity 49 implements DialogManager.DialogShowingViewActivity { 50 protected static final String TAG = "ContactEditorActivity"; 51 52 /** 53 * Intent action to edit a contact with all available field inputs displayed. 54 * 55 * Only used to open the "fully expanded" editor -- {@link ContactEditorActivity}. 56 */ 57 public static final String ACTION_EDIT = "com.google.android.contacts.action.EDIT"; 58 59 /** 60 * Intent action to insert a new contact with all available field inputs displayed. 61 * 62 * Only used to open the "fully expanded" editor -- {@link ContactEditorActivity}. 63 */ 64 public static final String ACTION_INSERT = "com.google.android.contacts.action.INSERT"; 65 66 public static final String ACTION_JOIN_COMPLETED = "joinCompleted"; 67 public static final String ACTION_SAVE_COMPLETED = "saveCompleted"; 68 69 /** 70 * Contract for contact editors Fragments that are managed by this Activity. 71 */ 72 public interface ContactEditor { 73 74 /** 75 * Modes that specify what the AsyncTask has to perform after saving 76 */ 77 public interface SaveMode { 78 /** 79 * Close the editor after saving 80 */ 81 public static final int CLOSE = 0; 82 83 /** 84 * Reload the data so that the user can continue editing 85 */ 86 public static final int RELOAD = 1; 87 88 /** 89 * Split the contact after saving 90 */ 91 public static final int SPLIT = 2; 92 93 /** 94 * Join another contact after saving 95 */ 96 public static final int JOIN = 3; 97 98 /** 99 * Navigate to the compact editor view after saving. 100 */ 101 public static final int COMPACT = 4; 102 } 103 104 /** 105 * The status of the contact editor. 106 */ 107 public interface Status { 108 /** 109 * The loader is fetching data 110 */ 111 public static final int LOADING = 0; 112 113 /** 114 * Not currently busy. We are waiting for the user to enter data 115 */ 116 public static final int EDITING = 1; 117 118 /** 119 * The data is currently being saved. This is used to prevent more 120 * auto-saves (they shouldn't overlap) 121 */ 122 public static final int SAVING = 2; 123 124 /** 125 * Prevents any more saves. This is used if in the following cases: 126 * - After Save/Close 127 * - After Revert 128 * - After the user has accepted an edit suggestion 129 * - After the user chooses to expand the compact editor 130 */ 131 public static final int CLOSING = 3; 132 133 /** 134 * Prevents saving while running a child activity. 135 */ 136 public static final int SUB_ACTIVITY = 4; 137 } 138 139 /** 140 * Sets the hosting Activity that will receive callbacks from the contact editor. 141 */ 142 void setListener(ContactEditorBaseFragment.Listener listener); 143 144 /** 145 * Initialize the contact editor. 146 */ 147 void load(String action, Uri lookupUri, Bundle intentExtras); 148 149 /** 150 * Applies extras from the hosting Activity to the first writable raw contact. 151 */ 152 void setIntentExtras(Bundle extras); 153 154 /** 155 * Saves or creates the contact based on the mode, and if successful 156 * finishes the activity. 157 */ 158 boolean save(int saveMode); 159 160 /** 161 * Invoked after the contact is saved. 162 */ 163 void onSaveCompleted(boolean hadChanges, int saveMode, boolean saveSucceeded, 164 Uri contactLookupUri); 165 166 /** 167 * Invoked after the contact is joined. 168 */ 169 void onJoinCompleted(Uri uri); 170 } 171 172 /** 173 * Boolean intent key that specifies that this activity should finish itself 174 * (instead of launching a new view intent) after the editor changes have been 175 * saved. 176 */ 177 public static final String INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED = 178 "finishActivityOnSaveCompleted"; 179 180 /** 181 * Intent key to pass the calculated photo palette calculated by 182 * {@link com.android.contacts.quickcontact.QuickContactActivity} to the compact editor. 183 */ 184 public static final String INTENT_KEY_MATERIAL_PALETTE = "materialPalette"; 185 186 protected ContactEditor mFragment; 187 private boolean mFinishActivityOnSaveCompleted; 188 189 private DialogManager mDialogManager = new DialogManager(this); 190 191 @Override 192 public void onCreate(Bundle savedState) { 193 super.onCreate(savedState); 194 195 final Intent intent = getIntent(); 196 final String action = intent.getAction(); 197 198 // Determine whether or not this activity should be finished after the user is done 199 // editing the contact or if this activity should launch another activity to view the 200 // contact's details. 201 mFinishActivityOnSaveCompleted = intent.getBooleanExtra( 202 INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, false); 203 204 // The only situation where action could be ACTION_JOIN_COMPLETED is if the 205 // user joined the contact with another and closed the activity before 206 // the save operation was completed. The activity should remain closed then. 207 if (ACTION_JOIN_COMPLETED.equals(action)) { 208 finish(); 209 return; 210 } 211 212 if (ACTION_SAVE_COMPLETED.equals(action)) { 213 finish(); 214 return; 215 } 216 217 ActionBar actionBar = getActionBar(); 218 if (actionBar != null) { 219 if (Intent.ACTION_EDIT.equals(action) || ACTION_EDIT.equals(action)) { 220 actionBar.setTitle(getResources().getString( 221 R.string.contact_editor_title_existing_contact)); 222 } else { 223 actionBar.setTitle(getResources().getString( 224 R.string.contact_editor_title_new_contact)); 225 } 226 actionBar.setDisplayShowHomeEnabled(true); 227 actionBar.setDisplayHomeAsUpEnabled(true); 228 } 229 } 230 231 @Override 232 protected void onNewIntent(Intent intent) { 233 super.onNewIntent(intent); 234 235 if (mFragment == null) { 236 return; 237 } 238 239 String action = intent.getAction(); 240 if (Intent.ACTION_EDIT.equals(action) || ACTION_EDIT.equals(action)) { 241 mFragment.setIntentExtras(intent.getExtras()); 242 } else if (ACTION_SAVE_COMPLETED.equals(action)) { 243 mFragment.onSaveCompleted(true, 244 intent.getIntExtra(ContactEditorFragment.SAVE_MODE_EXTRA_KEY, 245 ContactEditor.SaveMode.CLOSE), 246 intent.getBooleanExtra(ContactSaveService.EXTRA_SAVE_SUCCEEDED, false), 247 intent.getData()); 248 } else if (ACTION_JOIN_COMPLETED.equals(action)) { 249 mFragment.onJoinCompleted(intent.getData()); 250 } 251 } 252 253 @Override 254 protected Dialog onCreateDialog(int id, Bundle args) { 255 if (DialogManager.isManagedId(id)) return mDialogManager.onCreateDialog(id, args); 256 257 // Nobody knows about the Dialog 258 Log.w(TAG, "Unknown dialog requested, id: " + id + ", args: " + args); 259 return null; 260 } 261 262 protected final ContactEditorBaseFragment.Listener mFragmentListener = 263 new ContactEditorBaseFragment.Listener() { 264 265 @Override 266 public void onDeleteRequested(Uri contactUri) { 267 ContactDeletionInteraction.start(ContactEditorBaseActivity.this, contactUri, true); 268 } 269 270 @Override 271 public void onReverted() { 272 finish(); 273 } 274 275 @Override 276 public void onSaveFinished(Intent resultIntent) { 277 if (mFinishActivityOnSaveCompleted) { 278 setResult(resultIntent == null ? RESULT_CANCELED : RESULT_OK, resultIntent); 279 } else if (resultIntent != null) { 280 ImplicitIntentsUtil.startActivityInApp(ContactEditorBaseActivity.this, 281 resultIntent); 282 } 283 finish(); 284 } 285 286 @Override 287 public void onContactSplit(Uri newLookupUri) { 288 finish(); 289 } 290 291 @Override 292 public void onContactNotFound() { 293 finish(); 294 } 295 296 @Override 297 public void onEditOtherContactRequested( 298 Uri contactLookupUri, ArrayList<ContentValues> values) { 299 final Intent intent = EditorIntents.createEditOtherContactIntent( 300 contactLookupUri, values); 301 ImplicitIntentsUtil.startActivityInApp(ContactEditorBaseActivity.this, intent); 302 finish(); 303 } 304 305 @Override 306 public void onCustomCreateContactActivityRequested(AccountWithDataSet account, 307 Bundle intentExtras) { 308 final AccountTypeManager accountTypes = 309 AccountTypeManager.getInstance(ContactEditorBaseActivity.this); 310 final AccountType accountType = accountTypes.getAccountType( 311 account.type, account.dataSet); 312 313 Intent intent = new Intent(); 314 intent.setClassName(accountType.syncAdapterPackageName, 315 accountType.getCreateContactActivityClassName()); 316 intent.setAction(Intent.ACTION_INSERT); 317 intent.setType(Contacts.CONTENT_ITEM_TYPE); 318 if (intentExtras != null) { 319 intent.putExtras(intentExtras); 320 } 321 intent.putExtra(RawContacts.ACCOUNT_NAME, account.name); 322 intent.putExtra(RawContacts.ACCOUNT_TYPE, account.type); 323 intent.putExtra(RawContacts.DATA_SET, account.dataSet); 324 intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 325 | Intent.FLAG_ACTIVITY_FORWARD_RESULT); 326 startActivity(intent); 327 finish(); 328 } 329 330 @Override 331 public void onCustomEditContactActivityRequested(AccountWithDataSet account, 332 Uri rawContactUri, Bundle intentExtras, boolean redirect) { 333 final AccountTypeManager accountTypes = 334 AccountTypeManager.getInstance(ContactEditorBaseActivity.this); 335 final AccountType accountType = accountTypes.getAccountType( 336 account.type, account.dataSet); 337 338 Intent intent = new Intent(); 339 intent.setClassName(accountType.syncAdapterPackageName, 340 accountType.getEditContactActivityClassName()); 341 intent.setAction(Intent.ACTION_EDIT); 342 intent.setData(rawContactUri); 343 if (intentExtras != null) { 344 intent.putExtras(intentExtras); 345 } 346 347 if (redirect) { 348 intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 349 | Intent.FLAG_ACTIVITY_FORWARD_RESULT); 350 startActivity(intent); 351 finish(); 352 } else { 353 startActivity(intent); 354 } 355 } 356 }; 357 358 @Override 359 public DialogManager getDialogManager() { 360 return mDialogManager; 361 } 362} 363