2 * Copyright (C) 2006 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings;
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.provider.Telephony;
30 import android.support.v14.preference.MultiSelectListPreference;
31 import android.support.v14.preference.SwitchPreference;
32 import android.support.v7.preference.EditTextPreference;
33 import android.support.v7.preference.ListPreference;
34 import android.support.v7.preference.Preference;
35 import android.telephony.ServiceState;
36 import android.telephony.SubscriptionManager;
37 import android.telephony.TelephonyManager;
38 import android.text.TextUtils;
39 import android.util.Log;
40 import android.view.KeyEvent;
41 import android.view.Menu;
42 import android.view.MenuItem;
44 import com.android.internal.logging.MetricsLogger;
46 import java.util.HashSet;
49 public class ApnEditor extends InstrumentedPreferenceActivity
50 implements SharedPreferences.OnSharedPreferenceChangeListener,
51 Preference.OnPreferenceChangeListener {
53 private final static String TAG = ApnEditor.class.getSimpleName();
55 private final static String SAVED_POS = "pos";
56 private final static String KEY_AUTH_TYPE = "auth_type";
57 private final static String KEY_PROTOCOL = "apn_protocol";
58 private final static String KEY_ROAMING_PROTOCOL = "apn_roaming_protocol";
59 private final static String KEY_CARRIER_ENABLED = "carrier_enabled";
60 private final static String KEY_BEARER_MULTI = "bearer_multi";
61 private final static String KEY_MVNO_TYPE = "mvno_type";
63 private static final int MENU_DELETE = Menu.FIRST;
64 private static final int MENU_SAVE = Menu.FIRST + 1;
65 private static final int MENU_CANCEL = Menu.FIRST + 2;
66 private static final int ERROR_DIALOG_ID = 0;
68 private static String sNotSet;
69 private EditTextPreference mName;
70 private EditTextPreference mApn;
71 private EditTextPreference mProxy;
72 private EditTextPreference mPort;
73 private EditTextPreference mUser;
74 private EditTextPreference mServer;
75 private EditTextPreference mPassword;
76 private EditTextPreference mMmsc;
77 private EditTextPreference mMcc;
78 private EditTextPreference mMnc;
79 private EditTextPreference mMmsProxy;
80 private EditTextPreference mMmsPort;
81 private ListPreference mAuthType;
82 private EditTextPreference mApnType;
83 private ListPreference mProtocol;
84 private ListPreference mRoamingProtocol;
85 private SwitchPreference mCarrierEnabled;
86 private MultiSelectListPreference mBearerMulti;
87 private ListPreference mMvnoType;
88 private EditTextPreference mMvnoMatchData;
90 private String mCurMnc;
91 private String mCurMcc;
94 private Cursor mCursor;
95 private boolean mNewApn;
96 private boolean mFirstTime;
98 private Resources mRes;
99 private TelephonyManager mTelephonyManager;
100 private int mBearerInitialVal = 0;
101 private String mMvnoTypeStr;
102 private String mMvnoMatchDataStr;
105 * Standard projection for the interesting columns of a normal note.
107 private static final String[] sProjection = new String[] {
108 Telephony.Carriers._ID, // 0
109 Telephony.Carriers.NAME, // 1
110 Telephony.Carriers.APN, // 2
111 Telephony.Carriers.PROXY, // 3
112 Telephony.Carriers.PORT, // 4
113 Telephony.Carriers.USER, // 5
114 Telephony.Carriers.SERVER, // 6
115 Telephony.Carriers.PASSWORD, // 7
116 Telephony.Carriers.MMSC, // 8
117 Telephony.Carriers.MCC, // 9
118 Telephony.Carriers.MNC, // 10
119 Telephony.Carriers.NUMERIC, // 11
120 Telephony.Carriers.MMSPROXY,// 12
121 Telephony.Carriers.MMSPORT, // 13
122 Telephony.Carriers.AUTH_TYPE, // 14
123 Telephony.Carriers.TYPE, // 15
124 Telephony.Carriers.PROTOCOL, // 16
125 Telephony.Carriers.CARRIER_ENABLED, // 17
126 Telephony.Carriers.BEARER, // 18
127 Telephony.Carriers.BEARER_BITMASK, // 19
128 Telephony.Carriers.ROAMING_PROTOCOL, // 20
129 Telephony.Carriers.MVNO_TYPE, // 21
130 Telephony.Carriers.MVNO_MATCH_DATA // 22
133 private static final int ID_INDEX = 0;
134 private static final int NAME_INDEX = 1;
135 private static final int APN_INDEX = 2;
136 private static final int PROXY_INDEX = 3;
137 private static final int PORT_INDEX = 4;
138 private static final int USER_INDEX = 5;
139 private static final int SERVER_INDEX = 6;
140 private static final int PASSWORD_INDEX = 7;
141 private static final int MMSC_INDEX = 8;
142 private static final int MCC_INDEX = 9;
143 private static final int MNC_INDEX = 10;
144 private static final int MMSPROXY_INDEX = 12;
145 private static final int MMSPORT_INDEX = 13;
146 private static final int AUTH_TYPE_INDEX = 14;
147 private static final int TYPE_INDEX = 15;
148 private static final int PROTOCOL_INDEX = 16;
149 private static final int CARRIER_ENABLED_INDEX = 17;
150 private static final int BEARER_INDEX = 18;
151 private static final int BEARER_BITMASK_INDEX = 19;
152 private static final int ROAMING_PROTOCOL_INDEX = 20;
153 private static final int MVNO_TYPE_INDEX = 21;
154 private static final int MVNO_MATCH_DATA_INDEX = 22;
158 protected void onCreate(Bundle icicle) {
159 super.onCreate(icicle);
161 addPreferencesFromResource(R.xml.apn_editor);
163 sNotSet = getResources().getString(R.string.apn_not_set);
164 mName = (EditTextPreference) findPreference("apn_name");
165 mApn = (EditTextPreference) findPreference("apn_apn");
166 mProxy = (EditTextPreference) findPreference("apn_http_proxy");
167 mPort = (EditTextPreference) findPreference("apn_http_port");
168 mUser = (EditTextPreference) findPreference("apn_user");
169 mServer = (EditTextPreference) findPreference("apn_server");
170 mPassword = (EditTextPreference) findPreference("apn_password");
171 mMmsProxy = (EditTextPreference) findPreference("apn_mms_proxy");
172 mMmsPort = (EditTextPreference) findPreference("apn_mms_port");
173 mMmsc = (EditTextPreference) findPreference("apn_mmsc");
174 mMcc = (EditTextPreference) findPreference("apn_mcc");
175 mMnc = (EditTextPreference) findPreference("apn_mnc");
176 mApnType = (EditTextPreference) findPreference("apn_type");
178 mAuthType = (ListPreference) findPreference(KEY_AUTH_TYPE);
179 mAuthType.setOnPreferenceChangeListener(this);
181 mProtocol = (ListPreference) findPreference(KEY_PROTOCOL);
182 mProtocol.setOnPreferenceChangeListener(this);
184 mRoamingProtocol = (ListPreference) findPreference(KEY_ROAMING_PROTOCOL);
185 mRoamingProtocol.setOnPreferenceChangeListener(this);
187 mCarrierEnabled = (SwitchPreference) findPreference(KEY_CARRIER_ENABLED);
189 mBearerMulti = (MultiSelectListPreference) findPreference(KEY_BEARER_MULTI);
190 mBearerMulti.setOnPreferenceChangeListener(this);
192 mMvnoType = (ListPreference) findPreference(KEY_MVNO_TYPE);
193 mMvnoType.setOnPreferenceChangeListener(this);
194 mMvnoMatchData = (EditTextPreference) findPreference("mvno_match_data");
196 mRes = getResources();
198 final Intent intent = getIntent();
199 final String action = intent.getAction();
200 mSubId = intent.getIntExtra(ApnSettings.SUB_ID,
201 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
203 mFirstTime = icicle == null;
205 if (action.equals(Intent.ACTION_EDIT)) {
206 Uri uri = intent.getData();
207 if (!uri.isPathPrefixMatch(Telephony.Carriers.CONTENT_URI)) {
208 Log.e(TAG, "Edit request not for carrier table. Uri: " + uri);
213 } else if (action.equals(Intent.ACTION_INSERT)) {
214 if (mFirstTime || icicle.getInt(SAVED_POS) == 0) {
215 Uri uri = intent.getData();
216 if (!uri.isPathPrefixMatch(Telephony.Carriers.CONTENT_URI)) {
217 Log.e(TAG, "Insert request not for carrier table. Uri: " + uri);
221 mUri = getContentResolver().insert(uri, new ContentValues());
223 mUri = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI,
224 icicle.getInt(SAVED_POS));
227 mMvnoTypeStr = intent.getStringExtra(ApnSettings.MVNO_TYPE);
228 mMvnoMatchDataStr = intent.getStringExtra(ApnSettings.MVNO_MATCH_DATA);
229 // If we were unable to create a new note, then just finish
230 // this activity. A RESULT_CANCELED will be sent back to the
231 // original activity if they requested a result.
233 Log.w(TAG, "Failed to insert new telephony provider into "
234 + getIntent().getData());
239 // The new entry was created, so assume all will end well and
240 // set the result to be returned.
241 setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
248 mCursor = managedQuery(mUri, sProjection, null, null);
249 mCursor.moveToFirst();
251 mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
257 protected int getMetricsCategory() {
258 return MetricsLogger.APN_EDITOR;
262 public void onResume() {
264 getPreferenceScreen().getSharedPreferences()
265 .registerOnSharedPreferenceChangeListener(this);
269 public void onPause() {
270 getPreferenceScreen().getSharedPreferences()
271 .unregisterOnSharedPreferenceChangeListener(this);
275 private void fillUi() {
278 // Fill in all the values from the db in both text editor and summary
279 mName.setText(mCursor.getString(NAME_INDEX));
280 mApn.setText(mCursor.getString(APN_INDEX));
281 mProxy.setText(mCursor.getString(PROXY_INDEX));
282 mPort.setText(mCursor.getString(PORT_INDEX));
283 mUser.setText(mCursor.getString(USER_INDEX));
284 mServer.setText(mCursor.getString(SERVER_INDEX));
285 mPassword.setText(mCursor.getString(PASSWORD_INDEX));
286 mMmsProxy.setText(mCursor.getString(MMSPROXY_INDEX));
287 mMmsPort.setText(mCursor.getString(MMSPORT_INDEX));
288 mMmsc.setText(mCursor.getString(MMSC_INDEX));
289 mMcc.setText(mCursor.getString(MCC_INDEX));
290 mMnc.setText(mCursor.getString(MNC_INDEX));
291 mApnType.setText(mCursor.getString(TYPE_INDEX));
293 String numeric = mTelephonyManager.getSimOperator(mSubId);
294 // MCC is first 3 chars and then in 2 - 3 chars of MNC
295 if (numeric != null && numeric.length() > 4) {
297 String mcc = numeric.substring(0, 3);
299 String mnc = numeric.substring(3);
300 // Auto populate MNC and MCC for new entries, based on what SIM reports
307 int authVal = mCursor.getInt(AUTH_TYPE_INDEX);
309 mAuthType.setValueIndex(authVal);
311 mAuthType.setValue(null);
314 mProtocol.setValue(mCursor.getString(PROTOCOL_INDEX));
315 mRoamingProtocol.setValue(mCursor.getString(ROAMING_PROTOCOL_INDEX));
316 mCarrierEnabled.setChecked(mCursor.getInt(CARRIER_ENABLED_INDEX)==1);
317 mBearerInitialVal = mCursor.getInt(BEARER_INDEX);
319 HashSet<String> bearers = new HashSet<String>();
320 int bearerBitmask = mCursor.getInt(BEARER_BITMASK_INDEX);
321 if (bearerBitmask == 0) {
322 if (mBearerInitialVal == 0) {
327 while (bearerBitmask != 0) {
328 if ((bearerBitmask & 1) == 1) {
336 if (mBearerInitialVal != 0 && bearers.contains("" + mBearerInitialVal) == false) {
337 // add mBearerInitialVal to bearers
338 bearers.add("" + mBearerInitialVal);
340 mBearerMulti.setValues(bearers);
342 mMvnoType.setValue(mCursor.getString(MVNO_TYPE_INDEX));
343 mMvnoMatchData.setEnabled(false);
344 mMvnoMatchData.setText(mCursor.getString(MVNO_MATCH_DATA_INDEX));
345 if (mNewApn && mMvnoTypeStr != null && mMvnoMatchDataStr != null) {
346 mMvnoType.setValue(mMvnoTypeStr);
347 mMvnoMatchData.setText(mMvnoMatchDataStr);
351 mName.setSummary(checkNull(mName.getText()));
352 mApn.setSummary(checkNull(mApn.getText()));
353 mProxy.setSummary(checkNull(mProxy.getText()));
354 mPort.setSummary(checkNull(mPort.getText()));
355 mUser.setSummary(checkNull(mUser.getText()));
356 mServer.setSummary(checkNull(mServer.getText()));
357 mPassword.setSummary(starify(mPassword.getText()));
358 mMmsProxy.setSummary(checkNull(mMmsProxy.getText()));
359 mMmsPort.setSummary(checkNull(mMmsPort.getText()));
360 mMmsc.setSummary(checkNull(mMmsc.getText()));
361 mMcc.setSummary(checkNull(mMcc.getText()));
362 mMnc.setSummary(checkNull(mMnc.getText()));
363 mApnType.setSummary(checkNull(mApnType.getText()));
365 String authVal = mAuthType.getValue();
366 if (authVal != null) {
367 int authValIndex = Integer.parseInt(authVal);
368 mAuthType.setValueIndex(authValIndex);
370 String []values = mRes.getStringArray(R.array.apn_auth_entries);
371 mAuthType.setSummary(values[authValIndex]);
373 mAuthType.setSummary(sNotSet);
376 mProtocol.setSummary(
377 checkNull(protocolDescription(mProtocol.getValue(), mProtocol)));
378 mRoamingProtocol.setSummary(
379 checkNull(protocolDescription(mRoamingProtocol.getValue(), mRoamingProtocol)));
380 mBearerMulti.setSummary(
381 checkNull(bearerMultiDescription(mBearerMulti.getValues())));
382 mMvnoType.setSummary(
383 checkNull(mvnoDescription(mMvnoType.getValue())));
384 mMvnoMatchData.setSummary(checkNull(mMvnoMatchData.getText()));
385 // allow user to edit carrier_enabled for some APN
386 boolean ceEditable = getResources().getBoolean(R.bool.config_allow_edit_carrier_enabled);
388 mCarrierEnabled.setEnabled(true);
390 mCarrierEnabled.setEnabled(false);
395 * Returns the UI choice (e.g., "IPv4/IPv6") corresponding to the given
396 * raw value of the protocol preference (e.g., "IPV4V6"). If unknown,
399 private String protocolDescription(String raw, ListPreference protocol) {
400 int protocolIndex = protocol.findIndexOfValue(raw);
401 if (protocolIndex == -1) {
404 String[] values = mRes.getStringArray(R.array.apn_protocol_entries);
406 return values[protocolIndex];
407 } catch (ArrayIndexOutOfBoundsException e) {
413 private String bearerDescription(String raw) {
414 int mBearerIndex = mBearerMulti.findIndexOfValue(raw);
415 if (mBearerIndex == -1) {
418 String[] values = mRes.getStringArray(R.array.bearer_entries);
420 return values[mBearerIndex];
421 } catch (ArrayIndexOutOfBoundsException e) {
427 private String bearerMultiDescription(Set<String> raw) {
428 String[] values = mRes.getStringArray(R.array.bearer_entries);
429 StringBuilder retVal = new StringBuilder();
430 boolean first = true;
431 for (String bearer : raw) {
432 int bearerIndex = mBearerMulti.findIndexOfValue(bearer);
435 retVal.append(values[bearerIndex]);
438 retVal.append(", " + values[bearerIndex]);
440 } catch (ArrayIndexOutOfBoundsException e) {
444 String val = retVal.toString();
445 if (!TextUtils.isEmpty(val)) {
451 private String mvnoDescription(String newValue) {
452 int mvnoIndex = mMvnoType.findIndexOfValue(newValue);
453 String oldValue = mMvnoType.getValue();
455 if (mvnoIndex == -1) {
458 String[] values = mRes.getStringArray(R.array.mvno_type_entries);
459 if (values[mvnoIndex].equals("None")) {
460 mMvnoMatchData.setEnabled(false);
462 mMvnoMatchData.setEnabled(true);
464 if (newValue != null && newValue.equals(oldValue) == false) {
465 if (values[mvnoIndex].equals("SPN")) {
466 mMvnoMatchData.setText(mTelephonyManager.getSimOperatorName());
467 } else if (values[mvnoIndex].equals("IMSI")) {
468 String numeric = mTelephonyManager.getSimOperator(mSubId);
469 mMvnoMatchData.setText(numeric + "x");
470 } else if (values[mvnoIndex].equals("GID")) {
471 mMvnoMatchData.setText(mTelephonyManager.getGroupIdLevel1());
476 return values[mvnoIndex];
477 } catch (ArrayIndexOutOfBoundsException e) {
483 public boolean onPreferenceChange(Preference preference, Object newValue) {
484 String key = preference.getKey();
485 if (KEY_AUTH_TYPE.equals(key)) {
487 int index = Integer.parseInt((String) newValue);
488 mAuthType.setValueIndex(index);
490 String []values = mRes.getStringArray(R.array.apn_auth_entries);
491 mAuthType.setSummary(values[index]);
492 } catch (NumberFormatException e) {
495 } else if (KEY_PROTOCOL.equals(key)) {
496 String protocol = protocolDescription((String) newValue, mProtocol);
497 if (protocol == null) {
500 mProtocol.setSummary(protocol);
501 mProtocol.setValue((String) newValue);
502 } else if (KEY_ROAMING_PROTOCOL.equals(key)) {
503 String protocol = protocolDescription((String) newValue, mRoamingProtocol);
504 if (protocol == null) {
507 mRoamingProtocol.setSummary(protocol);
508 mRoamingProtocol.setValue((String) newValue);
509 } else if (KEY_BEARER_MULTI.equals(key)) {
510 String bearer = bearerMultiDescription((Set<String>) newValue);
511 if (bearer == null) {
514 mBearerMulti.setValues((Set<String>) newValue);
515 mBearerMulti.setSummary(bearer);
516 } else if (KEY_MVNO_TYPE.equals(key)) {
517 String mvno = mvnoDescription((String) newValue);
521 mMvnoType.setValue((String) newValue);
522 mMvnoType.setSummary(mvno);
529 public boolean onCreateOptionsMenu(Menu menu) {
530 super.onCreateOptionsMenu(menu);
531 // If it's a new APN, then cancel will delete the new entry in onPause
533 menu.add(0, MENU_DELETE, 0, R.string.menu_delete)
534 .setIcon(R.drawable.ic_menu_delete);
536 menu.add(0, MENU_SAVE, 0, R.string.menu_save)
537 .setIcon(android.R.drawable.ic_menu_save);
538 menu.add(0, MENU_CANCEL, 0, R.string.menu_cancel)
539 .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
544 public boolean onOptionsItemSelected(MenuItem item) {
545 switch (item.getItemId()) {
550 if (validateAndSave(false)) {
556 getContentResolver().delete(mUri, null, null);
561 return super.onOptionsItemSelected(item);
565 public boolean onKeyDown(int keyCode, KeyEvent event) {
567 case KeyEvent.KEYCODE_BACK: {
568 if (validateAndSave(false)) {
574 return super.onKeyDown(keyCode, event);
578 protected void onSaveInstanceState(Bundle icicle) {
579 super.onSaveInstanceState(icicle);
580 if (validateAndSave(true)) {
581 icicle.putInt(SAVED_POS, mCursor.getInt(ID_INDEX));
586 * Check the key fields' validity and save if valid.
587 * @param force save even if the fields are not valid, if the app is
589 * @return true if the data was saved
591 private boolean validateAndSave(boolean force) {
592 String name = checkNotSet(mName.getText());
593 String apn = checkNotSet(mApn.getText());
594 String mcc = checkNotSet(mMcc.getText());
595 String mnc = checkNotSet(mMnc.getText());
597 if (getErrorMsg() != null && !force) {
598 showDialog(ERROR_DIALOG_ID);
602 if (!mCursor.moveToFirst()) {
604 "Could not go to the first row in the Cursor when saving data.");
608 // If it's a new APN and a name or apn haven't been entered, then erase the entry
609 if (force && mNewApn && name.length() < 1 && apn.length() < 1) {
610 getContentResolver().delete(mUri, null, null);
614 ContentValues values = new ContentValues();
616 // Add a dummy name "Untitled", if the user exits the screen without adding a name but
617 // entered other information worth keeping.
618 values.put(Telephony.Carriers.NAME,
619 name.length() < 1 ? getResources().getString(R.string.untitled_apn) : name);
620 values.put(Telephony.Carriers.APN, apn);
621 values.put(Telephony.Carriers.PROXY, checkNotSet(mProxy.getText()));
622 values.put(Telephony.Carriers.PORT, checkNotSet(mPort.getText()));
623 values.put(Telephony.Carriers.MMSPROXY, checkNotSet(mMmsProxy.getText()));
624 values.put(Telephony.Carriers.MMSPORT, checkNotSet(mMmsPort.getText()));
625 values.put(Telephony.Carriers.USER, checkNotSet(mUser.getText()));
626 values.put(Telephony.Carriers.SERVER, checkNotSet(mServer.getText()));
627 values.put(Telephony.Carriers.PASSWORD, checkNotSet(mPassword.getText()));
628 values.put(Telephony.Carriers.MMSC, checkNotSet(mMmsc.getText()));
630 String authVal = mAuthType.getValue();
631 if (authVal != null) {
632 values.put(Telephony.Carriers.AUTH_TYPE, Integer.parseInt(authVal));
635 values.put(Telephony.Carriers.PROTOCOL, checkNotSet(mProtocol.getValue()));
636 values.put(Telephony.Carriers.ROAMING_PROTOCOL, checkNotSet(mRoamingProtocol.getValue()));
638 values.put(Telephony.Carriers.TYPE, checkNotSet(mApnType.getText()));
640 values.put(Telephony.Carriers.MCC, mcc);
641 values.put(Telephony.Carriers.MNC, mnc);
643 values.put(Telephony.Carriers.NUMERIC, mcc + mnc);
645 if (mCurMnc != null && mCurMcc != null) {
646 if (mCurMnc.equals(mnc) && mCurMcc.equals(mcc)) {
647 values.put(Telephony.Carriers.CURRENT, 1);
651 Set<String> bearerSet = mBearerMulti.getValues();
652 int bearerBitmask = 0;
653 for (String bearer : bearerSet) {
654 if (Integer.parseInt(bearer) == 0) {
658 bearerBitmask |= ServiceState.getBitmaskForTech(Integer.parseInt(bearer));
661 values.put(Telephony.Carriers.BEARER_BITMASK, bearerBitmask);
664 if (bearerBitmask == 0 || mBearerInitialVal == 0) {
666 } else if (ServiceState.bitmaskHasTech(bearerBitmask, mBearerInitialVal)) {
667 bearerVal = mBearerInitialVal;
669 // bearer field was being used but bitmask has changed now and does not include the
670 // initial bearer value -- setting bearer to 0 but maybe better behavior is to choose a
671 // random tech from the new bitmask??
674 values.put(Telephony.Carriers.BEARER, bearerVal);
676 values.put(Telephony.Carriers.MVNO_TYPE, checkNotSet(mMvnoType.getValue()));
677 values.put(Telephony.Carriers.MVNO_MATCH_DATA, checkNotSet(mMvnoMatchData.getText()));
679 values.put(Telephony.Carriers.CARRIER_ENABLED, mCarrierEnabled.isChecked() ? 1 : 0);
680 getContentResolver().update(mUri, values, null, null);
685 private String getErrorMsg() {
686 String errorMsg = null;
688 String name = checkNotSet(mName.getText());
689 String apn = checkNotSet(mApn.getText());
690 String mcc = checkNotSet(mMcc.getText());
691 String mnc = checkNotSet(mMnc.getText());
693 if (name.length() < 1) {
694 errorMsg = mRes.getString(R.string.error_name_empty);
695 } else if (apn.length() < 1) {
696 errorMsg = mRes.getString(R.string.error_apn_empty);
697 } else if (mcc.length() != 3) {
698 errorMsg = mRes.getString(R.string.error_mcc_not3);
699 } else if ((mnc.length() & 0xFFFE) != 2) {
700 errorMsg = mRes.getString(R.string.error_mnc_not23);
707 protected Dialog onCreateDialog(int id) {
709 if (id == ERROR_DIALOG_ID) {
710 String msg = getErrorMsg();
712 return new AlertDialog.Builder(this)
713 .setTitle(R.string.error_title)
714 .setPositiveButton(android.R.string.ok, null)
719 return super.onCreateDialog(id);
723 protected void onPrepareDialog(int id, Dialog dialog) {
724 super.onPrepareDialog(id, dialog);
726 if (id == ERROR_DIALOG_ID) {
727 String msg = getErrorMsg();
730 ((AlertDialog)dialog).setMessage(msg);
735 private void deleteApn() {
736 getContentResolver().delete(mUri, null, null);
740 private String starify(String value) {
741 if (value == null || value.length() == 0) {
744 char[] password = new char[value.length()];
745 for (int i = 0; i < password.length; i++) {
748 return new String(password);
752 private String checkNull(String value) {
753 if (value == null || value.length() == 0) {
760 private String checkNotSet(String value) {
761 if (value == null || value.equals(sNotSet)) {
768 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
769 Preference pref = findPreference(key);
771 if (pref.equals(mPassword)){
772 pref.setSummary(starify(sharedPreferences.getString(key, "")));
773 } else if (pref.equals(mCarrierEnabled) || pref.equals(mBearerMulti)) {
776 pref.setSummary(checkNull(sharedPreferences.getString(key, "")));