AndroidシステムAPN構成の詳細
13484 ワード
ここ数日ずっとシステムの原生を調整しています.アプリ内のAPN構成の問題は、設定中に手動でAPN構成オプションを追加しましたが、インタフェースではまだ見えません.だからコードについて、简単なページ表示の问题だと思っていたが、このフォローは大丈夫で、すぐにHAL层に追いついた(NND).
まず見てapkのソースコードは、packages/apps/settings/src/com/android/settings/ディレクトリの下にあります.まずApnSettingsクラスを見つけ、PreferenceActivityに継承し、Preferenceを実現します.OnPreferenceChangeListenerインタフェース.PreferencesActivityは、Androidでプログラム設定インタフェースおよびパラメータ格納を実現するために特化したActivityであり、ここでは後述しない.
public class ApnSettings extends PreferenceActivity implements
Preference.OnPreferenceChangeListener {
// URI
public static final String RESTORE_CARRIERS_URI = "content://telephony/carriers/restore";
// URI, ContentPrivoder APN
public static final String PREFERRED_APN_URI = "content://telephony/carriers/preferapn";
private static final Uri DEFAULTAPN_URI = Uri.parse(RESTORE_CARRIERS_URI);
private static final Uri PREFERAPN_URI = Uri.parse(PREFERRED_APN_URI);
// ,
private RestoreApnUiHandler mRestoreApnUiHandler;
private RestoreApnProcessHandler mRestoreApnProcessHandler;
private String mSelectedKey;
// Intent
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;
}
}
}
};
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
// activity xml ,
// res/xml/apn_settings.xml PreferenceScreen
addPreferencesFromResource(R.xml.apn_settings);
getListView().setItemsCanFocus(true); // List
// Inter , ACTION_ANY_DATA_CONNECTION_STATE_CHANGED
mMobileStateFilter = new IntentFilter(
TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
}
@Override
protected void onResume() {
super.onResume();
//
registerReceiver(mMobileStateReceiver, mMobileStateFilter);
if (!mRestoreDefaultApnMode) { //
fillList(); // Activity ListView
} else {
showDialog(DIALOG_RESTORE_DEFAULTAPN);
}
}
}
1)ここではまずonCreate()メソッドでapn_settings.xmlファイルはインタフェースのビューを構成し、実際にはPreferenceScreenです.Intentフィルタを作成し、アクションをACTION_にフィルタします.ANY_DATA_CONNECTION_STATE_CHANGED.
2)その後、onResume()メソッドにおいて、上記のACTION_を受信したときに、ブロードキャスト受信者を登録するANY_DATA_CONNECTION_STATE_CHANGED動作時、呼び出す
mMobileStateReceiverのonReceive()メソッド.その目的は、APN設定に入ると、SIMカードを差し込んでAPNの構成情報を表示できるようにすることです.その後、工場出荷時の設定を復元する必要があるかどうかを判断し、そうでない場合はfillList()メソッドを呼び出して現在のActivityを埋め、APNの構成情報を表示します.
3)まずシステム属性gsmを取得する.sim.operator.numericは、このパラメータに基づいて、システムが提供するContentProviderによってデータベース(/data/data/com.android.providers.Telephonyの下にあるtelephony.dbデータベースのcarriersテーブル)をクエリーし、対応する構成情報を取得する.その後、各ApnPreferenceに充填し、最後に各ApnPreferenceを現在のPreferenceGroupに表示します.
private void fillList() {
// gsm.sim.operator.numeric
String where = "numeric=\"" + android.os.SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "")+ "\"";
// ContentProvider
Cursor cursor = getContentResolver().query(Telephony.Carriers.CONTENT_URI, new String[] {
"_id", "name", "apn", "type"}, where, null,
Telephony.Carriers.DEFAULT_SORT_ORDER);
// Activity PreferenceGroup
PreferenceGroup apnList = (PreferenceGroup) findPreference("apn_list");
apnList.removeAll();
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,
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();
}
apnList.addPreference(pref);
} else {
mmsApnList.add(pref);
}
cursor.moveToNext();
}
cursor.close();
for (Preference preference : mmsApnList) { // preference apnList
apnList.addPreference(preference);
}
}
ここでApnPreferenceは私たちが定義したクラスで、Preferenceに継承されています.このクラスは簡単ですR.layout.によるとapn_preference_Layoutファイルは、APN構成ページの各項目をレイアウトします.主に2つのTextViewと1つのRadioButtonです.
ここでは,APN設定に入ると,データベースに既に存在するAPNエントリをどのように読み出し,UI形式で表示するかを知った.では、私たちはどのように自分が定義したAPN構成情報を追加しますか?これはOptions Menuに使います.携帯電話でMenuキーを押すとリストがポップアップします.このリストをクリックすると、対応するActivityなどに入ることができます.
@Override
public boolean onCreateOptionsMenu(Menu menu) { // Menu
super.onCreateOptionsMenu(menu);
menu.add(0, MENU_NEW, 0, // , APN
getResources().getString(R.string.menu_new))
.setIcon(android.R.drawable.ic_menu_add);
menu.add(0, MENU_RESTORE, 0,
getResources().getString(R.string.menu_restore))
.setIcon(android.R.drawable.ic_menu_upload);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { // Menu
case MENU_NEW: // APN
addNewApn();
return true;
case MENU_RESTORE: //
restoreDefaultApn();
return true;
}
return super.onOptionsItemSelected(item);
}
private void addNewApn() { // Activity, Intent.ACTION_INSERT
startActivity(new Intent(Intent.ACTION_INSERT, Telephony.Carriers.CONTENT_URI));
}
//
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
int pos = Integer.parseInt(preference.getKey());
Uri url = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI, pos);
// , Activity
startActivity(new Intent(Intent.ACTION_EDIT, url));
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;
}
APNを追加しても既存のAPNエントリを編集しても、新しいActivityに入ることで完了します.次に一致するIntentを見つけます.ACTION_EDIT,Intent.ACTION_INSERT対応するActivity ApnEditorを見つけました.ApnEditorもPreferenceActivityを継承するクラスで、SharedPreferencesを実現しました.SharedPreferenceChangeListenerとPreference.OnPreferenceChangeListenerインタフェース.
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.apn_editor);
sNotSet = getResources().getString(R.string.apn_not_set);
mName = (EditTextPreference) findPreference("apn_name");
mApn = (EditTextPreference) findPreference("apn_apn");
mProxy = (EditTextPreference) findPreference("apn_http_proxy");
mPort = (EditTextPreference) findPreference("apn_http_port");
mUser = (EditTextPreference) findPreference("apn_user");
mServer = (EditTextPreference) findPreference("apn_server");
mPassword = (EditTextPreference) findPreference("apn_password");
mMmsProxy = (EditTextPreference) findPreference("apn_mms_proxy");
mMmsPort = (EditTextPreference) findPreference("apn_mms_port");
mMmsc = (EditTextPreference) findPreference("apn_mmsc");
mMcc = (EditTextPreference) findPreference("apn_mcc");
mMnc = (EditTextPreference) findPreference("apn_mnc");
mApnType = (EditTextPreference) findPreference("apn_type");
mAuthType = (ListPreference) findPreference(KEY_AUTH_TYPE);
mAuthType.setOnPreferenceChangeListener(this);
mProtocol = (ListPreference) findPreference(KEY_PROTOCOL);
mProtocol.setOnPreferenceChangeListener(this);
mRoamingProtocol = (ListPreference) findPreference(KEY_ROAMING_PROTOCOL);
// Only enable this on CDMA phones for now, since it may cause problems on other phone
// types. (This screen is not normally accessible on CDMA phones, but is useful for
// testing.)
TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
if (tm.getCurrentPhoneType() == Phone.PHONE_TYPE_CDMA) {
mRoamingProtocol.setOnPreferenceChangeListener(this);
} else {
getPreferenceScreen().removePreference(mRoamingProtocol);
}
mCarrierEnabled = (CheckBoxPreference) findPreference(KEY_CARRIER_ENABLED);
mBearer = (ListPreference) findPreference(KEY_BEARER);
mBearer.setOnPreferenceChangeListener(this);
mRes = getResources();
final Intent intent = getIntent();
final String action = intent.getAction();
mFirstTime = icicle == null;
if (action.equals(Intent.ACTION_EDIT)) {
mUri = intent.getData();
Log.w(TAG, "llping Edit action:"+mUri.toString());
} else if (action.equals(Intent.ACTION_INSERT)) {
if (mFirstTime || icicle.getInt(SAVED_POS) == 0) {
mUri = getContentResolver().insert(intent.getData(), new ContentValues());
} else {
mUri = ContentUris.withAppendedId(Telephony.Carriers.CONTENT_URI,
icicle.getInt(SAVED_POS));
}
Log.w(TAG, "llping Insert action:"+mUri.toString());
mNewApn = true;
// If we were unable to create a new note, then just finish
// this activity. A RESULT_CANCELED will be sent back to the
// original activity if they requested a result.
if (mUri == null) {
Log.w(TAG, "Failed to insert new telephony provider into "
+ getIntent().getData());
finish();
return;
}
// The new entry was created, so assume all will end well and
// set the result to be returned.
setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
} else {
finish();
return;
}
mCursor = managedQuery(mUri, sProjection, null, null);
mCursor.moveToFirst();
fillUi();
}
記事ソース:http://www.itnose.net/detail/6024266.htmlより多くの記事:http://www.itnose.net/type/85.html