summaryrefslogtreecommitdiff
path: root/src/com/android/phone/EditFdnContactScreen.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/phone/EditFdnContactScreen.java')
-rwxr-xr-xsrc/com/android/phone/EditFdnContactScreen.java458
1 files changed, 458 insertions, 0 deletions
diff --git a/src/com/android/phone/EditFdnContactScreen.java b/src/com/android/phone/EditFdnContactScreen.java
new file mode 100755
index 00000000..2992b7dc
--- /dev/null
+++ b/src/com/android/phone/EditFdnContactScreen.java
@@ -0,0 +1,458 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import static android.view.Window.PROGRESS_VISIBILITY_OFF;
+import static android.view.Window.PROGRESS_VISIBILITY_ON;
+
+import android.app.Activity;
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.Contacts.PeopleColumns;
+import android.provider.Contacts.PhonesColumns;
+import android.telephony.PhoneNumberUtils;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.text.method.DialerKeyListener;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/**
+ * Activity to let the user add or edit an FDN contact.
+ */
+public class EditFdnContactScreen extends Activity {
+ private static final String LOG_TAG = PhoneGlobals.LOG_TAG;
+ private static final boolean DBG = false;
+
+ // Menu item codes
+ private static final int MENU_IMPORT = 1;
+ private static final int MENU_DELETE = 2;
+
+ private static final String INTENT_EXTRA_NAME = "name";
+ private static final String INTENT_EXTRA_NUMBER = "number";
+
+ private static final int PIN2_REQUEST_CODE = 100;
+
+ private String mName;
+ private String mNumber;
+ private String mPin2;
+ private boolean mAddContact;
+ private QueryHandler mQueryHandler;
+
+ private EditText mNameField;
+ private EditText mNumberField;
+ private LinearLayout mPinFieldContainer;
+ private Button mButton;
+
+ private Handler mHandler = new Handler();
+
+ /**
+ * Constants used in importing from contacts
+ */
+ /** request code when invoking subactivity */
+ private static final int CONTACTS_PICKER_CODE = 200;
+ /** projection for phone number query */
+ private static final String NUM_PROJECTION[] = {PeopleColumns.DISPLAY_NAME,
+ PhonesColumns.NUMBER};
+ /** static intent to invoke phone number picker */
+ private static final Intent CONTACT_IMPORT_INTENT;
+ static {
+ CONTACT_IMPORT_INTENT = new Intent(Intent.ACTION_GET_CONTENT);
+ CONTACT_IMPORT_INTENT.setType(android.provider.Contacts.Phones.CONTENT_ITEM_TYPE);
+ }
+ /** flag to track saving state */
+ private boolean mDataBusy;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ resolveIntent();
+
+ getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ setContentView(R.layout.edit_fdn_contact_screen);
+ setupView();
+ setTitle(mAddContact ?
+ R.string.add_fdn_contact : R.string.edit_fdn_contact);
+
+ displayProgress(false);
+ }
+
+ /**
+ * We now want to bring up the pin request screen AFTER the
+ * contact information is displayed, to help with user
+ * experience.
+ *
+ * Also, process the results from the contact picker.
+ */
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ if (DBG) log("onActivityResult request:" + requestCode + " result:" + resultCode);
+
+ switch (requestCode) {
+ case PIN2_REQUEST_CODE:
+ Bundle extras = (intent != null) ? intent.getExtras() : null;
+ if (extras != null) {
+ mPin2 = extras.getString("pin2");
+ if (mAddContact) {
+ addContact();
+ } else {
+ updateContact();
+ }
+ } else if (resultCode != RESULT_OK) {
+ // if they cancelled, then we just cancel too.
+ if (DBG) log("onActivityResult: cancelled.");
+ finish();
+ }
+ break;
+
+ // look for the data associated with this number, and update
+ // the display with it.
+ case CONTACTS_PICKER_CODE:
+ if (resultCode != RESULT_OK) {
+ if (DBG) log("onActivityResult: cancelled.");
+ return;
+ }
+ Cursor cursor = null;
+ try {
+ cursor = getContentResolver().query(intent.getData(),
+ NUM_PROJECTION, null, null, null);
+ if ((cursor == null) || (!cursor.moveToFirst())) {
+ Log.w(LOG_TAG,"onActivityResult: bad contact data, no results found.");
+ return;
+ }
+ mNameField.setText(cursor.getString(0));
+ mNumberField.setText(cursor.getString(1));
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ break;
+ }
+ }
+
+ /**
+ * Overridden to display the import and delete commands.
+ */
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+
+ Resources r = getResources();
+
+ // Added the icons to the context menu
+ menu.add(0, MENU_IMPORT, 0, r.getString(R.string.importToFDNfromContacts))
+ .setIcon(R.drawable.ic_menu_contact);
+ menu.add(0, MENU_DELETE, 0, r.getString(R.string.menu_delete))
+ .setIcon(android.R.drawable.ic_menu_delete);
+ return true;
+ }
+
+ /**
+ * Allow the menu to be opened ONLY if we're not busy.
+ */
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ boolean result = super.onPrepareOptionsMenu(menu);
+ return mDataBusy ? false : result;
+ }
+
+ /**
+ * Overridden to allow for handling of delete and import.
+ */
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_IMPORT:
+ startActivityForResult(CONTACT_IMPORT_INTENT, CONTACTS_PICKER_CODE);
+ return true;
+
+ case MENU_DELETE:
+ deleteSelected();
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void resolveIntent() {
+ Intent intent = getIntent();
+
+ mName = intent.getStringExtra(INTENT_EXTRA_NAME);
+ mNumber = intent.getStringExtra(INTENT_EXTRA_NUMBER);
+
+ mAddContact = TextUtils.isEmpty(mNumber);
+ }
+
+ /**
+ * We have multiple layouts, one to indicate that the user needs to
+ * open the keyboard to enter information (if the keybord is hidden).
+ * So, we need to make sure that the layout here matches that in the
+ * layout file.
+ */
+ private void setupView() {
+ mNameField = (EditText) findViewById(R.id.fdn_name);
+ if (mNameField != null) {
+ mNameField.setOnFocusChangeListener(mOnFocusChangeHandler);
+ mNameField.setOnClickListener(mClicked);
+ }
+
+ mNumberField = (EditText) findViewById(R.id.fdn_number);
+ if (mNumberField != null) {
+ mNumberField.setKeyListener(DialerKeyListener.getInstance());
+ mNumberField.setOnFocusChangeListener(mOnFocusChangeHandler);
+ mNumberField.setOnClickListener(mClicked);
+ }
+
+ if (!mAddContact) {
+ if (mNameField != null) {
+ mNameField.setText(mName);
+ }
+ if (mNumberField != null) {
+ mNumberField.setText(mNumber);
+ }
+ }
+
+ mButton = (Button) findViewById(R.id.button);
+ if (mButton != null) {
+ mButton.setOnClickListener(mClicked);
+ }
+
+ mPinFieldContainer = (LinearLayout) findViewById(R.id.pinc);
+
+ }
+
+ private String getNameFromTextField() {
+ return mNameField.getText().toString();
+ }
+
+ private String getNumberFromTextField() {
+ return mNumberField.getText().toString();
+ }
+
+ private Uri getContentURI() {
+ return Uri.parse("content://icc/fdn");
+ }
+
+ /**
+ * @param number is voice mail number
+ * @return true if number length is less than 20-digit limit
+ *
+ * TODO: Fix this logic.
+ */
+ private boolean isValidNumber(String number) {
+ return (number.length() <= 20);
+ }
+
+
+ private void addContact() {
+ if (DBG) log("addContact");
+
+ final String number = PhoneNumberUtils.convertAndStrip(getNumberFromTextField());
+
+ if (!isValidNumber(number)) {
+ handleResult(false, true);
+ return;
+ }
+
+ Uri uri = getContentURI();
+
+ ContentValues bundle = new ContentValues(3);
+ bundle.put("tag", getNameFromTextField());
+ bundle.put("number", number);
+ bundle.put("pin2", mPin2);
+
+ mQueryHandler = new QueryHandler(getContentResolver());
+ mQueryHandler.startInsert(0, null, uri, bundle);
+ displayProgress(true);
+ showStatus(getResources().getText(R.string.adding_fdn_contact));
+ }
+
+ private void updateContact() {
+ if (DBG) log("updateContact");
+
+ final String name = getNameFromTextField();
+ final String number = PhoneNumberUtils.convertAndStrip(getNumberFromTextField());
+
+ if (!isValidNumber(number)) {
+ handleResult(false, true);
+ return;
+ }
+ Uri uri = getContentURI();
+
+ ContentValues bundle = new ContentValues();
+ bundle.put("tag", mName);
+ bundle.put("number", mNumber);
+ bundle.put("newTag", name);
+ bundle.put("newNumber", number);
+ bundle.put("pin2", mPin2);
+
+ mQueryHandler = new QueryHandler(getContentResolver());
+ mQueryHandler.startUpdate(0, null, uri, bundle, null, null);
+ displayProgress(true);
+ showStatus(getResources().getText(R.string.updating_fdn_contact));
+ }
+
+ /**
+ * Handle the delete command, based upon the state of the Activity.
+ */
+ private void deleteSelected() {
+ // delete ONLY if this is NOT a new contact.
+ if (!mAddContact) {
+ Intent intent = new Intent();
+ intent.setClass(this, DeleteFdnContactScreen.class);
+ intent.putExtra(INTENT_EXTRA_NAME, mName);
+ intent.putExtra(INTENT_EXTRA_NUMBER, mNumber);
+ startActivity(intent);
+ }
+ finish();
+ }
+
+ private void authenticatePin2() {
+ Intent intent = new Intent();
+ intent.setClass(this, GetPin2Screen.class);
+ startActivityForResult(intent, PIN2_REQUEST_CODE);
+ }
+
+ private void displayProgress(boolean flag) {
+ // indicate we are busy.
+ mDataBusy = flag;
+ getWindow().setFeatureInt(
+ Window.FEATURE_INDETERMINATE_PROGRESS,
+ mDataBusy ? PROGRESS_VISIBILITY_ON : PROGRESS_VISIBILITY_OFF);
+ // make sure we don't allow calls to save when we're
+ // not ready for them.
+ mButton.setClickable(!mDataBusy);
+ }
+
+ /**
+ * Removed the status field, with preference to displaying a toast
+ * to match the rest of settings UI.
+ */
+ private void showStatus(CharSequence statusMsg) {
+ if (statusMsg != null) {
+ Toast.makeText(this, statusMsg, Toast.LENGTH_LONG)
+ .show();
+ }
+ }
+
+ private void handleResult(boolean success, boolean invalidNumber) {
+ if (success) {
+ if (DBG) log("handleResult: success!");
+ showStatus(getResources().getText(mAddContact ?
+ R.string.fdn_contact_added : R.string.fdn_contact_updated));
+ } else {
+ if (DBG) log("handleResult: failed!");
+ if (invalidNumber) {
+ showStatus(getResources().getText(R.string.fdn_invalid_number));
+ } else {
+ // There's no way to know whether the failure is due to incorrect PIN2 or
+ // an inappropriate phone number.
+ showStatus(getResources().getText(R.string.pin2_or_fdn_invalid));
+ }
+ }
+
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ finish();
+ }
+ }, 2000);
+
+ }
+
+ private final View.OnClickListener mClicked = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mPinFieldContainer.getVisibility() != View.VISIBLE) {
+ return;
+ }
+
+ if (v == mNameField) {
+ mNumberField.requestFocus();
+ } else if (v == mNumberField) {
+ mButton.requestFocus();
+ } else if (v == mButton) {
+ // Authenticate the pin AFTER the contact information
+ // is entered, and if we're not busy.
+ if (!mDataBusy) {
+ authenticatePin2();
+ }
+ }
+ }
+ };
+
+ private final View.OnFocusChangeListener mOnFocusChangeHandler =
+ new View.OnFocusChangeListener() {
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ if (hasFocus) {
+ TextView textView = (TextView) v;
+ Selection.selectAll((Spannable) textView.getText());
+ }
+ }
+ };
+
+ private class QueryHandler extends AsyncQueryHandler {
+ public QueryHandler(ContentResolver cr) {
+ super(cr);
+ }
+
+ @Override
+ protected void onQueryComplete(int token, Object cookie, Cursor c) {
+ }
+
+ @Override
+ protected void onInsertComplete(int token, Object cookie, Uri uri) {
+ if (DBG) log("onInsertComplete");
+ displayProgress(false);
+ handleResult(uri != null, false);
+ }
+
+ @Override
+ protected void onUpdateComplete(int token, Object cookie, int result) {
+ if (DBG) log("onUpdateComplete");
+ displayProgress(false);
+ handleResult(result > 0, false);
+ }
+
+ @Override
+ protected void onDeleteComplete(int token, Object cookie, int result) {
+ }
+ }
+
+ private void log(String msg) {
+ Log.d(LOG_TAG, "[EditFdnContact] " + msg);
+ }
+}