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
145                 && !accounts.get(0).getAccount().equals(AccountWithDataSet.getLocalAccount(this))) {
146             // If the user has 1 writable account we will just show the user a message with 2
147             // possible action buttons.
148             view = View.inflate(this,
149                     R.layout.contact_editor_accounts_changed_activity_with_text, null);
150 
151             final TextView textView = (TextView) view.findViewById(R.id.text);
152             final Button leftButton = (Button) view.findViewById(R.id.left_button);
153             final Button rightButton = (Button) view.findViewById(R.id.right_button);
154 
155             final AccountInfo accountInfo = accounts.get(0);
156             textView.setText(getString(R.string.contact_editor_prompt_one_account,
157                     accountInfo.getNameLabel()));
158 
159             // This button allows the user to add a new account to the device and return to
160             // this app afterwards.
161             leftButton.setText(getString(R.string.add_new_account));
162             leftButton.setOnClickListener(mAddAccountClickListener);
163 
164             // This button allows the user to continue creating the contact in the specified
165             // account.
166             rightButton.setText(getString(android.R.string.ok));
167             rightButton.setOnClickListener(new OnClickListener() {
168                 @Override
169                 public void onClick(View v) {
170                     saveAccountAndReturnResult(accountInfo.getAccount());
171                 }
172             });
173         } else {
174             // If the user has 0 writable accounts, we will just show the user a message with 2
175             // possible action buttons.
176             view = View.inflate(this,
177                     R.layout.contact_editor_accounts_changed_activity_with_text, null);
178 
179             final TextView textView = (TextView) view.findViewById(R.id.text);
180             final Button leftButton = (Button) view.findViewById(R.id.left_button);
181             final Button rightButton = (Button) view.findViewById(R.id.right_button);
182 
183             textView.setText(getString(R.string.contact_editor_prompt_zero_accounts));
184 
185             // This button allows the user to continue editing the contact as a phone-only
186             // local contact.
187             leftButton.setText(getString(android.R.string.cancel));
188             leftButton.setOnClickListener(new OnClickListener() {
189                 @Override
190                 public void onClick(View v) {
191                     // Remember that the user wants to create local contacts, so the user is not
192                     // prompted again with this activity.
193                     saveAccountAndReturnResult(AccountWithDataSet.getNullAccount());
194                     finish();
195                 }
196             });
197 
198             // This button allows the user to add a new account to the device and return to
199             // this app afterwards.
200             rightButton.setText(getString(R.string.add_account));
201             rightButton.setOnClickListener(mAddAccountClickListener);
202         }
203 
204         if (mDialog != null && mDialog.isShowing()) {
205             mDialog.dismiss();
206         }
207         mDialog = new AlertDialog.Builder(this)
208                 .setView(view)
209                 .setOnCancelListener(new DialogInterface.OnCancelListener() {
210                     @Override
211                     public void onCancel(DialogInterface dialog) {
212                         finish();
213                     }
214                 })
215                 .create();
216         mDialog.show();
217     }
218 
saveAccountAndReturnResult(AccountWithDataSet account)219     private void saveAccountAndReturnResult(AccountWithDataSet account) {
220         // Save this as the default account
221         mEditorUtils.saveDefaultAccount(account);
222 
223         // Pass account info in activity result intent
224         Intent intent = new Intent();
225         intent.putExtra(Intents.Insert.EXTRA_ACCOUNT, account);
226         setResult(RESULT_OK, intent);
227         finish();
228     }
229 
230     @Override
onAccountsLoaded(List<AccountInfo> accounts)231     public void onAccountsLoaded(List<AccountInfo> accounts) {
232         updateDisplayedAccounts(accounts);
233     }
234 }
235