diff options
-rw-r--r-- | res/layout/apn_preference_layout.xml | 65 | ||||
-rw-r--r-- | src/com/android/settings/ApnPreference.java | 151 | ||||
-rw-r--r-- | src/com/android/settings/ApnSettings.java | 152 |
3 files changed, 350 insertions, 18 deletions
diff --git a/res/layout/apn_preference_layout.xml b/res/layout/apn_preference_layout.xml new file mode 100644 index 0000000..2a7c2e9 --- /dev/null +++ b/res/layout/apn_preference_layout.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2009 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. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:minHeight="?android:attr/listPreferredItemHeight" + android:gravity="center_vertical"> + + <RelativeLayout + android:id="@+android:id/text_layout" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="16sp" + android:layout_marginRight="6sp" + android:layout_marginTop="6sp" + android:layout_marginBottom="6sp" + android:layout_weight="1" + android:focusable="true" + android:background="@android:drawable/menuitem_background"> + + <TextView + android:id="@+android:id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:focusable="true" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceLarge" /> + + <TextView + android:id="@+android:id/summary" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@android:id/title" + android:layout_alignLeft="@android:id/title" + android:textAppearance="?android:attr/textAppearanceSmall" + android:maxLines="2" /> + + </RelativeLayout> + + <RadioButton + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+android:id/apn_radiobutton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="4dip" + android:layout_marginRight="4dip" + android:layout_gravity="center_vertical" + android:clickable="true" /> + +</LinearLayout> diff --git a/src/com/android/settings/ApnPreference.java b/src/com/android/settings/ApnPreference.java new file mode 100644 index 0000000..74fb902 --- /dev/null +++ b/src/com/android/settings/ApnPreference.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2009 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.settings; + +import android.content.ContentUris; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.preference.Preference; +import android.provider.Telephony; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.view.View.OnClickListener; +import android.widget.CompoundButton; +import android.widget.RadioButton; +import android.widget.RelativeLayout; + +public class ApnPreference extends Preference implements + CompoundButton.OnCheckedChangeListener, OnClickListener { + final static String TAG = "ApnPreference"; + + /** + * @param context + * @param attrs + * @param defStyle + */ + public ApnPreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + /** + * @param context + * @param attrs + */ + public ApnPreference(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + /** + * @param context + */ + public ApnPreference(Context context) { + super(context); + init(); + } + + private static String mSelectedKey = null; + private static CompoundButton mCurrentChecked = null; + private boolean mProtectFromCheckedChange = false; + private boolean mSelectable = true; + + @Override + public View getView(View convertView, ViewGroup parent) { + View view = super.getView(convertView, parent); + + View widget = view.findViewById(R.id.apn_radiobutton); + if ((widget != null) && widget instanceof RadioButton) { + RadioButton rb = (RadioButton) widget; + if (mSelectable) { + rb.setOnCheckedChangeListener(this); + + boolean isChecked = getKey().equals(mSelectedKey); + if (isChecked) { + mCurrentChecked = rb; + mSelectedKey = getKey(); + } + + mProtectFromCheckedChange = true; + rb.setChecked(isChecked); + mProtectFromCheckedChange = false; + } else { + rb.setVisibility(View.GONE); + } + } + + View textLayout = view.findViewById(R.id.text_layout); + if ((textLayout != null) && textLayout instanceof RelativeLayout) { + textLayout.setOnClickListener(this); + } + + return view; + } + + private void init() { + setLayoutResource(R.layout.apn_preference_layout); + } + + public boolean isChecked() { + return getKey().equals(mSelectedKey); + } + + public void setChecked(boolean checked) { + mSelectedKey = getKey(); + } + + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + Log.i(TAG, "ID: " + getKey() + " :" + isChecked); + if (mProtectFromCheckedChange) { + return; + } + + if (isChecked) { + if (mCurrentChecked != null) { + mCurrentChecked.setChecked(false); + } + mCurrentChecked = buttonView; + mSelectedKey = getKey(); + callChangeListener(mSelectedKey); + } else { + mCurrentChecked = null; + mSelectedKey = null; + } + } + + public void onClick(android.view.View v) { + if ((v != null) && (R.id.text_layout == v.getId())) { + Context context = getContext(); + if (context != null) { + int pos = Integer.parseInt(getKey()); + Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos); + context.startActivity(new Intent(Intent.ACTION_EDIT, url)); + } + } + } + + public void setSelectable(boolean selectable) { + mSelectable = selectable; + } + + public boolean getSelectable() { + return mSelectable; + } +} diff --git a/src/com/android/settings/ApnSettings.java b/src/com/android/settings/ApnSettings.java index 87e3412..ecfdb24 100644 --- a/src/com/android/settings/ApnSettings.java +++ b/src/com/android/settings/ApnSettings.java @@ -18,10 +18,13 @@ package com.android.settings; import android.app.Dialog; import android.app.ProgressDialog; +import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.ContentUris; +import android.content.ContentValues; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; @@ -34,20 +37,33 @@ import android.preference.PreferenceActivity; import android.preference.PreferenceGroup; import android.preference.PreferenceScreen; import android.provider.Telephony; -import android.text.TextUtils; +import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; -public class ApnSettings extends PreferenceActivity { +import com.android.internal.telephony.Phone; +import com.android.internal.telephony.TelephonyIntents; +import com.android.internal.telephony.TelephonyProperties; + +import java.util.ArrayList; + +public class ApnSettings extends PreferenceActivity implements + Preference.OnPreferenceChangeListener { + static final String TAG = "ApnSettings"; public static final String EXTRA_POSITION = "position"; public static final String RESTORE_CARRIERS_URI = "content://telephony/carriers/restore"; + public static final String PREFERRED_APN_URI = + "content://telephony/carriers/preferapn"; + + public static final String APN_ID = "apn_id"; private static final int ID_INDEX = 0; private static final int NAME_INDEX = 1; private static final int APN_INDEX = 2; + private static final int TYPES_INDEX = 3; private static final int MENU_NEW = Menu.FIRST; private static final int MENU_RESTORE = Menu.FIRST + 1; @@ -58,25 +74,62 @@ public class ApnSettings extends PreferenceActivity { private static final int DIALOG_RESTORE_DEFAULTAPN = 1001; private static final Uri DEFAULTAPN_URI = Uri.parse(RESTORE_CARRIERS_URI); + private static final Uri PREFERAPN_URI = Uri.parse(PREFERRED_APN_URI); private static boolean mRestoreDefaultApnMode; private RestoreApnUiHandler mRestoreApnUiHandler; private RestoreApnProcessHandler mRestoreApnProcessHandler; - private Cursor mCursor; + private String mSelectedKey; + + private IntentFilter mMobileStateFilter; + + private final BroadcastReceiver mMobileStateReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals( + TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) { + Phone.DataState state = getMobileDataState(intent); + switch (state) { + case CONNECTED: + if (!mRestoreDefaultApnMode) { + fillList(); + } else { + showDialog(DIALOG_RESTORE_DEFAULTAPN); + } + break; + } + } + } + }; + + private static Phone.DataState getMobileDataState(Intent intent) { + String str = intent.getStringExtra(Phone.STATE_KEY); + if (str != null) { + return Enum.valueOf(Phone.DataState.class, str); + } else { + return Phone.DataState.DISCONNECTED; + } + } @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); addPreferencesFromResource(R.xml.apn_settings); + getListView().setItemsCanFocus(true); + + mMobileStateFilter = new IntentFilter( + TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); } @Override protected void onResume() { super.onResume(); + registerReceiver(mMobileStateReceiver, mMobileStateFilter); + if (!mRestoreDefaultApnMode) { fillList(); } else { @@ -84,29 +137,59 @@ public class ApnSettings extends PreferenceActivity { } } + @Override + protected void onPause() { + super.onPause(); + + unregisterReceiver(mMobileStateReceiver); + } + private void fillList() { - mCursor = managedQuery(Telephony.Carriers.CONTENT_URI, new String[] { - "_id", "name", "apn"}, null, Telephony.Carriers.DEFAULT_SORT_ORDER); + String where = "numeric=\"" + + android.os.SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC, "") + + "\""; + + Cursor cursor = managedQuery(Telephony.Carriers.CONTENT_URI, new String[] { + "_id", "name", "apn", "type"}, where, + Telephony.Carriers.DEFAULT_SORT_ORDER); PreferenceGroup apnList = (PreferenceGroup) findPreference("apn_list"); apnList.removeAll(); - mCursor.moveToFirst(); - while (!mCursor.isAfterLast()) { - String name = mCursor.getString(NAME_INDEX); - String apn = mCursor.getString(APN_INDEX); - - if (name != null && apn != null && TextUtils.getTrimmedLength(name) > 0 - && TextUtils.getTrimmedLength(apn) > 0) { - Preference pref = new Preference((Context) this); - pref.setKey(mCursor.getString(ID_INDEX)); - pref.setTitle(name); - pref.setSummary(apn); - pref.setPersistent(false); + ArrayList<Preference> mmsApnList = new ArrayList<Preference>(); + + mSelectedKey = getSelectedApnKey(); + cursor.moveToFirst(); + while (!cursor.isAfterLast()) { + String name = cursor.getString(NAME_INDEX); + String apn = cursor.getString(APN_INDEX); + String key = cursor.getString(ID_INDEX); + String type = cursor.getString(TYPES_INDEX); + + ApnPreference pref = new ApnPreference(this); + + pref.setKey(key); + pref.setTitle(name); + pref.setSummary(apn); + pref.setPersistent(false); + pref.setOnPreferenceChangeListener(this); + + boolean selectable = ((type == null) || !type.equals("mms")); + pref.setSelectable(selectable); + if (selectable) { + if ((mSelectedKey != null) && mSelectedKey.equals(key)) { + pref.setChecked(true); + } apnList.addPreference(pref); + } else { + mmsApnList.add(pref); } + cursor.moveToNext(); + } + cursor.close(); - mCursor.moveToNext(); + for (Preference preference : mmsApnList) { + apnList.addPreference(preference); } } @@ -148,6 +231,39 @@ public class ApnSettings extends PreferenceActivity { return true; } + public boolean onPreferenceChange(Preference preference, Object newValue) { + Log.d(TAG, "onPreferenceChange(): Preference - " + preference + + ", newValue - " + newValue + ", newValue type - " + + newValue.getClass()); + if (newValue instanceof String) { + setSelectedApnKey((String) newValue); + } + + return true; + } + + private void setSelectedApnKey(String key) { + mSelectedKey = key; + ContentResolver resolver = getContentResolver(); + + ContentValues values = new ContentValues(); + values.put(APN_ID, mSelectedKey); + resolver.update(PREFERAPN_URI, values, null, null); + } + + private String getSelectedApnKey() { + String key = null; + + Cursor cursor = managedQuery(PREFERAPN_URI, new String[] {"_id"}, + null, Telephony.Carriers.DEFAULT_SORT_ORDER); + if (cursor.getCount() > 0) { + cursor.moveToFirst(); + key = cursor.getString(ID_INDEX); + } + cursor.close(); + return key; + } + private boolean restoreDefaultApn() { showDialog(DIALOG_RESTORE_DEFAULTAPN); mRestoreDefaultApnMode = true; |