1 /*
2  * Copyright (C) 2011 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 
17 package com.android.contacts.activities;
18 
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.content.DialogInterface;
22 import android.content.Intent;
23 import android.os.Bundle;
24 import android.provider.ContactsContract.Intents;
25 import android.view.View;
26 import android.view.View.OnClickListener;
27 import android.widget.AdapterView;
28 import android.widget.AdapterView.OnItemClickListener;
29 import android.widget.Button;
30 import android.widget.ListView;
31 import android.widget.TextView;
32 
33 import com.android.contacts.R;
34 import com.android.contacts.editor.ContactEditorUtils;
35 import com.android.contacts.model.AccountTypeManager;
36 import com.android.contacts.model.account.AccountInfo;
37 import com.android.contacts.model.account.AccountWithDataSet;
38 import com.android.contacts.model.account.AccountsLoader;
39 import com.android.contacts.util.AccountsListAdapter;
40 import com.android.contacts.util.ImplicitIntentsUtil;
41 
42 import java.util.List;
43 
44 /**
45  * This activity can be shown to the user when creating a new contact to inform the user about
46  * which account the contact will be saved in. There is also an option to add an account at
47  * this time. The {@link Intent} in the activity result will contain an extra
48  * {@link #Intents.Insert.ACCOUNT} that contains the {@link AccountWithDataSet} to create
49  * the new contact in. If the activity result doesn't contain intent data, then there is no
50  * account for this contact.
51  */
52 public class ContactEditorAccountsChangedActivity extends Activity
53         implements AccountsLoader.AccountsListener {
54     private static final int SUBACTIVITY_ADD_NEW_ACCOUNT = 1;
55 
56     private AccountsListAdapter mAccountListAdapter;
57     private ContactEditorUtils mEditorUtils;
58     private AlertDialog mDialog;
59 
60     private final OnItemClickListener mAccountListItemClickListener = new OnItemClickListener() {
61         @Override
62         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
63             if (mAccountListAdapter == null) {
64                 return;
65             }
66             saveAccountAndReturnResult(mAccountListAdapter.getItem(position));
67         }
68     };
69 
70     private final OnClickListener mAddAccountClickListener = new OnClickListener() {
71         @Override
72         public void onClick(View v) {
73             final Intent intent = ImplicitIntentsUtil.getIntentForAddingGoogleAccount();
74             startActivityForResult(intent, SUBACTIVITY_ADD_NEW_ACCOUNT);
75         }
76     };
77 
78     @Override
onResume()79     protected void onResume() {
80         super.onResume();
81         if (mDialog != null && !mDialog.isShowing()) {
82             mDialog.show();
83         }
84     }
85 
86     @Override
onPause()87     protected void onPause() {
88         super.onPause();
89         if (mDialog != null) {
90             mDialog.dismiss();
91         }
92     }
93 
94     @Override
onCreate(Bundle savedInstanceState)95     protected void onCreate(Bundle savedInstanceState) {
96         super.onCreate(savedInstanceState);
97         mEditorUtils = ContactEditorUtils.create(this);
98         AccountsLoader.loadAccounts(this, 0, AccountTypeManager.writableFilter());
99     }
100 
101     @Override
onActivityResult(int requestCode, int resultCode, Intent data)102     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
103         if (requestCode == SUBACTIVITY_ADD_NEW_ACCOUNT) {
104             // If the user canceled the account setup process, then keep this activity visible to
105             // the user.
106             if (resultCode != RESULT_OK) {
107                 return;
108             }
109             // Subactivity was successful, so pass the result back and finish the activity.
110             AccountWithDataSet account = mEditorUtils.getCreatedAccount(resultCode, data);
111             if (account == null) {
112                 setResult(resultCode);
113                 finish();
114                 return;
115             }
116             saveAccountAndReturnResult(account);
117         }
118     }
119 
updateDisplayedAccounts(List<AccountInfo> accounts)120     private void updateDisplayedAccounts(List<AccountInfo> accounts) {
121         final int numAccounts = accounts.size();
122         if (numAccounts < 0) {
123             throw new IllegalStateException("Cannot have a negative number of accounts");
124         }
125 
126         final View view;
127         if (numAccounts >= 2) {
128             // When the user has 2+ writable accounts, show a list of accounts so the user can pick
129             // which account to create a contact in.
130             view = View.inflate(this,
131                     R.layout.contact_editor_accounts_changed_activity_with_picker, null);
132 
133             final TextView textView = (TextView) view.findViewById(R.id.text);
134             textView.setText(getString(R.string.contact_editor_prompt_multiple_accounts));
135 
136             final Button button = (Button) view.findViewById(R.id.add_account_button);
137             button.setText(getString(R.string.add_new_account));
138             button.setOnClickListener(mAddAccountClickListener);
139 
140             final ListView accountListView = (ListView) view.findViewById(R.id.account_list);
141             mAccountListAdapter = new AccountsListAdapter(this, accounts);
142             accountListView.setAdapter(mAccountListAdapter);
143             accountListView.setOnItemClickListener(mAccountListItemClickListener);
144         } else if (numAccounts == 1 && !accounts.get(0).getAccount().isNullAccount()) {
145             // If the user has 1 writable account we will just show the user a message with 2
146             // possible action buttons.
147             view = View.inflate(this,
148                     R.layout.contact_editor_accounts_changed_activity_with_text, null);
149 
150             final TextView textView = (TextView) view.findViewById(R.id.text);
151             final Button leftButton = (Button) view.findViewById(R.id.left_button);
152             final Button rightButton = (Button) view.findViewById(R.id.right_button);
153 
154             final AccountInfo accountInfo = accounts.get(0);
155             textView.setText(getString(R.string.contact_editor_prompt_one_account,
156                     accountInfo.getNameLabel()));
157 
158             // This button allows the user to add a new account to the device and return to
159             // this app afterwards.
160             leftButton.setText(getString(R.string.add_new_account));
161             leftButton.setOnClickListener(mAddAccountClickListener);
162 
163             // This button allows the user to continue creating the contact in the specified
164             // account.
165             rightButton.setText(getString(android.R.string.ok));
166             rightButton.setOnClickListener(new OnClickListener() {
167                 @Override
168                 public void onClick(View v) {
169                     saveAccountAndReturnResult(accountInfo.getAccount());
170                 }
171             });
172         } else {
173             // If the user has 0 writable accounts, we will just show the user a message with 2
174             // possible action buttons.
175             view = View.inflate(this,
176                     R.layout.contact_editor_accounts_changed_activity_with_text, null);
177 
178             final TextView textView = (TextView) view.findViewById(R.id.text);
179             final Button leftButton = (Button) view.findViewById(R.id.left_button);
180             final Button rightButton = (Button) view.findViewById(R.id.right_button);
181 
182             textView.setText(getString(R.string.contact_editor_prompt_zero_accounts));
183 
184             // This button allows the user to continue editing the contact as a phone-only
185             // local contact.
186             leftButton.setText(getString(android.R.string.cancel));
187             leftButton.setOnClickListener(new OnClickListener() {
188                 @Override
189                 public void onClick(View v) {
190                     // Remember that the user wants to create local contacts, so the user is not
191                     // prompted again with this activity.
192                     saveAccountAndReturnResult(AccountWithDataSet.getNullAccount());
193                     finish();
194                 }
195             });
196 
197             // This button allows the user to add a new account to the device and return to
198             // this app afterwards.
199             rightButton.setText(getString(R.string.add_account));
200             rightButton.setOnClickListener(mAddAccountClickListener);
201         }
202 
203         if (mDialog != null && mDialog.isShowing()) {
204             mDialog.dismiss();
205         }
206         mDialog = new AlertDialog.Builder(this)
207                 .setView(view)
208                 .setOnCancelListener(new DialogInterface.OnCancelListener() {
209                     @Override
210                     public void onCancel(DialogInterface dialog) {
211                         finish();
212                     }
213                 })
214                 .create();
215         mDialog.show();
216     }
217 
saveAccountAndReturnResult(AccountWithDataSet account)218     private void saveAccountAndReturnResult(AccountWithDataSet account) {
219         // Save this as the default account
220         mEditorUtils.saveDefaultAccount(account);
221 
222         // Pass account info in activity result intent
223         Intent intent = new Intent();
224         intent.putExtra(Intents.Insert.EXTRA_ACCOUNT, account);
225         setResult(RESULT_OK, intent);
226         finish();
227     }
228 
229     @Override
onAccountsLoaded(List<AccountInfo> accounts)230     public void onAccountsLoaded(List<AccountInfo> accounts) {
231         updateDisplayedAccounts(accounts);
232     }
233 }
234