Initial checkin of AOSP Messaging app.
b/23110861 Change-Id: I9aa980d7569247d6b2ca78f5dcb4502e1eaadb8a
This commit is contained in:
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.messaging.ui.appsettings;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.provider.Telephony;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.data.ParticipantData;
|
||||
import com.android.messaging.sms.ApnDatabase;
|
||||
import com.android.messaging.sms.BugleApnSettingsLoader;
|
||||
import com.android.messaging.ui.BugleActionBarActivity;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
import com.android.messaging.util.PhoneUtils;
|
||||
|
||||
public class ApnEditorActivity extends BugleActionBarActivity {
|
||||
private static final int ERROR_DIALOG_ID = 0;
|
||||
private static final String ERROR_MESSAGE_KEY = "error_msg";
|
||||
private ApnEditorFragment mApnEditorFragment;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
// Display the fragment as the main content.
|
||||
mApnEditorFragment = new ApnEditorFragment();
|
||||
mApnEditorFragment.setSubId(getIntent().getIntExtra(UIIntents.UI_INTENT_EXTRA_SUB_ID,
|
||||
ParticipantData.DEFAULT_SELF_SUB_ID));
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(android.R.id.content, mApnEditorFragment)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
NavUtils.navigateUpFromSameTask(this);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id, Bundle args) {
|
||||
|
||||
if (id == ERROR_DIALOG_ID) {
|
||||
String msg = args.getString(ERROR_MESSAGE_KEY);
|
||||
|
||||
return new AlertDialog.Builder(this)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.setMessage(msg)
|
||||
.create();
|
||||
}
|
||||
|
||||
return super.onCreateDialog(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_BACK: {
|
||||
if (mApnEditorFragment.validateAndSave(false)) {
|
||||
finish();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
|
||||
super.onPrepareDialog(id, dialog);
|
||||
|
||||
if (id == ERROR_DIALOG_ID) {
|
||||
final String msg = args.getString(ERROR_MESSAGE_KEY);
|
||||
|
||||
if (msg != null) {
|
||||
((AlertDialog) dialog).setMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ApnEditorFragment extends PreferenceFragment implements
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
private static final String SAVED_POS = "pos";
|
||||
|
||||
private static final int MENU_DELETE = Menu.FIRST;
|
||||
private static final int MENU_SAVE = Menu.FIRST + 1;
|
||||
private static final int MENU_CANCEL = Menu.FIRST + 2;
|
||||
|
||||
private EditTextPreference mMmsProxy;
|
||||
private EditTextPreference mMmsPort;
|
||||
private EditTextPreference mName;
|
||||
private EditTextPreference mMmsc;
|
||||
private EditTextPreference mMcc;
|
||||
private EditTextPreference mMnc;
|
||||
private static String sNotSet;
|
||||
|
||||
private String mCurMnc;
|
||||
private String mCurMcc;
|
||||
|
||||
private Cursor mCursor;
|
||||
private boolean mNewApn;
|
||||
private boolean mFirstTime;
|
||||
private String mCurrentId;
|
||||
|
||||
private int mSubId;
|
||||
|
||||
/**
|
||||
* Standard projection for the interesting columns of a normal note.
|
||||
*/
|
||||
private static final String[] sProjection = new String[] {
|
||||
Telephony.Carriers._ID, // 0
|
||||
Telephony.Carriers.NAME, // 1
|
||||
Telephony.Carriers.MMSC, // 2
|
||||
Telephony.Carriers.MCC, // 3
|
||||
Telephony.Carriers.MNC, // 4
|
||||
Telephony.Carriers.NUMERIC, // 5
|
||||
Telephony.Carriers.MMSPROXY, // 6
|
||||
Telephony.Carriers.MMSPORT, // 7
|
||||
Telephony.Carriers.TYPE, // 8
|
||||
};
|
||||
|
||||
private static final int ID_INDEX = 0;
|
||||
private static final int NAME_INDEX = 1;
|
||||
private static final int MMSC_INDEX = 2;
|
||||
private static final int MCC_INDEX = 3;
|
||||
private static final int MNC_INDEX = 4;
|
||||
private static final int NUMERIC_INDEX = 5;
|
||||
private static final int MMSPROXY_INDEX = 6;
|
||||
private static final int MMSPORT_INDEX = 7;
|
||||
private static final int TYPE_INDEX = 8;
|
||||
|
||||
private SQLiteDatabase mDatabase;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
addPreferencesFromResource(R.xml.apn_editor);
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
sNotSet = getResources().getString(R.string.apn_not_set);
|
||||
mName = (EditTextPreference) findPreference("apn_name");
|
||||
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");
|
||||
|
||||
final Intent intent = getActivity().getIntent();
|
||||
|
||||
mFirstTime = savedInstanceState == null;
|
||||
mCurrentId = intent.getStringExtra(UIIntents.UI_INTENT_EXTRA_APN_ROW_ID);
|
||||
mNewApn = mCurrentId == null;
|
||||
|
||||
mDatabase = ApnDatabase.getApnDatabase().getWritableDatabase();
|
||||
|
||||
if (mNewApn) {
|
||||
fillUi();
|
||||
} else {
|
||||
// Do initial query not on the UI thread
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
if (mCurrentId != null) {
|
||||
String selection = Telephony.Carriers._ID + " =?";
|
||||
String[] selectionArgs = new String[]{ mCurrentId };
|
||||
mCursor = mDatabase.query(ApnDatabase.APN_TABLE, sProjection, selection,
|
||||
selectionArgs, null, null, null, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result) {
|
||||
if (mCursor == null) {
|
||||
getActivity().finish();
|
||||
return;
|
||||
}
|
||||
mCursor.moveToFirst();
|
||||
|
||||
fillUi();
|
||||
}
|
||||
}.execute((Void) null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mCursor != null) {
|
||||
mCursor.close();
|
||||
mCursor = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.unregisterOnSharedPreferenceChangeListener(this);
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
public void setSubId(final int subId) {
|
||||
mSubId = subId;
|
||||
}
|
||||
|
||||
private void fillUi() {
|
||||
if (mNewApn) {
|
||||
mMcc.setText(null);
|
||||
mMnc.setText(null);
|
||||
String numeric = PhoneUtils.get(mSubId).getSimOperatorNumeric();
|
||||
// MCC is first 3 chars and then in 2 - 3 chars of MNC
|
||||
if (numeric != null && numeric.length() > 4) {
|
||||
// Country code
|
||||
String mcc = numeric.substring(0, 3);
|
||||
// Network code
|
||||
String mnc = numeric.substring(3);
|
||||
// Auto populate MNC and MCC for new entries, based on what SIM reports
|
||||
mMcc.setText(mcc);
|
||||
mMnc.setText(mnc);
|
||||
mCurMnc = mnc;
|
||||
mCurMcc = mcc;
|
||||
}
|
||||
mName.setText(null);
|
||||
mMmsProxy.setText(null);
|
||||
mMmsPort.setText(null);
|
||||
mMmsc.setText(null);
|
||||
} else if (mFirstTime) {
|
||||
mFirstTime = false;
|
||||
// Fill in all the values from the db in both text editor and summary
|
||||
mName.setText(mCursor.getString(NAME_INDEX));
|
||||
mMmsProxy.setText(mCursor.getString(MMSPROXY_INDEX));
|
||||
mMmsPort.setText(mCursor.getString(MMSPORT_INDEX));
|
||||
mMmsc.setText(mCursor.getString(MMSC_INDEX));
|
||||
mMcc.setText(mCursor.getString(MCC_INDEX));
|
||||
mMnc.setText(mCursor.getString(MNC_INDEX));
|
||||
}
|
||||
|
||||
mName.setSummary(checkNull(mName.getText()));
|
||||
mMmsProxy.setSummary(checkNull(mMmsProxy.getText()));
|
||||
mMmsPort.setSummary(checkNull(mMmsPort.getText()));
|
||||
mMmsc.setSummary(checkNull(mMmsc.getText()));
|
||||
mMcc.setSummary(checkNull(mMcc.getText()));
|
||||
mMnc.setSummary(checkNull(mMnc.getText()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
// If it's a new APN, then cancel will delete the new entry in onPause
|
||||
if (!mNewApn) {
|
||||
menu.add(0, MENU_DELETE, 0, R.string.menu_delete_apn)
|
||||
.setIcon(R.drawable.ic_delete_small_dark);
|
||||
}
|
||||
menu.add(0, MENU_SAVE, 0, R.string.menu_save_apn)
|
||||
.setIcon(android.R.drawable.ic_menu_save);
|
||||
menu.add(0, MENU_CANCEL, 0, R.string.menu_discard_apn_change)
|
||||
.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MENU_DELETE:
|
||||
deleteApn();
|
||||
return true;
|
||||
|
||||
case MENU_SAVE:
|
||||
if (validateAndSave(false)) {
|
||||
getActivity().finish();
|
||||
}
|
||||
return true;
|
||||
|
||||
case MENU_CANCEL:
|
||||
getActivity().finish();
|
||||
return true;
|
||||
|
||||
case android.R.id.home:
|
||||
getActivity().onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle icicle) {
|
||||
super.onSaveInstanceState(icicle);
|
||||
if (validateAndSave(true) && mCursor != null) {
|
||||
icicle.putInt(SAVED_POS, mCursor.getInt(ID_INDEX));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the key fields' validity and save if valid.
|
||||
* @param force save even if the fields are not valid, if the app is
|
||||
* being suspended
|
||||
* @return true if the data was saved
|
||||
*/
|
||||
private boolean validateAndSave(boolean force) {
|
||||
final String name = checkNotSet(mName.getText());
|
||||
final String mcc = checkNotSet(mMcc.getText());
|
||||
final String mnc = checkNotSet(mMnc.getText());
|
||||
|
||||
if (getErrorMsg() != null && !force) {
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putString(ERROR_MESSAGE_KEY, getErrorMsg());
|
||||
getActivity().showDialog(ERROR_DIALOG_ID, bundle);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make database changes not on the UI thread
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
// Add a dummy name "Untitled", if the user exits the screen without adding a
|
||||
// name but entered other information worth keeping.
|
||||
values.put(Telephony.Carriers.NAME, name.length() < 1 ?
|
||||
getResources().getString(R.string.untitled_apn) : name);
|
||||
values.put(Telephony.Carriers.MMSPROXY, checkNotSet(mMmsProxy.getText()));
|
||||
values.put(Telephony.Carriers.MMSPORT, checkNotSet(mMmsPort.getText()));
|
||||
values.put(Telephony.Carriers.MMSC, checkNotSet(mMmsc.getText()));
|
||||
|
||||
values.put(Telephony.Carriers.TYPE, BugleApnSettingsLoader.APN_TYPE_MMS);
|
||||
|
||||
values.put(Telephony.Carriers.MCC, mcc);
|
||||
values.put(Telephony.Carriers.MNC, mnc);
|
||||
|
||||
values.put(Telephony.Carriers.NUMERIC, mcc + mnc);
|
||||
|
||||
if (mCurMnc != null && mCurMcc != null) {
|
||||
if (mCurMnc.equals(mnc) && mCurMcc.equals(mcc)) {
|
||||
values.put(Telephony.Carriers.CURRENT, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (mNewApn) {
|
||||
mDatabase.insert(ApnDatabase.APN_TABLE, null, values);
|
||||
} else {
|
||||
// update the APN
|
||||
String selection = Telephony.Carriers._ID + " =?";
|
||||
String[] selectionArgs = new String[]{ mCurrentId };
|
||||
int updated = mDatabase.update(ApnDatabase.APN_TABLE, values,
|
||||
selection, selectionArgs);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}.execute((Void) null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void deleteApn() {
|
||||
// Make database changes not on the UI thread
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
// delete the APN
|
||||
String where = Telephony.Carriers._ID + " =?";
|
||||
String[] whereArgs = new String[]{ mCurrentId };
|
||||
|
||||
mDatabase.delete(ApnDatabase.APN_TABLE, where, whereArgs);
|
||||
return null;
|
||||
}
|
||||
}.execute((Void) null);
|
||||
|
||||
getActivity().finish();
|
||||
}
|
||||
|
||||
private String checkNull(String value) {
|
||||
if (value == null || value.length() == 0) {
|
||||
return sNotSet;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
Preference pref = findPreference(key);
|
||||
if (pref != null) {
|
||||
pref.setSummary(checkNull(sharedPreferences.getString(key, "")));
|
||||
}
|
||||
}
|
||||
|
||||
private String getErrorMsg() {
|
||||
String errorMsg = null;
|
||||
|
||||
String name = checkNotSet(mName.getText());
|
||||
String mcc = checkNotSet(mMcc.getText());
|
||||
String mnc = checkNotSet(mMnc.getText());
|
||||
|
||||
if (name.length() < 1) {
|
||||
errorMsg = getString(R.string.error_apn_name_empty);
|
||||
} else if (mcc.length() != 3) {
|
||||
errorMsg = getString(R.string.error_mcc_not3);
|
||||
} else if ((mnc.length() & 0xFFFE) != 2) {
|
||||
errorMsg = getString(R.string.error_mnc_not23);
|
||||
}
|
||||
|
||||
return errorMsg;
|
||||
}
|
||||
|
||||
private String checkNotSet(String value) {
|
||||
if (value == null || value.equals(sNotSet)) {
|
||||
return "";
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.messaging.ui.appsettings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.preference.Preference;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.data.ParticipantData;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
|
||||
/**
|
||||
* ApnPreference implements a pref, typically used as a list item, that has a title/summary on
|
||||
* the left and a radio button on the right.
|
||||
*
|
||||
*/
|
||||
public class ApnPreference extends Preference implements
|
||||
CompoundButton.OnCheckedChangeListener, OnClickListener {
|
||||
static final String TAG = "ApnPreference";
|
||||
|
||||
public ApnPreference(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
public ApnPreference(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, R.attr.apnPreferenceStyle);
|
||||
}
|
||||
|
||||
public ApnPreference(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
private static String mSelectedKey = null;
|
||||
private static CompoundButton mCurrentChecked = null;
|
||||
private boolean mProtectFromCheckedChange = false;
|
||||
private boolean mSelectable = true;
|
||||
private int mSubId = ParticipantData.DEFAULT_SELF_SUB_ID;
|
||||
|
||||
@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);
|
||||
}
|
||||
setApnRadioButtonContentDescription(rb);
|
||||
}
|
||||
|
||||
View textLayout = view.findViewById(R.id.text_layout);
|
||||
if ((textLayout != null) && textLayout instanceof RelativeLayout) {
|
||||
textLayout.setOnClickListener(this);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
public void setApnRadioButtonContentDescription(final CompoundButton buttonView) {
|
||||
final View widget = (View) buttonView.getParent();
|
||||
final TextView tv = (TextView) widget.findViewById(android.R.id.title);
|
||||
final String apnTitle = tv.getText().toString();
|
||||
buttonView.setContentDescription(apnTitle);
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return getKey().equals(mSelectedKey);
|
||||
}
|
||||
|
||||
public void setChecked() {
|
||||
mSelectedKey = getKey();
|
||||
}
|
||||
|
||||
public void setSubId(final int subId) {
|
||||
mSubId = subId;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
setApnRadioButtonContentDescription(buttonView);
|
||||
}
|
||||
|
||||
public void onClick(android.view.View v) {
|
||||
if ((v != null) && (R.id.text_layout == v.getId())) {
|
||||
Context context = getContext();
|
||||
if (context != null) {
|
||||
context.startActivity(
|
||||
UIIntents.get().getApnEditorIntent(context, getKey(), mSubId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectable(boolean selectable) {
|
||||
mSelectable = selectable;
|
||||
}
|
||||
|
||||
public boolean getSelectable() {
|
||||
return mSelectable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.messaging.ui.appsettings;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.UserManager;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceGroup;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.provider.Telephony;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.data.ParticipantData;
|
||||
import com.android.messaging.sms.ApnDatabase;
|
||||
import com.android.messaging.sms.BugleApnSettingsLoader;
|
||||
import com.android.messaging.ui.BugleActionBarActivity;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
import com.android.messaging.util.OsUtil;
|
||||
import com.android.messaging.util.PhoneUtils;
|
||||
|
||||
public class ApnSettingsActivity extends BugleActionBarActivity {
|
||||
private static final int DIALOG_RESTORE_DEFAULTAPN = 1001;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
// Display the fragment as the main content.
|
||||
final ApnSettingsFragment fragment = new ApnSettingsFragment();
|
||||
fragment.setSubId(getIntent().getIntExtra(UIIntents.UI_INTENT_EXTRA_SUB_ID,
|
||||
ParticipantData.DEFAULT_SELF_SUB_ID));
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(android.R.id.content, fragment)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
NavUtils.navigateUpFromSameTask(this);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
if (id == DIALOG_RESTORE_DEFAULTAPN) {
|
||||
ProgressDialog dialog = new ProgressDialog(this);
|
||||
dialog.setMessage(getResources().getString(R.string.restore_default_apn));
|
||||
dialog.setCancelable(false);
|
||||
return dialog;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class ApnSettingsFragment extends PreferenceFragment implements
|
||||
Preference.OnPreferenceChangeListener {
|
||||
public static final String EXTRA_POSITION = "position";
|
||||
|
||||
public static final String APN_ID = "apn_id";
|
||||
|
||||
private static final String[] APN_PROJECTION = {
|
||||
Telephony.Carriers._ID, // 0
|
||||
Telephony.Carriers.NAME, // 1
|
||||
Telephony.Carriers.APN, // 2
|
||||
Telephony.Carriers.TYPE // 3
|
||||
};
|
||||
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;
|
||||
|
||||
private static final int EVENT_RESTORE_DEFAULTAPN_START = 1;
|
||||
private static final int EVENT_RESTORE_DEFAULTAPN_COMPLETE = 2;
|
||||
|
||||
private static boolean mRestoreDefaultApnMode;
|
||||
|
||||
private RestoreApnUiHandler mRestoreApnUiHandler;
|
||||
private RestoreApnProcessHandler mRestoreApnProcessHandler;
|
||||
private HandlerThread mRestoreDefaultApnThread;
|
||||
|
||||
private String mSelectedKey;
|
||||
|
||||
private static final ContentValues sCurrentNullMap;
|
||||
private static final ContentValues sCurrentSetMap;
|
||||
|
||||
private UserManager mUm;
|
||||
|
||||
private boolean mUnavailable;
|
||||
private int mSubId;
|
||||
|
||||
static {
|
||||
sCurrentNullMap = new ContentValues(1);
|
||||
sCurrentNullMap.putNull(Telephony.Carriers.CURRENT);
|
||||
|
||||
sCurrentSetMap = new ContentValues(1);
|
||||
sCurrentSetMap.put(Telephony.Carriers.CURRENT, "2"); // 2 for user-selected APN,
|
||||
// 1 for Bugle-selected APN
|
||||
}
|
||||
|
||||
private SQLiteDatabase mDatabase;
|
||||
|
||||
public void setSubId(final int subId) {
|
||||
mSubId = subId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
mDatabase = ApnDatabase.getApnDatabase().getWritableDatabase();
|
||||
|
||||
if (OsUtil.isAtLeastL()) {
|
||||
mUm = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
|
||||
if (!mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
} else {
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
final ListView lv = (ListView) getView().findViewById(android.R.id.list);
|
||||
TextView empty = (TextView) getView().findViewById(android.R.id.empty);
|
||||
if (empty != null) {
|
||||
empty.setText(R.string.apn_settings_not_available);
|
||||
lv.setEmptyView(empty);
|
||||
}
|
||||
|
||||
if (OsUtil.isAtLeastL() &&
|
||||
mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
|
||||
mUnavailable = true;
|
||||
setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getActivity()));
|
||||
return;
|
||||
}
|
||||
|
||||
addPreferencesFromResource(R.xml.apn_settings);
|
||||
|
||||
lv.setItemsCanFocus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if (mUnavailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mRestoreDefaultApnMode) {
|
||||
fillList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
if (mUnavailable) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
if (mRestoreDefaultApnThread != null) {
|
||||
mRestoreDefaultApnThread.quit();
|
||||
}
|
||||
}
|
||||
|
||||
private void fillList() {
|
||||
final String mccMnc = PhoneUtils.getMccMncString(PhoneUtils.get(mSubId).getMccMnc());
|
||||
|
||||
new AsyncTask<Void, Void, Cursor>() {
|
||||
@Override
|
||||
protected Cursor doInBackground(Void... params) {
|
||||
String selection = Telephony.Carriers.NUMERIC + " =?";
|
||||
String[] selectionArgs = new String[]{ mccMnc };
|
||||
final Cursor cursor = mDatabase.query(ApnDatabase.APN_TABLE, APN_PROJECTION,
|
||||
selection, selectionArgs, null, null, null, null);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Cursor cursor) {
|
||||
if (cursor != null) {
|
||||
try {
|
||||
PreferenceGroup apnList = (PreferenceGroup)
|
||||
findPreference(getString(R.string.apn_list_pref_key));
|
||||
apnList.removeAll();
|
||||
|
||||
mSelectedKey = BugleApnSettingsLoader.getFirstTryApn(mDatabase, mccMnc);
|
||||
while (cursor.moveToNext()) {
|
||||
String name = cursor.getString(NAME_INDEX);
|
||||
String apn = cursor.getString(APN_INDEX);
|
||||
String key = cursor.getString(ID_INDEX);
|
||||
String type = cursor.getString(TYPES_INDEX);
|
||||
|
||||
if (BugleApnSettingsLoader.isValidApnType(type,
|
||||
BugleApnSettingsLoader.APN_TYPE_MMS)) {
|
||||
ApnPreference pref = new ApnPreference(getActivity());
|
||||
pref.setKey(key);
|
||||
pref.setTitle(name);
|
||||
pref.setSummary(apn);
|
||||
pref.setPersistent(false);
|
||||
pref.setOnPreferenceChangeListener(ApnSettingsFragment.this);
|
||||
pref.setSelectable(true);
|
||||
|
||||
// Turn on the radio button for the currently selected APN. If
|
||||
// there is no selected APN, don't select an APN.
|
||||
if ((mSelectedKey != null && mSelectedKey.equals(key))) {
|
||||
pref.setChecked();
|
||||
}
|
||||
apnList.addPreference(pref);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.execute((Void) null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
if (!mUnavailable) {
|
||||
menu.add(0, MENU_NEW, 0,
|
||||
getResources().getString(R.string.menu_new_apn))
|
||||
.setIcon(R.drawable.ic_add_gray)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
menu.add(0, MENU_RESTORE, 0,
|
||||
getResources().getString(R.string.menu_restore_default_apn))
|
||||
.setIcon(android.R.drawable.ic_menu_upload);
|
||||
}
|
||||
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MENU_NEW:
|
||||
addNewApn();
|
||||
return true;
|
||||
|
||||
case MENU_RESTORE:
|
||||
restoreDefaultApn();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void addNewApn() {
|
||||
startActivity(UIIntents.get().getApnEditorIntent(getActivity(), null, mSubId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
|
||||
Preference preference) {
|
||||
startActivity(
|
||||
UIIntents.get().getApnEditorIntent(getActivity(), preference.getKey(), mSubId));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (newValue instanceof String) {
|
||||
setSelectedApnKey((String) newValue);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// current=2 means user selected APN
|
||||
private static final String UPDATE_SELECTION = Telephony.Carriers.CURRENT + " =?";
|
||||
private static final String[] UPDATE_SELECTION_ARGS = new String[] { "2" };
|
||||
private void setSelectedApnKey(final String key) {
|
||||
mSelectedKey = key;
|
||||
|
||||
// Make database changes not on the UI thread
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
// null out the previous "current=2" APN
|
||||
mDatabase.update(ApnDatabase.APN_TABLE, sCurrentNullMap,
|
||||
UPDATE_SELECTION, UPDATE_SELECTION_ARGS);
|
||||
|
||||
// set the new "current" APN (2)
|
||||
String selection = Telephony.Carriers._ID + " =?";
|
||||
String[] selectionArgs = new String[]{ key };
|
||||
|
||||
mDatabase.update(ApnDatabase.APN_TABLE, sCurrentSetMap,
|
||||
selection, selectionArgs);
|
||||
return null;
|
||||
}
|
||||
}.execute((Void) null);
|
||||
}
|
||||
|
||||
private boolean restoreDefaultApn() {
|
||||
getActivity().showDialog(DIALOG_RESTORE_DEFAULTAPN);
|
||||
mRestoreDefaultApnMode = true;
|
||||
|
||||
if (mRestoreApnUiHandler == null) {
|
||||
mRestoreApnUiHandler = new RestoreApnUiHandler();
|
||||
}
|
||||
|
||||
if (mRestoreApnProcessHandler == null ||
|
||||
mRestoreDefaultApnThread == null) {
|
||||
mRestoreDefaultApnThread = new HandlerThread(
|
||||
"Restore default APN Handler: Process Thread");
|
||||
mRestoreDefaultApnThread.start();
|
||||
mRestoreApnProcessHandler = new RestoreApnProcessHandler(
|
||||
mRestoreDefaultApnThread.getLooper(), mRestoreApnUiHandler);
|
||||
}
|
||||
|
||||
mRestoreApnProcessHandler.sendEmptyMessage(EVENT_RESTORE_DEFAULTAPN_START);
|
||||
return true;
|
||||
}
|
||||
|
||||
private class RestoreApnUiHandler extends Handler {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case EVENT_RESTORE_DEFAULTAPN_COMPLETE:
|
||||
fillList();
|
||||
getPreferenceScreen().setEnabled(true);
|
||||
mRestoreDefaultApnMode = false;
|
||||
final Activity activity = getActivity();
|
||||
activity.dismissDialog(DIALOG_RESTORE_DEFAULTAPN);
|
||||
Toast.makeText(activity, getResources().getString(
|
||||
R.string.restore_default_apn_completed), Toast.LENGTH_LONG)
|
||||
.show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class RestoreApnProcessHandler extends Handler {
|
||||
private Handler mCachedRestoreApnUiHandler;
|
||||
|
||||
public RestoreApnProcessHandler(Looper looper, Handler restoreApnUiHandler) {
|
||||
super(looper);
|
||||
this.mCachedRestoreApnUiHandler = restoreApnUiHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case EVENT_RESTORE_DEFAULTAPN_START:
|
||||
ApnDatabase.forceBuildAndLoadApnTables();
|
||||
mCachedRestoreApnUiHandler.sendEmptyMessage(
|
||||
EVENT_RESTORE_DEFAULTAPN_COMPLETE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.messaging.ui.appsettings;
|
||||
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.preference.RingtonePreference;
|
||||
import android.preference.TwoStatePreference;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.ui.BugleActionBarActivity;
|
||||
import com.android.messaging.ui.LicenseActivity;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
import com.android.messaging.util.BuglePrefs;
|
||||
import com.android.messaging.util.DebugUtils;
|
||||
import com.android.messaging.util.OsUtil;
|
||||
import com.android.messaging.util.PhoneUtils;
|
||||
|
||||
public class ApplicationSettingsActivity extends BugleActionBarActivity {
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
final boolean topLevel = getIntent().getBooleanExtra(
|
||||
UIIntents.UI_INTENT_EXTRA_TOP_LEVEL_SETTINGS, false);
|
||||
if (topLevel) {
|
||||
getSupportActionBar().setTitle(getString(R.string.settings_activity_title));
|
||||
}
|
||||
|
||||
FragmentTransaction ft = getFragmentManager().beginTransaction();
|
||||
ft.replace(android.R.id.content, new ApplicationSettingsFragment());
|
||||
ft.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
if (super.onCreateOptionsMenu(menu)) {
|
||||
return true;
|
||||
}
|
||||
getMenuInflater().inflate(R.menu.settings_menu, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
NavUtils.navigateUpFromSameTask(this);
|
||||
return true;
|
||||
case R.id.action_license:
|
||||
final Intent intent = new Intent(this, LicenseActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
public static class ApplicationSettingsFragment extends PreferenceFragment implements
|
||||
OnSharedPreferenceChangeListener {
|
||||
|
||||
private String mNotificationsEnabledPreferenceKey;
|
||||
private TwoStatePreference mNotificationsEnabledPreference;
|
||||
private String mRingtonePreferenceKey;
|
||||
private RingtonePreference mRingtonePreference;
|
||||
private Preference mVibratePreference;
|
||||
private String mSmsDisabledPrefKey;
|
||||
private Preference mSmsDisabledPreference;
|
||||
private String mSmsEnabledPrefKey;
|
||||
private Preference mSmsEnabledPreference;
|
||||
private boolean mIsSmsPreferenceClicked;
|
||||
|
||||
public ApplicationSettingsFragment() {
|
||||
// Required empty constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getPreferenceManager().setSharedPreferencesName(BuglePrefs.SHARED_PREFERENCES_NAME);
|
||||
addPreferencesFromResource(R.xml.preferences_application);
|
||||
|
||||
mNotificationsEnabledPreferenceKey =
|
||||
getString(R.string.notifications_enabled_pref_key);
|
||||
mNotificationsEnabledPreference = (TwoStatePreference) findPreference(
|
||||
mNotificationsEnabledPreferenceKey);
|
||||
mRingtonePreferenceKey = getString(R.string.notification_sound_pref_key);
|
||||
mRingtonePreference = (RingtonePreference) findPreference(mRingtonePreferenceKey);
|
||||
mVibratePreference = findPreference(
|
||||
getString(R.string.notification_vibration_pref_key));
|
||||
mSmsDisabledPrefKey = getString(R.string.sms_disabled_pref_key);
|
||||
mSmsDisabledPreference = findPreference(mSmsDisabledPrefKey);
|
||||
mSmsEnabledPrefKey = getString(R.string.sms_enabled_pref_key);
|
||||
mSmsEnabledPreference = findPreference(mSmsEnabledPrefKey);
|
||||
mIsSmsPreferenceClicked = false;
|
||||
|
||||
final SharedPreferences prefs = getPreferenceScreen().getSharedPreferences();
|
||||
updateSoundSummary(prefs);
|
||||
|
||||
if (!DebugUtils.isDebugEnabled()) {
|
||||
final Preference debugCategory = findPreference(getString(
|
||||
R.string.debug_pref_key));
|
||||
getPreferenceScreen().removePreference(debugCategory);
|
||||
}
|
||||
|
||||
final PreferenceScreen advancedScreen = (PreferenceScreen) findPreference(
|
||||
getString(R.string.advanced_pref_key));
|
||||
final boolean topLevel = getActivity().getIntent().getBooleanExtra(
|
||||
UIIntents.UI_INTENT_EXTRA_TOP_LEVEL_SETTINGS, false);
|
||||
if (topLevel) {
|
||||
advancedScreen.setIntent(UIIntents.get()
|
||||
.getAdvancedSettingsIntent(getPreferenceScreen().getContext()));
|
||||
} else {
|
||||
// Hide the Advanced settings screen if this is not top-level; these are shown at
|
||||
// the parent SettingsActivity.
|
||||
getPreferenceScreen().removePreference(advancedScreen);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick (PreferenceScreen preferenceScreen,
|
||||
Preference preference) {
|
||||
if (preference.getKey() == mSmsDisabledPrefKey ||
|
||||
preference.getKey() == mSmsEnabledPrefKey) {
|
||||
mIsSmsPreferenceClicked = true;
|
||||
}
|
||||
return super.onPreferenceTreeClick(preferenceScreen, preference);
|
||||
}
|
||||
|
||||
private void updateSoundSummary(final SharedPreferences sharedPreferences) {
|
||||
// The silent ringtone just returns an empty string
|
||||
String ringtoneName = mRingtonePreference.getContext().getString(
|
||||
R.string.silent_ringtone);
|
||||
|
||||
String ringtoneString = sharedPreferences.getString(mRingtonePreferenceKey, null);
|
||||
|
||||
// Bootstrap the default setting in the preferences so that we have a valid selection
|
||||
// in the dialog the first time that the user opens it.
|
||||
if (ringtoneString == null) {
|
||||
ringtoneString = Settings.System.DEFAULT_NOTIFICATION_URI.toString();
|
||||
final SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putString(mRingtonePreferenceKey, ringtoneString);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(ringtoneString)) {
|
||||
final Uri ringtoneUri = Uri.parse(ringtoneString);
|
||||
final Ringtone tone = RingtoneManager.getRingtone(mRingtonePreference.getContext(),
|
||||
ringtoneUri);
|
||||
|
||||
if (tone != null) {
|
||||
ringtoneName = tone.getTitle(mRingtonePreference.getContext());
|
||||
}
|
||||
}
|
||||
|
||||
mRingtonePreference.setSummary(ringtoneName);
|
||||
}
|
||||
|
||||
private void updateSmsEnabledPreferences() {
|
||||
if (!OsUtil.isAtLeastKLP()) {
|
||||
getPreferenceScreen().removePreference(mSmsDisabledPreference);
|
||||
getPreferenceScreen().removePreference(mSmsEnabledPreference);
|
||||
} else {
|
||||
final String defaultSmsAppLabel = getString(R.string.default_sms_app,
|
||||
PhoneUtils.getDefault().getDefaultSmsAppLabel());
|
||||
boolean isSmsEnabledBeforeState;
|
||||
boolean isSmsEnabledCurrentState;
|
||||
if (PhoneUtils.getDefault().isDefaultSmsApp()) {
|
||||
if (getPreferenceScreen().findPreference(mSmsEnabledPrefKey) == null) {
|
||||
getPreferenceScreen().addPreference(mSmsEnabledPreference);
|
||||
isSmsEnabledBeforeState = false;
|
||||
} else {
|
||||
isSmsEnabledBeforeState = true;
|
||||
}
|
||||
isSmsEnabledCurrentState = true;
|
||||
getPreferenceScreen().removePreference(mSmsDisabledPreference);
|
||||
mSmsEnabledPreference.setSummary(defaultSmsAppLabel);
|
||||
} else {
|
||||
if (getPreferenceScreen().findPreference(mSmsDisabledPrefKey) == null) {
|
||||
getPreferenceScreen().addPreference(mSmsDisabledPreference);
|
||||
isSmsEnabledBeforeState = true;
|
||||
} else {
|
||||
isSmsEnabledBeforeState = false;
|
||||
}
|
||||
isSmsEnabledCurrentState = false;
|
||||
getPreferenceScreen().removePreference(mSmsEnabledPreference);
|
||||
mSmsDisabledPreference.setSummary(defaultSmsAppLabel);
|
||||
}
|
||||
updateNotificationsPreferences();
|
||||
}
|
||||
mIsSmsPreferenceClicked = false;
|
||||
}
|
||||
|
||||
private void updateNotificationsPreferences() {
|
||||
final boolean canNotify = !OsUtil.isAtLeastKLP()
|
||||
|| PhoneUtils.getDefault().isDefaultSmsApp();
|
||||
mNotificationsEnabledPreference.setEnabled(canNotify);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
// We do this on start rather than on resume because the sound picker is in a
|
||||
// separate activity.
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
updateSmsEnabledPreferences();
|
||||
updateNotificationsPreferences();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences,
|
||||
final String key) {
|
||||
if (key.equals(mNotificationsEnabledPreferenceKey)) {
|
||||
updateNotificationsPreferences();
|
||||
} else if (key.equals(mRingtonePreferenceKey)) {
|
||||
updateSoundSummary(sharedPreferences);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.messaging.ui.appsettings;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.RadioButton;
|
||||
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.util.Assert;
|
||||
import com.android.messaging.util.BuglePrefs;
|
||||
|
||||
/**
|
||||
* Displays an on/off switch for group MMS setting for a given subscription.
|
||||
*/
|
||||
public class GroupMmsSettingDialog {
|
||||
private final Context mContext;
|
||||
private final int mSubId;
|
||||
private AlertDialog mDialog;
|
||||
|
||||
/**
|
||||
* Shows a new group MMS setting dialog.
|
||||
*/
|
||||
public static void showDialog(final Context context, final int subId) {
|
||||
new GroupMmsSettingDialog(context, subId).show();
|
||||
}
|
||||
|
||||
private GroupMmsSettingDialog(final Context context, final int subId) {
|
||||
mContext = context;
|
||||
mSubId = subId;
|
||||
}
|
||||
|
||||
private void show() {
|
||||
Assert.isNull(mDialog);
|
||||
mDialog = new AlertDialog.Builder(mContext)
|
||||
.setView(createView())
|
||||
.setTitle(R.string.group_mms_pref_title)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
private void changeGroupMmsSettings(final boolean enable) {
|
||||
Assert.notNull(mDialog);
|
||||
BuglePrefs.getSubscriptionPrefs(mSubId).putBoolean(
|
||||
mContext.getString(R.string.group_mms_pref_key), enable);
|
||||
mDialog.dismiss();
|
||||
}
|
||||
|
||||
private View createView() {
|
||||
final LayoutInflater inflater = (LayoutInflater) mContext
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
final View rootView = inflater.inflate(R.layout.group_mms_setting_dialog, null, false);
|
||||
final RadioButton disableButton = (RadioButton)
|
||||
rootView.findViewById(R.id.disable_group_mms_button);
|
||||
final RadioButton enableButton = (RadioButton)
|
||||
rootView.findViewById(R.id.enable_group_mms_button);
|
||||
disableButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
changeGroupMmsSettings(false);
|
||||
}
|
||||
});
|
||||
enableButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
changeGroupMmsSettings(true);
|
||||
}
|
||||
});
|
||||
final boolean mmsEnabled = BuglePrefs.getSubscriptionPrefs(mSubId).getBoolean(
|
||||
mContext.getString(R.string.group_mms_pref_key),
|
||||
mContext.getResources().getBoolean(R.bool.group_mms_pref_default));
|
||||
enableButton.setChecked(mmsEnabled);
|
||||
disableButton.setChecked(!mmsEnabled);
|
||||
return rootView;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.messaging.ui.appsettings;
|
||||
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceClickListener;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.text.TextUtils;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.android.messaging.Factory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.ParticipantRefresh;
|
||||
import com.android.messaging.datamodel.data.ParticipantData;
|
||||
import com.android.messaging.sms.ApnDatabase;
|
||||
import com.android.messaging.sms.MmsConfig;
|
||||
import com.android.messaging.sms.MmsUtils;
|
||||
import com.android.messaging.ui.BugleActionBarActivity;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
import com.android.messaging.util.Assert;
|
||||
import com.android.messaging.util.BuglePrefs;
|
||||
import com.android.messaging.util.LogUtil;
|
||||
import com.android.messaging.util.PhoneUtils;
|
||||
|
||||
public class PerSubscriptionSettingsActivity extends BugleActionBarActivity {
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
final String title = getIntent().getStringExtra(
|
||||
UIIntents.UI_INTENT_EXTRA_PER_SUBSCRIPTION_SETTING_TITLE);
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
getSupportActionBar().setTitle(title);
|
||||
} else {
|
||||
// This will fall back to the default title, i.e. "Messaging settings," so No-op.
|
||||
}
|
||||
|
||||
final FragmentTransaction ft = getFragmentManager().beginTransaction();
|
||||
final PerSubscriptionSettingsFragment fragment = new PerSubscriptionSettingsFragment();
|
||||
ft.replace(android.R.id.content, fragment);
|
||||
ft.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
NavUtils.navigateUpFromSameTask(this);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
public static class PerSubscriptionSettingsFragment extends PreferenceFragment
|
||||
implements OnSharedPreferenceChangeListener {
|
||||
private PhoneNumberPreference mPhoneNumberPreference;
|
||||
private Preference mGroupMmsPreference;
|
||||
private String mGroupMmsPrefKey;
|
||||
private String mPhoneNumberKey;
|
||||
private int mSubId;
|
||||
|
||||
public PerSubscriptionSettingsFragment() {
|
||||
// Required empty constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Get sub id from launch intent
|
||||
final Intent intent = getActivity().getIntent();
|
||||
Assert.notNull(intent);
|
||||
mSubId = (intent != null) ? intent.getIntExtra(UIIntents.UI_INTENT_EXTRA_SUB_ID,
|
||||
ParticipantData.DEFAULT_SELF_SUB_ID) : ParticipantData.DEFAULT_SELF_SUB_ID;
|
||||
|
||||
final BuglePrefs subPrefs = Factory.get().getSubscriptionPrefs(mSubId);
|
||||
getPreferenceManager().setSharedPreferencesName(subPrefs.getSharedPreferencesName());
|
||||
addPreferencesFromResource(R.xml.preferences_per_subscription);
|
||||
|
||||
mPhoneNumberKey = getString(R.string.mms_phone_number_pref_key);
|
||||
mPhoneNumberPreference = (PhoneNumberPreference) findPreference(mPhoneNumberKey);
|
||||
final PreferenceCategory advancedCategory = (PreferenceCategory)
|
||||
findPreference(getString(R.string.advanced_category_pref_key));
|
||||
final PreferenceCategory mmsCategory = (PreferenceCategory)
|
||||
findPreference(getString(R.string.mms_messaging_category_pref_key));
|
||||
|
||||
mPhoneNumberPreference.setDefaultPhoneNumber(
|
||||
PhoneUtils.get(mSubId).getCanonicalForSelf(false/*allowOverride*/), mSubId);
|
||||
|
||||
mGroupMmsPrefKey = getString(R.string.group_mms_pref_key);
|
||||
mGroupMmsPreference = findPreference(mGroupMmsPrefKey);
|
||||
if (!MmsConfig.get(mSubId).getGroupMmsEnabled()) {
|
||||
// Always show group messaging setting even if the SIM has no number
|
||||
// If broadcast sms is selected, the SIM number is not needed
|
||||
// If group mms is selected, the phone number dialog will popup when message
|
||||
// is being sent, making sure we will have a self number for group mms.
|
||||
mmsCategory.removePreference(mGroupMmsPreference);
|
||||
} else {
|
||||
mGroupMmsPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference pref) {
|
||||
GroupMmsSettingDialog.showDialog(getActivity(), mSubId);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
updateGroupMmsPrefSummary();
|
||||
}
|
||||
|
||||
if (!MmsConfig.get(mSubId).getSMSDeliveryReportsEnabled()) {
|
||||
final Preference deliveryReportsPref = findPreference(
|
||||
getString(R.string.delivery_reports_pref_key));
|
||||
mmsCategory.removePreference(deliveryReportsPref);
|
||||
}
|
||||
final Preference wirelessAlertPref = findPreference(getString(
|
||||
R.string.wireless_alerts_key));
|
||||
if (!isCellBroadcastAppLinkEnabled()) {
|
||||
advancedCategory.removePreference(wirelessAlertPref);
|
||||
} else {
|
||||
wirelessAlertPref.setOnPreferenceClickListener(
|
||||
new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(final Preference preference) {
|
||||
try {
|
||||
startActivity(UIIntents.get().getWirelessAlertsIntent());
|
||||
} catch (final ActivityNotFoundException e) {
|
||||
// Handle so we shouldn't crash if the wireless alerts
|
||||
// implementation is broken.
|
||||
LogUtil.e(LogUtil.BUGLE_TAG,
|
||||
"Failed to launch wireless alerts activity", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Access Point Names (APNs)
|
||||
final Preference apnsPref = findPreference(getString(R.string.sms_apns_key));
|
||||
|
||||
if (MmsUtils.useSystemApnTable() && !ApnDatabase.doesDatabaseExist()) {
|
||||
// Don't remove the ability to edit the local APN prefs if this device lets us
|
||||
// access the system APN, but we can't find the MCC/MNC in the APN table and we
|
||||
// created the local APN table in case the MCC/MNC was in there. In other words,
|
||||
// if the local APN table exists, let the user edit it.
|
||||
advancedCategory.removePreference(apnsPref);
|
||||
} else {
|
||||
final PreferenceScreen apnsScreen = (PreferenceScreen) findPreference(
|
||||
getString(R.string.sms_apns_key));
|
||||
apnsScreen.setIntent(UIIntents.get()
|
||||
.getApnSettingsIntent(getPreferenceScreen().getContext(), mSubId));
|
||||
}
|
||||
|
||||
// We want to disable preferences if we are not the default app, but we do all of the
|
||||
// above first so that the user sees the correct information on the screen
|
||||
if (!PhoneUtils.getDefault().isDefaultSmsApp()) {
|
||||
mGroupMmsPreference.setEnabled(false);
|
||||
final Preference autoRetrieveMmsPreference =
|
||||
findPreference(getString(R.string.auto_retrieve_mms_pref_key));
|
||||
autoRetrieveMmsPreference.setEnabled(false);
|
||||
final Preference deliveryReportsPreference =
|
||||
findPreference(getString(R.string.delivery_reports_pref_key));
|
||||
deliveryReportsPreference.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isCellBroadcastAppLinkEnabled() {
|
||||
if (!MmsConfig.get(mSubId).getShowCellBroadcast()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
final PackageManager pm = getActivity().getPackageManager();
|
||||
return pm.getApplicationEnabledSetting(UIIntents.CMAS_COMPONENT)
|
||||
!= PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
// CMAS app not installed.
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updateGroupMmsPrefSummary() {
|
||||
final boolean groupMmsEnabled = getPreferenceScreen().getSharedPreferences().getBoolean(
|
||||
mGroupMmsPrefKey, getResources().getBoolean(R.bool.group_mms_pref_default));
|
||||
mGroupMmsPreference.setSummary(groupMmsEnabled ?
|
||||
R.string.enable_group_mms : R.string.disable_group_mms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences,
|
||||
final String key) {
|
||||
if (key.equals(mGroupMmsPrefKey)) {
|
||||
updateGroupMmsPrefSummary();
|
||||
} else if (key.equals(mPhoneNumberKey)) {
|
||||
// Save the changed phone number in preferences specific to the sub id
|
||||
final String newPhoneNumber = mPhoneNumberPreference.getText();
|
||||
final BuglePrefs subPrefs = BuglePrefs.getSubscriptionPrefs(mSubId);
|
||||
if (TextUtils.isEmpty(newPhoneNumber)) {
|
||||
subPrefs.remove(mPhoneNumberKey);
|
||||
} else {
|
||||
subPrefs.putString(getString(R.string.mms_phone_number_pref_key),
|
||||
newPhoneNumber);
|
||||
}
|
||||
// Update the self participants so the new phone number will be reflected
|
||||
// everywhere in the UI.
|
||||
ParticipantRefresh.refreshSelfParticipants();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
getPreferenceScreen().getSharedPreferences()
|
||||
.unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.messaging.ui.appsettings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.support.v4.text.BidiFormatter;
|
||||
import android.support.v4.text.TextDirectionHeuristicsCompat;
|
||||
import android.text.InputType;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.util.PhoneUtils;
|
||||
|
||||
/**
|
||||
* Preference that displays a phone number and allows editing via a dialog.
|
||||
* <p>
|
||||
* A default number can be assigned, which is shown in the preference view and
|
||||
* used to populate the dialog editor when the preference value is not set. If
|
||||
* the user sets the preference to a number equivalent to the default, the
|
||||
* underlying preference is cleared.
|
||||
*/
|
||||
public class PhoneNumberPreference extends EditTextPreference {
|
||||
|
||||
private String mDefaultPhoneNumber;
|
||||
private int mSubId;
|
||||
|
||||
public PhoneNumberPreference(final Context context, final AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mDefaultPhoneNumber = "";
|
||||
}
|
||||
|
||||
public void setDefaultPhoneNumber(final String phoneNumber, final int subscriptionId) {
|
||||
mDefaultPhoneNumber = phoneNumber;
|
||||
mSubId = subscriptionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindView(final View view) {
|
||||
// Show the preference value if it's set, or the default number if not.
|
||||
// If we don't have a default, fall back to a static string (e.g. Unknown).
|
||||
String value = getText();
|
||||
if (TextUtils.isEmpty(value)) {
|
||||
value = mDefaultPhoneNumber;
|
||||
}
|
||||
final String displayValue = (!TextUtils.isEmpty(value))
|
||||
? PhoneUtils.get(mSubId).formatForDisplay(value)
|
||||
: getContext().getString(R.string.unknown_phone_number_pref_display_value);
|
||||
final BidiFormatter bidiFormatter = BidiFormatter.getInstance();
|
||||
final String phoneNumber = bidiFormatter.unicodeWrap
|
||||
(displayValue, TextDirectionHeuristicsCompat.LTR);
|
||||
// Set the value as the summary and let the superclass populate the views
|
||||
setSummary(phoneNumber);
|
||||
super.onBindView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindDialogView(final View view) {
|
||||
super.onBindDialogView(view);
|
||||
|
||||
final String value = getText();
|
||||
|
||||
// If the preference is empty, populate the EditText with the default number instead.
|
||||
if (TextUtils.isEmpty(value) && !TextUtils.isEmpty(mDefaultPhoneNumber)) {
|
||||
final BidiFormatter bidiFormatter = BidiFormatter.getInstance();
|
||||
final String phoneNumber = bidiFormatter.unicodeWrap
|
||||
(PhoneUtils.get(mSubId).getCanonicalBySystemLocale(mDefaultPhoneNumber),
|
||||
TextDirectionHeuristicsCompat.LTR);
|
||||
getEditText().setText(phoneNumber);
|
||||
}
|
||||
getEditText().setInputType(InputType.TYPE_CLASS_PHONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDialogClosed(final boolean positiveResult) {
|
||||
if (positiveResult && mDefaultPhoneNumber != null) {
|
||||
final String value = getEditText().getText().toString();
|
||||
final PhoneUtils phoneUtils = PhoneUtils.get(mSubId);
|
||||
final String phoneNumber = phoneUtils.getCanonicalBySystemLocale(value);
|
||||
final String defaultPhoneNumber = phoneUtils.getCanonicalBySystemLocale(
|
||||
mDefaultPhoneNumber);
|
||||
|
||||
// If the new value is the default, clear the preference.
|
||||
if (phoneNumber.equals(defaultPhoneNumber)) {
|
||||
setText("");
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.onDialogClosed(positiveResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(final String text) {
|
||||
super.setText(text);
|
||||
|
||||
// EditTextPreference doesn't show the value on the preference view, but we do.
|
||||
// We thus need to force a rebind of the view when a new value is set.
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.messaging.ui.appsettings;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.DataModel;
|
||||
import com.android.messaging.datamodel.binding.Binding;
|
||||
import com.android.messaging.datamodel.binding.BindingBase;
|
||||
import com.android.messaging.datamodel.data.SettingsData;
|
||||
import com.android.messaging.datamodel.data.SettingsData.SettingsDataListener;
|
||||
import com.android.messaging.datamodel.data.SettingsData.SettingsItem;
|
||||
import com.android.messaging.ui.BugleActionBarActivity;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
import com.android.messaging.util.Assert;
|
||||
import com.android.messaging.util.PhoneUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Shows the "master" settings activity that contains two parts, one for application-wide settings
|
||||
* (dubbed "General settings"), and one or more for per-subscription settings (dubbed "Messaging
|
||||
* settings" for single-SIM, and the actual SIM name for multi-SIM). Clicking on either item
|
||||
* (e.g. "General settings") will open the detail settings activity (ApplicationSettingsActivity
|
||||
* in this case).
|
||||
*/
|
||||
public class SettingsActivity extends BugleActionBarActivity {
|
||||
@Override
|
||||
protected void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
// Directly open the detailed settings page as the top-level settings activity if this is
|
||||
// not a multi-SIM device.
|
||||
if (PhoneUtils.getDefault().getActiveSubscriptionCount() <= 1) {
|
||||
UIIntents.get().launchApplicationSettingsActivity(this, true /* topLevel */);
|
||||
finish();
|
||||
} else {
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(android.R.id.content, new SettingsFragment())
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(final MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
NavUtils.navigateUpFromSameTask(this);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
public static class SettingsFragment extends Fragment implements SettingsDataListener {
|
||||
private ListView mListView;
|
||||
private SettingsListAdapter mAdapter;
|
||||
private final Binding<SettingsData> mBinding = BindingBase.createBinding(this);
|
||||
|
||||
@Override
|
||||
public void onCreate(final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mBinding.bind(DataModel.get().createSettingsData(getActivity(), this));
|
||||
mBinding.getData().init(getLoaderManager(), mBinding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
|
||||
final Bundle savedInstanceState) {
|
||||
final View view = inflater.inflate(R.layout.settings_fragment, container, false);
|
||||
mListView = (ListView) view.findViewById(android.R.id.list);
|
||||
mAdapter = new SettingsListAdapter(getActivity());
|
||||
mListView.setAdapter(mAdapter);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mBinding.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelfParticipantDataLoaded(SettingsData data) {
|
||||
mBinding.ensureBound(data);
|
||||
mAdapter.setSettingsItems(data.getSettingsItems());
|
||||
}
|
||||
|
||||
/**
|
||||
* An adapter that displays a list of SettingsItem.
|
||||
*/
|
||||
private class SettingsListAdapter extends ArrayAdapter<SettingsItem> {
|
||||
public SettingsListAdapter(final Context context) {
|
||||
super(context, R.layout.settings_item_view, new ArrayList<SettingsItem>());
|
||||
}
|
||||
|
||||
public void setSettingsItems(final List<SettingsItem> newList) {
|
||||
clear();
|
||||
addAll(newList);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, final View convertView,
|
||||
final ViewGroup parent) {
|
||||
View itemView;
|
||||
if (convertView != null) {
|
||||
itemView = convertView;
|
||||
} else {
|
||||
final LayoutInflater inflater = (LayoutInflater) getContext()
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
itemView = inflater.inflate(
|
||||
R.layout.settings_item_view, parent, false);
|
||||
}
|
||||
final SettingsItem item = getItem(position);
|
||||
final TextView titleTextView = (TextView) itemView.findViewById(R.id.title);
|
||||
final TextView subtitleTextView = (TextView) itemView.findViewById(R.id.subtitle);
|
||||
final String summaryText = item.getDisplayDetail();
|
||||
titleTextView.setText(item.getDisplayName());
|
||||
if (!TextUtils.isEmpty(summaryText)) {
|
||||
subtitleTextView.setText(summaryText);
|
||||
subtitleTextView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
subtitleTextView.setVisibility(View.GONE);
|
||||
}
|
||||
itemView.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (item.getType()) {
|
||||
case SettingsItem.TYPE_GENERAL_SETTINGS:
|
||||
UIIntents.get().launchApplicationSettingsActivity(getActivity(),
|
||||
false /* topLevel */);
|
||||
break;
|
||||
|
||||
case SettingsItem.TYPE_PER_SUBSCRIPTION_SETTINGS:
|
||||
UIIntents.get().launchPerSubscriptionSettingsActivity(getActivity(),
|
||||
item.getSubId(), item.getActivityTitle());
|
||||
break;
|
||||
|
||||
default:
|
||||
Assert.fail("unrecognized setting type!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
return itemView;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user