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