1 /* 2 * Copyright (C) 2006 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.settings; 18 19 import android.app.AlertDialog; 20 import android.app.Dialog; 21 import android.content.ContentUris; 22 import android.content.ContentValues; 23 import android.content.Intent; 24 import android.content.SharedPreferences; 25 import android.content.res.Resources; 26 import android.database.Cursor; 27 import android.net.Uri; 28 import android.os.Bundle; 29 import android.os.SystemProperties; 30 import android.preference.EditTextPreference; 31 import android.preference.ListPreference; 32 import android.preference.CheckBoxPreference; 33 import android.preference.Preference; 34 import android.preference.PreferenceActivity; 35 import android.preference.SwitchPreference; 36 import android.provider.Telephony; 37 import android.telephony.SubscriptionManager; 38 import android.telephony.TelephonyManager; 39 import android.util.Log; 40 import android.view.KeyEvent; 41 import android.view.Menu; 42 import android.view.MenuItem; 43 44 import com.android.internal.telephony.Phone; 45 import com.android.internal.telephony.PhoneConstants; 46 import com.android.internal.telephony.RILConstants; 47 import com.android.internal.telephony.TelephonyProperties; 48 49 50 public class ApnEditor extends PreferenceActivity 51 implements SharedPreferences.OnSharedPreferenceChangeListener, 52 Preference.OnPreferenceChangeListener { 53 54 private final static String TAG = ApnEditor.class.getSimpleName(); 55 56 private final static String SAVED_POS = "pos"; 57 private final static String KEY_AUTH_TYPE = "auth_type"; 58 private final static String KEY_PROTOCOL = "apn_protocol"; 59 private final static String KEY_ROAMING_PROTOCOL = "apn_roaming_protocol"; 60 private final static String KEY_CARRIER_ENABLED = "carrier_enabled"; 61 private final static String KEY_BEARER = "bearer"; 62 private final static String KEY_MVNO_TYPE = "mvno_type"; 63 64 private static final int MENU_DELETE = Menu.FIRST; 65 private static final int MENU_SAVE = Menu.FIRST + 1; 66 private static final int MENU_CANCEL = Menu.FIRST + 2; 67 private static final int ERROR_DIALOG_ID = 0; 68 69 private static String sNotSet; 70 private EditTextPreference mName; 71 private EditTextPreference mApn; 72 private EditTextPreference mProxy; 73 private EditTextPreference mPort; 74 private EditTextPreference mUser; 75 private EditTextPreference mServer; 76 private EditTextPreference mPassword; 77 private EditTextPreference mMmsc; 78 private EditTextPreference mMcc; 79 private EditTextPreference mMnc; 80 private EditTextPreference mMmsProxy; 81 private EditTextPreference mMmsPort; 82 private ListPreference mAuthType; 83 private EditTextPreference mApnType; 84 private ListPreference mProtocol; 85 private ListPreference mRoamingProtocol; 86 private SwitchPreference mCarrierEnabled; 87 private ListPreference mBearer; 88 private ListPreference mMvnoType; 89 private EditTextPreference mMvnoMatchData; 90 91 private String mCurMnc; 92 private String mCurMcc; 93 94 private Uri mUri; 95 private Cursor mCursor; 96 private boolean mNewApn; 97 private boolean mFirstTime; 98 private int mSubId; 99 private Resources mRes; 100 private TelephonyManager mTelephonyManager; 101 102 /** 103 * Standard projection for the interesting columns of a normal note. 104 */ 105 private static final String[] sProjection = new String[] { 106 Telephony.Carriers._ID, // 0 107 Telephony.Carriers.NAME, // 1 108 Telephony.Carriers.APN, // 2 109 Telephony.Carriers.PROXY, // 3 110 Telephony.Carriers.PORT, // 4 111 Telephony.Carriers.USER, // 5 112 Telephony.Carriers.SERVER, // 6 113 Telephony.Carriers.PASSWORD, // 7 114 Telephony.Carriers.MMSC, // 8 115 Telephony.Carriers.MCC, // 9 116 Telephony.Carriers.MNC, // 10 117 Telephony.Carriers.NUMERIC, // 11 118 Telephony.Carriers.MMSPROXY,// 12 119 Telephony.Carriers.MMSPORT, // 13 120 Telephony.Carriers.AUTH_TYPE, // 14 121 Telephony.Carriers.TYPE, // 15 122 Telephony.Carriers.PROTOCOL, // 16 123 Telephony.Carriers.CARRIER_ENABLED, // 17 124 Telephony.Carriers.BEARER, // 18 125 Telephony.Carriers.ROAMING_PROTOCOL, // 19 126 Telephony.Carriers.MVNO_TYPE, // 20 127 Telephony.Carriers.MVNO_MATCH_DATA // 21 128 }; 129 130 private static final int ID_INDEX = 0; 131 private static final int NAME_INDEX = 1; 132 private static final int APN_INDEX = 2; 133 private static final int PROXY_INDEX = 3; 134 private static final int PORT_INDEX = 4; 135 private static final int USER_INDEX = 5; 136 private static final int SERVER_INDEX = 6; 137 private static final int PASSWORD_INDEX = 7; 138 private static final int MMSC_INDEX = 8; 139 private static final int MCC_INDEX = 9; 140 private static final int MNC_INDEX = 10; 141 private static final int MMSPROXY_INDEX = 12; 142 private static final int MMSPORT_INDEX = 13; 143 private static final int AUTH_TYPE_INDEX = 14; 144 private static final int TYPE_INDEX = 15; 145 private static final int PROTOCOL_INDEX = 16; 146 private static final int CARRIER_ENABLED_INDEX = 17; 147 private static final int BEARER_INDEX = 18; 148 private static final int ROAMING_PROTOCOL_INDEX = 19; 149 private static final int MVNO_TYPE_INDEX = 20; 150 private static final int MVNO_MATCH_DATA_INDEX = 21; 151 152 153 @Override onCreate(Bundle icicle)154 protected void onCreate(Bundle icicle) { 155 super.onCreate(icicle); 156 157 addPreferencesFromResource(R.xml.apn_editor); 158 159 sNotSet = getResources().getString(R.string.apn_not_set); 160 mName = (EditTextPreference) findPreference("apn_name"); 161 mApn = (EditTextPreference) findPreference("apn_apn"); 162 mProxy = (EditTextPreference) findPreference("apn_http_proxy"); 163 mPort = (EditTextPreference) findPreference("apn_http_port"); 164 mUser = (EditTextPreference) findPreference("apn_user"); 165 mServer = (EditTextPreference) findPreference("apn_server"); 166 mPassword = (EditTextPreference) findPreference("apn_password"); 167 mMmsProxy = (EditTextPreference) findPreference("apn_mms_proxy"); 168 mMmsPort = (EditTextPreference) findPreference("apn_mms_port"); 169 mMmsc = (EditTextPreference) findPreference("apn_mmsc"); 170 mMcc = (EditTextPreference) findPreference("apn_mcc"); 171 mMnc = (EditTextPreference) findPreference("apn_mnc"); 172 mApnType = (EditTextPreference) findPreference("apn_type"); 173 174 mAuthType = (ListPreference) findPreference(KEY_AUTH_TYPE); 175 mAuthType.setOnPreferenceChangeListener(this); 176 177 mProtocol = (ListPreference) findPreference(KEY_PROTOCOL); 178 mProtocol.setOnPreferenceChangeListener(this); 179 180 mRoamingProtocol = (ListPreference) findPreference(KEY_ROAMING_PROTOCOL); 181 mRoamingProtocol.setOnPreferenceChangeListener(this); 182 183 mCarrierEnabled = (SwitchPreference) findPreference(KEY_CARRIER_ENABLED); 184 185 mBearer = (ListPreference) findPreference(KEY_BEARER); 186 mBearer.setOnPreferenceChangeListener(this); 187 188 mMvnoType = (ListPreference) findPreference(KEY_MVNO_TYPE); 189 mMvnoType.setOnPreferenceChangeListener(this); 190 mMvnoMatchData = (EditTextPreference) findPreference("mvno_match_data"); 191 192 mRes = getResources(); 193 194 final Intent intent = getIntent(); 195 final String action = intent.getAction(); 196 mSubId = intent.getIntExtra("sub_id", SubscriptionManager.INVALID_SUBSCRIPTION_ID); 197 198 mFirstTime = icicle == null; 199 200 if (action.equals(Intent.ACTION_EDIT)) { 201 mUri = intent.getData(); 202 } else if (action.equals(Intent.ACTION_INSERT)) { 203 if (mFirstTime || icicle.getInt(SAVED_POS) == 0) { 204 mUri = getContentResolver().insert(intent.getData(), new ContentValues()); 205 } else { 206 mUri = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, 207 icicle.getInt(SAVED_POS)); 208 } 209 mNewApn = true; 210 // If we were unable to create a new note, then just finish 211 // this activity. A RESULT_CANCELED will be sent back to the 212 // original activity if they requested a result. 213 if (mUri == null) { 214 Log.w(TAG, "Failed to insert new telephony provider into " 215 + getIntent().getData()); 216 finish(); 217 return; 218 } 219 220 // The new entry was created, so assume all will end well and 221 // set the result to be returned. 222 setResult(RESULT_OK, (new Intent()).setAction(mUri.toString())); 223 224 } else { 225 finish(); 226 return; 227 } 228 229 mCursor = managedQuery(mUri, sProjection, null, null); 230 mCursor.moveToFirst(); 231 232 mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); 233 234 fillUi(); 235 } 236 237 @Override onResume()238 public void onResume() { 239 super.onResume(); 240 getPreferenceScreen().getSharedPreferences() 241 .registerOnSharedPreferenceChangeListener(this); 242 } 243 244 @Override onPause()245 public void onPause() { 246 getPreferenceScreen().getSharedPreferences() 247 .unregisterOnSharedPreferenceChangeListener(this); 248 super.onPause(); 249 } 250 fillUi()251 private void fillUi() { 252 if (mFirstTime) { 253 mFirstTime = false; 254 // Fill in all the values from the db in both text editor and summary 255 mName.setText(mCursor.getString(NAME_INDEX)); 256 mApn.setText(mCursor.getString(APN_INDEX)); 257 mProxy.setText(mCursor.getString(PROXY_INDEX)); 258 mPort.setText(mCursor.getString(PORT_INDEX)); 259 mUser.setText(mCursor.getString(USER_INDEX)); 260 mServer.setText(mCursor.getString(SERVER_INDEX)); 261 mPassword.setText(mCursor.getString(PASSWORD_INDEX)); 262 mMmsProxy.setText(mCursor.getString(MMSPROXY_INDEX)); 263 mMmsPort.setText(mCursor.getString(MMSPORT_INDEX)); 264 mMmsc.setText(mCursor.getString(MMSC_INDEX)); 265 mMcc.setText(mCursor.getString(MCC_INDEX)); 266 mMnc.setText(mCursor.getString(MNC_INDEX)); 267 mApnType.setText(mCursor.getString(TYPE_INDEX)); 268 if (mNewApn) { 269 String numeric = mTelephonyManager.getSimOperator(mSubId); 270 // MCC is first 3 chars and then in 2 - 3 chars of MNC 271 if (numeric != null && numeric.length() > 4) { 272 // Country code 273 String mcc = numeric.substring(0, 3); 274 // Network code 275 String mnc = numeric.substring(3); 276 // Auto populate MNC and MCC for new entries, based on what SIM reports 277 mMcc.setText(mcc); 278 mMnc.setText(mnc); 279 mCurMnc = mnc; 280 mCurMcc = mcc; 281 } 282 } 283 int authVal = mCursor.getInt(AUTH_TYPE_INDEX); 284 if (authVal != -1) { 285 mAuthType.setValueIndex(authVal); 286 } else { 287 mAuthType.setValue(null); 288 } 289 290 mProtocol.setValue(mCursor.getString(PROTOCOL_INDEX)); 291 mRoamingProtocol.setValue(mCursor.getString(ROAMING_PROTOCOL_INDEX)); 292 mCarrierEnabled.setChecked(mCursor.getInt(CARRIER_ENABLED_INDEX)==1); 293 mBearer.setValue(mCursor.getString(BEARER_INDEX)); 294 mMvnoType.setValue(mCursor.getString(MVNO_TYPE_INDEX)); 295 mMvnoMatchData.setEnabled(false); 296 mMvnoMatchData.setText(mCursor.getString(MVNO_MATCH_DATA_INDEX)); 297 } 298 299 mName.setSummary(checkNull(mName.getText())); 300 mApn.setSummary(checkNull(mApn.getText())); 301 mProxy.setSummary(checkNull(mProxy.getText())); 302 mPort.setSummary(checkNull(mPort.getText())); 303 mUser.setSummary(checkNull(mUser.getText())); 304 mServer.setSummary(checkNull(mServer.getText())); 305 mPassword.setSummary(starify(mPassword.getText())); 306 mMmsProxy.setSummary(checkNull(mMmsProxy.getText())); 307 mMmsPort.setSummary(checkNull(mMmsPort.getText())); 308 mMmsc.setSummary(checkNull(mMmsc.getText())); 309 mMcc.setSummary(checkNull(mMcc.getText())); 310 mMnc.setSummary(checkNull(mMnc.getText())); 311 mApnType.setSummary(checkNull(mApnType.getText())); 312 313 String authVal = mAuthType.getValue(); 314 if (authVal != null) { 315 int authValIndex = Integer.parseInt(authVal); 316 mAuthType.setValueIndex(authValIndex); 317 318 String []values = mRes.getStringArray(R.array.apn_auth_entries); 319 mAuthType.setSummary(values[authValIndex]); 320 } else { 321 mAuthType.setSummary(sNotSet); 322 } 323 324 mProtocol.setSummary( 325 checkNull(protocolDescription(mProtocol.getValue(), mProtocol))); 326 mRoamingProtocol.setSummary( 327 checkNull(protocolDescription(mRoamingProtocol.getValue(), mRoamingProtocol))); 328 mBearer.setSummary( 329 checkNull(bearerDescription(mBearer.getValue()))); 330 mMvnoType.setSummary( 331 checkNull(mvnoDescription(mMvnoType.getValue()))); 332 mMvnoMatchData.setSummary(checkNull(mMvnoMatchData.getText())); 333 // allow user to edit carrier_enabled for some APN 334 boolean ceEditable = getResources().getBoolean(R.bool.config_allow_edit_carrier_enabled); 335 if (ceEditable) { 336 mCarrierEnabled.setEnabled(true); 337 } else { 338 mCarrierEnabled.setEnabled(false); 339 } 340 } 341 342 /** 343 * Returns the UI choice (e.g., "IPv4/IPv6") corresponding to the given 344 * raw value of the protocol preference (e.g., "IPV4V6"). If unknown, 345 * return null. 346 */ protocolDescription(String raw, ListPreference protocol)347 private String protocolDescription(String raw, ListPreference protocol) { 348 int protocolIndex = protocol.findIndexOfValue(raw); 349 if (protocolIndex == -1) { 350 return null; 351 } else { 352 String[] values = mRes.getStringArray(R.array.apn_protocol_entries); 353 try { 354 return values[protocolIndex]; 355 } catch (ArrayIndexOutOfBoundsException e) { 356 return null; 357 } 358 } 359 } 360 bearerDescription(String raw)361 private String bearerDescription(String raw) { 362 int mBearerIndex = mBearer.findIndexOfValue(raw); 363 if (mBearerIndex == -1) { 364 return null; 365 } else { 366 String[] values = mRes.getStringArray(R.array.bearer_entries); 367 try { 368 return values[mBearerIndex]; 369 } catch (ArrayIndexOutOfBoundsException e) { 370 return null; 371 } 372 } 373 } 374 mvnoDescription(String newValue)375 private String mvnoDescription(String newValue) { 376 int mvnoIndex = mMvnoType.findIndexOfValue(newValue); 377 String oldValue = mMvnoType.getValue(); 378 379 if (mvnoIndex == -1) { 380 return null; 381 } else { 382 String[] values = mRes.getStringArray(R.array.mvno_type_entries); 383 if (values[mvnoIndex].equals("None")) { 384 mMvnoMatchData.setEnabled(false); 385 } else { 386 mMvnoMatchData.setEnabled(true); 387 } 388 if (newValue != null && newValue.equals(oldValue) == false) { 389 if (values[mvnoIndex].equals("SPN")) { 390 mMvnoMatchData.setText(mTelephonyManager.getSimOperatorName()); 391 } else if (values[mvnoIndex].equals("IMSI")) { 392 String numeric = mTelephonyManager.getSimOperator(mSubId); 393 mMvnoMatchData.setText(numeric + "x"); 394 } else if (values[mvnoIndex].equals("GID")) { 395 mMvnoMatchData.setText(mTelephonyManager.getGroupIdLevel1()); 396 } 397 } 398 399 try { 400 return values[mvnoIndex]; 401 } catch (ArrayIndexOutOfBoundsException e) { 402 return null; 403 } 404 } 405 } 406 onPreferenceChange(Preference preference, Object newValue)407 public boolean onPreferenceChange(Preference preference, Object newValue) { 408 String key = preference.getKey(); 409 if (KEY_AUTH_TYPE.equals(key)) { 410 try { 411 int index = Integer.parseInt((String) newValue); 412 mAuthType.setValueIndex(index); 413 414 String []values = mRes.getStringArray(R.array.apn_auth_entries); 415 mAuthType.setSummary(values[index]); 416 } catch (NumberFormatException e) { 417 return false; 418 } 419 } else if (KEY_PROTOCOL.equals(key)) { 420 String protocol = protocolDescription((String) newValue, mProtocol); 421 if (protocol == null) { 422 return false; 423 } 424 mProtocol.setSummary(protocol); 425 mProtocol.setValue((String) newValue); 426 } else if (KEY_ROAMING_PROTOCOL.equals(key)) { 427 String protocol = protocolDescription((String) newValue, mRoamingProtocol); 428 if (protocol == null) { 429 return false; 430 } 431 mRoamingProtocol.setSummary(protocol); 432 mRoamingProtocol.setValue((String) newValue); 433 } else if (KEY_BEARER.equals(key)) { 434 String bearer = bearerDescription((String) newValue); 435 if (bearer == null) { 436 return false; 437 } 438 mBearer.setValue((String) newValue); 439 mBearer.setSummary(bearer); 440 } else if (KEY_MVNO_TYPE.equals(key)) { 441 String mvno = mvnoDescription((String) newValue); 442 if (mvno == null) { 443 return false; 444 } 445 mMvnoType.setValue((String) newValue); 446 mMvnoType.setSummary(mvno); 447 } 448 449 return true; 450 } 451 452 @Override onCreateOptionsMenu(Menu menu)453 public boolean onCreateOptionsMenu(Menu menu) { 454 super.onCreateOptionsMenu(menu); 455 // If it's a new APN, then cancel will delete the new entry in onPause 456 if (!mNewApn) { 457 menu.add(0, MENU_DELETE, 0, R.string.menu_delete) 458 .setIcon(R.drawable.ic_menu_delete); 459 } 460 menu.add(0, MENU_SAVE, 0, R.string.menu_save) 461 .setIcon(android.R.drawable.ic_menu_save); 462 menu.add(0, MENU_CANCEL, 0, R.string.menu_cancel) 463 .setIcon(android.R.drawable.ic_menu_close_clear_cancel); 464 return true; 465 } 466 467 @Override onOptionsItemSelected(MenuItem item)468 public boolean onOptionsItemSelected(MenuItem item) { 469 switch (item.getItemId()) { 470 case MENU_DELETE: 471 deleteApn(); 472 return true; 473 case MENU_SAVE: 474 if (validateAndSave(false)) { 475 finish(); 476 } 477 return true; 478 case MENU_CANCEL: 479 if (mNewApn) { 480 getContentResolver().delete(mUri, null, null); 481 } 482 finish(); 483 return true; 484 } 485 return super.onOptionsItemSelected(item); 486 } 487 488 @Override onKeyDown(int keyCode, KeyEvent event)489 public boolean onKeyDown(int keyCode, KeyEvent event) { 490 switch (keyCode) { 491 case KeyEvent.KEYCODE_BACK: { 492 if (validateAndSave(false)) { 493 finish(); 494 } 495 return true; 496 } 497 } 498 return super.onKeyDown(keyCode, event); 499 } 500 501 @Override onSaveInstanceState(Bundle icicle)502 protected void onSaveInstanceState(Bundle icicle) { 503 super.onSaveInstanceState(icicle); 504 if (validateAndSave(true)) { 505 icicle.putInt(SAVED_POS, mCursor.getInt(ID_INDEX)); 506 } 507 } 508 509 /** 510 * Check the key fields' validity and save if valid. 511 * @param force save even if the fields are not valid, if the app is 512 * being suspended 513 * @return true if the data was saved 514 */ validateAndSave(boolean force)515 private boolean validateAndSave(boolean force) { 516 String name = checkNotSet(mName.getText()); 517 String apn = checkNotSet(mApn.getText()); 518 String mcc = checkNotSet(mMcc.getText()); 519 String mnc = checkNotSet(mMnc.getText()); 520 521 if (getErrorMsg() != null && !force) { 522 showDialog(ERROR_DIALOG_ID); 523 return false; 524 } 525 526 if (!mCursor.moveToFirst()) { 527 Log.w(TAG, 528 "Could not go to the first row in the Cursor when saving data."); 529 return false; 530 } 531 532 // If it's a new APN and a name or apn haven't been entered, then erase the entry 533 if (force && mNewApn && name.length() < 1 && apn.length() < 1) { 534 getContentResolver().delete(mUri, null, null); 535 return false; 536 } 537 538 ContentValues values = new ContentValues(); 539 540 // Add a dummy name "Untitled", if the user exits the screen without adding a name but 541 // entered other information worth keeping. 542 values.put(Telephony.Carriers.NAME, 543 name.length() < 1 ? getResources().getString(R.string.untitled_apn) : name); 544 values.put(Telephony.Carriers.APN, apn); 545 values.put(Telephony.Carriers.PROXY, checkNotSet(mProxy.getText())); 546 values.put(Telephony.Carriers.PORT, checkNotSet(mPort.getText())); 547 values.put(Telephony.Carriers.MMSPROXY, checkNotSet(mMmsProxy.getText())); 548 values.put(Telephony.Carriers.MMSPORT, checkNotSet(mMmsPort.getText())); 549 values.put(Telephony.Carriers.USER, checkNotSet(mUser.getText())); 550 values.put(Telephony.Carriers.SERVER, checkNotSet(mServer.getText())); 551 values.put(Telephony.Carriers.PASSWORD, checkNotSet(mPassword.getText())); 552 values.put(Telephony.Carriers.MMSC, checkNotSet(mMmsc.getText())); 553 554 String authVal = mAuthType.getValue(); 555 if (authVal != null) { 556 values.put(Telephony.Carriers.AUTH_TYPE, Integer.parseInt(authVal)); 557 } 558 559 values.put(Telephony.Carriers.PROTOCOL, checkNotSet(mProtocol.getValue())); 560 values.put(Telephony.Carriers.ROAMING_PROTOCOL, checkNotSet(mRoamingProtocol.getValue())); 561 562 values.put(Telephony.Carriers.TYPE, checkNotSet(mApnType.getText())); 563 564 values.put(Telephony.Carriers.MCC, mcc); 565 values.put(Telephony.Carriers.MNC, mnc); 566 567 values.put(Telephony.Carriers.NUMERIC, mcc + mnc); 568 569 if (mCurMnc != null && mCurMcc != null) { 570 if (mCurMnc.equals(mnc) && mCurMcc.equals(mcc)) { 571 values.put(Telephony.Carriers.CURRENT, 1); 572 } 573 } 574 575 String bearerVal = mBearer.getValue(); 576 if (bearerVal != null) { 577 values.put(Telephony.Carriers.BEARER, Integer.parseInt(bearerVal)); 578 } 579 580 values.put(Telephony.Carriers.MVNO_TYPE, checkNotSet(mMvnoType.getValue())); 581 values.put(Telephony.Carriers.MVNO_MATCH_DATA, checkNotSet(mMvnoMatchData.getText())); 582 583 values.put(Telephony.Carriers.CARRIER_ENABLED, mCarrierEnabled.isChecked() ? 1 : 0); 584 getContentResolver().update(mUri, values, null, null); 585 586 return true; 587 } 588 getErrorMsg()589 private String getErrorMsg() { 590 String errorMsg = null; 591 592 String name = checkNotSet(mName.getText()); 593 String apn = checkNotSet(mApn.getText()); 594 String mcc = checkNotSet(mMcc.getText()); 595 String mnc = checkNotSet(mMnc.getText()); 596 597 if (name.length() < 1) { 598 errorMsg = mRes.getString(R.string.error_name_empty); 599 } else if (apn.length() < 1) { 600 errorMsg = mRes.getString(R.string.error_apn_empty); 601 } else if (mcc.length() != 3) { 602 errorMsg = mRes.getString(R.string.error_mcc_not3); 603 } else if ((mnc.length() & 0xFFFE) != 2) { 604 errorMsg = mRes.getString(R.string.error_mnc_not23); 605 } 606 607 return errorMsg; 608 } 609 610 @Override onCreateDialog(int id)611 protected Dialog onCreateDialog(int id) { 612 613 if (id == ERROR_DIALOG_ID) { 614 String msg = getErrorMsg(); 615 616 return new AlertDialog.Builder(this) 617 .setTitle(R.string.error_title) 618 .setPositiveButton(android.R.string.ok, null) 619 .setMessage(msg) 620 .create(); 621 } 622 623 return super.onCreateDialog(id); 624 } 625 626 @Override onPrepareDialog(int id, Dialog dialog)627 protected void onPrepareDialog(int id, Dialog dialog) { 628 super.onPrepareDialog(id, dialog); 629 630 if (id == ERROR_DIALOG_ID) { 631 String msg = getErrorMsg(); 632 633 if (msg != null) { 634 ((AlertDialog)dialog).setMessage(msg); 635 } 636 } 637 } 638 deleteApn()639 private void deleteApn() { 640 getContentResolver().delete(mUri, null, null); 641 finish(); 642 } 643 starify(String value)644 private String starify(String value) { 645 if (value == null || value.length() == 0) { 646 return sNotSet; 647 } else { 648 char[] password = new char[value.length()]; 649 for (int i = 0; i < password.length; i++) { 650 password[i] = '*'; 651 } 652 return new String(password); 653 } 654 } 655 checkNull(String value)656 private String checkNull(String value) { 657 if (value == null || value.length() == 0) { 658 return sNotSet; 659 } else { 660 return value; 661 } 662 } 663 checkNotSet(String value)664 private String checkNotSet(String value) { 665 if (value == null || value.equals(sNotSet)) { 666 return ""; 667 } else { 668 return value; 669 } 670 } 671 onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)672 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 673 Preference pref = findPreference(key); 674 if (pref != null) { 675 if (pref.equals(mPassword)){ 676 pref.setSummary(starify(sharedPreferences.getString(key, ""))); 677 } else if (pref.equals(mCarrierEnabled)) { 678 // do nothing 679 } else { 680 pref.setSummary(checkNull(sharedPreferences.getString(key, ""))); 681 } 682 } 683 } 684 } 685