设置源码解析--Uim/Sim卡锁定
2014-01-22 20:54
295 查看
转载请注明出处:http://blog.csdn.net/droyon/article/details/18669917
功能入口:android手机--〉设置--〉安全--〉设置SIM卡锁定。
主页面如下所示:
一、操作说明:
1、点击锁定sim卡,会弹出Dialog,让用户输入pin码,点击确定会通过Ril到达moderm,进而将卡锁定。在重新开机/飞行模式等初始化卡时,需要输入正确的pin码才能使用与卡
相关的操作。如果想取消pin卡锁定,则反勾选checkBox,输入正确的pin码即可。如下图所示:
2、如果pin码设定成功,那么可以通过第二个选项进行pin码的更改。更改pin码需要经过,输入旧pin码,输入新pin码,再次输入新pin码等步骤。如下图:
功能点解析:
1、pin码操作需要设定的状态。
OFF_MODE状态代表关闭状态,也是无操作状态。
ICC_LOCK_MODE:进行pin码设定与解锁的状态。
ICC_OLD_MODE:更改pin码,输入旧pin码的状态。
ICC_NEW_MODE:更改pin码,输入新pin码的状态。
ICC_REENTER_MODE:更改pni码,再次输入pin码的状态。
2、全局的dialog只有一个。
在onResume方法中会执行如下代码:
第一次进入此界面,mDialogState为OFF_MODE,故而,程序会执行resetDialogState方法:
重置Dialog状态。Dialog的状态包括,Dialog的title,以及message。
也就是说当我们什么都不做时,默认的title和message为mDialogState == ICC_OLD_MODE的状态。
3、piin码设定与解锁回掉处理逻辑:
这是一个运行在主线程的Handler,主要处理三类message。这三类message的what分别为:MSG_ENABLE_ICC_PIN_COMPLETE,MSG_CHANGE_ICC_PIN_COMPLETE,MSG_SIM_STATE_CANGED。
MSG_ENABLE_ICC_PIN_COMPLETE:开启/关闭 sim锁定
如果sucess为true,则说明成功的进行了锁定sim卡或者解锁sim卡。更新mPinToggle的check状态。如果为false,说明操作失败,给出toast提示。
success 为true的条件为:ar.exception == null。
MSG_CHANGE_IC_PIN_COMPLETE:更改pin码的message。
同样的,success为true的条件和上一步雷同。无论成功还是失败,给出提示,并且resetDialogState();
4、pin码条件:
也就是说pin码是大于4个字符,小于8个字符。
5、得到当前pin是否锁定的状态。
6、pin状态更迭
当我们输入的过程中,进行mDialogState状态的切换,并且执行showDialog()。
7、锁定sim的pin码。
初始化一个Message,然后执行mPhone.getIccCard().setIccLockEnabled,然后将Message传递下去。这个方法会一直执行到Ril,然后到达moderm,处理完毕会执行Message回调。关于此回调Message的处理,我们在上面的Handler中已经说过了。
8、更改sim的pin码。
同理。
主要说明就到这里,下面附 源码:
IccLockSettings.java
功能入口:android手机--〉设置--〉安全--〉设置SIM卡锁定。
主页面如下所示:
一、操作说明:
1、点击锁定sim卡,会弹出Dialog,让用户输入pin码,点击确定会通过Ril到达moderm,进而将卡锁定。在重新开机/飞行模式等初始化卡时,需要输入正确的pin码才能使用与卡
相关的操作。如果想取消pin卡锁定,则反勾选checkBox,输入正确的pin码即可。如下图所示:
2、如果pin码设定成功,那么可以通过第二个选项进行pin码的更改。更改pin码需要经过,输入旧pin码,输入新pin码,再次输入新pin码等步骤。如下图:
功能点解析:
1、pin码操作需要设定的状态。
private static final int OFF_MODE = 0; // State when enabling/disabling ICC lock private static final int ICC_LOCK_MODE = 1; // State when entering the old pin private static final int ICC_OLD_MODE = 2; // State when entering the new pin - first time private static final int ICC_NEW_MODE = 3; // State when entering the new pin - second time private static final int ICC_REENTER_MODE = 4;
OFF_MODE状态代表关闭状态,也是无操作状态。
ICC_LOCK_MODE:进行pin码设定与解锁的状态。
ICC_OLD_MODE:更改pin码,输入旧pin码的状态。
ICC_NEW_MODE:更改pin码,输入新pin码的状态。
ICC_REENTER_MODE:更改pni码,再次输入pin码的状态。
2、全局的dialog只有一个。
在onResume方法中会执行如下代码:
protected void onResume() { super.onResume(); // ACTION_SIM_STATE_CHANGED is sticky, so we'll receive current state after this call, // which will call updatePreferences(). final IntentFilter filter = new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED); registerReceiver(mSimStateReceiver, filter); if (mDialogState != OFF_MODE) { showPinDialog(); } else { // Prep for standard click on "Change PIN" resetDialogState(); } }
第一次进入此界面,mDialogState为OFF_MODE,故而,程序会执行resetDialogState方法:
private void resetDialogState() { mError = null; mDialogState = ICC_OLD_MODE; // Default for when Change PIN is clicked mPin = ""; setDialogValues(); mDialogState = OFF_MODE; }
重置Dialog状态。Dialog的状态包括,Dialog的title,以及message。
private void setDialogValues() { mPinDialog.setText(mPin); String message = ""; switch (mDialogState) { case ICC_LOCK_MODE: message = mRes.getString(R.string.sim_enter_pin); mPinDialog.setDialogTitle(mToState ? mRes.getString(R.string.sim_enable_sim_lock) : mRes.getString(R.string.sim_disable_sim_lock)); break; case ICC_OLD_MODE: message = mRes.getString(R.string.sim_enter_old); mPinDialog.setDialogTitle(mRes.getString(R.string.sim_change_pin)); break; case ICC_NEW_MODE: message = mRes.getString(R.string.sim_enter_new); mPinDialog.setDialogTitle(mRes.getString(R.string.sim_change_pin)); break; case ICC_REENTER_MODE: message = mRes.getString(R.string.sim_reenter_new); mPinDialog.setDialogTitle(mRes.getString(R.string.sim_change_pin)); break; } if (mError != null) { message = mError + "\n" + message; mError = null; } mPinDialog.setDialogMessage(message); }
也就是说当我们什么都不做时,默认的title和message为mDialogState == ICC_OLD_MODE的状态。
3、piin码设定与解锁回掉处理逻辑:
private Handler mHandler = new Handler() { public void handleMessage(Message msg) { AsyncResult ar = (AsyncResult) msg.obj; switch (msg.what) { case MSG_ENABLE_ICC_PIN_COMPLETE: iccLockChanged(ar.exception == null); break; case MSG_CHANGE_ICC_PIN_COMPLETE: iccPinChanged(ar.exception == null); break; case MSG_SIM_STATE_CHANGED: updatePreferences(); break; } return; } };
这是一个运行在主线程的Handler,主要处理三类message。这三类message的what分别为:MSG_ENABLE_ICC_PIN_COMPLETE,MSG_CHANGE_ICC_PIN_COMPLETE,MSG_SIM_STATE_CANGED。
MSG_ENABLE_ICC_PIN_COMPLETE:开启/关闭 sim锁定
private void iccLockChanged(boolean success) { if (success) { mPinToggle.setChecked(mToState); } else { Toast.makeText(this, mRes.getString(R.string.sim_lock_failed), Toast.LENGTH_SHORT) .show(); } resetDialogState(); }
如果sucess为true,则说明成功的进行了锁定sim卡或者解锁sim卡。更新mPinToggle的check状态。如果为false,说明操作失败,给出toast提示。
success 为true的条件为:ar.exception == null。
MSG_CHANGE_IC_PIN_COMPLETE:更改pin码的message。
private void iccPinChanged(boolean success) { if (!success) { Toast.makeText(this, mRes.getString(R.string.sim_change_failed), Toast.LENGTH_SHORT) .show(); } else { Toast.makeText(this, mRes.getString(R.string.sim_change_succeeded), Toast.LENGTH_SHORT) .show(); } resetDialogState(); }
同样的,success为true的条件和上一步雷同。无论成功还是失败,给出提示,并且resetDialogState();
4、pin码条件:
private boolean reasonablePin(String pin) { if (pin == null || pin.length() < MIN_PIN_LENGTH || pin.length() > MAX_PIN_LENGTH) { return false; } else { return true; } }
private static final int MIN_PIN_LENGTH = 4; private static final int MAX_PIN_LENGTH = 8;
也就是说pin码是大于4个字符,小于8个字符。
5、得到当前pin是否锁定的状态。
mPhone.getIccCard().getIccLockEnabled()
6、pin状态更迭
public void onPinEntered(EditPinPreference preference, boolean positiveResult) { if (!positiveResult) { resetDialogState(); return; } mPin = preference.getText(); if (!reasonablePin(mPin)) { // inject error message and display dialog again mError = mRes.getString(R.string.sim_bad_pin); showPinDialog(); return; } switch (mDialogState) { case ICC_LOCK_MODE: tryChangeIccLockState(); break; case ICC_OLD_MODE: mOldPin = mPin; mDialogState = ICC_NEW_MODE; mError = null; mPin = null; showPinDialog(); break; case ICC_NEW_MODE: mNewPin = mPin; mDialogState = ICC_REENTER_MODE; mPin = null; showPinDialog(); break; case ICC_REENTER_MODE: if (!mPin.equals(mNewPin)) { mError = mRes.getString(R.string.sim_pins_dont_match); mDialogState = ICC_NEW_MODE; mPin = null; showPinDialog(); } else { mError = null; tryChangePin(); } break; } }
当我们输入的过程中,进行mDialogState状态的切换,并且执行showDialog()。
7、锁定sim的pin码。
private void tryChangeIccLockState() { // Try to change icc lock. If it succeeds, toggle the lock state and // reset dialog state. Else inject error message and show dialog again. Message callback = Message.obtain(mHandler, MSG_ENABLE_ICC_PIN_COMPLETE); mPhone.getIccCard().setIccLockEnabled(mToState, mPin, callback); }
初始化一个Message,然后执行mPhone.getIccCard().setIccLockEnabled,然后将Message传递下去。这个方法会一直执行到Ril,然后到达moderm,处理完毕会执行Message回调。关于此回调Message的处理,我们在上面的Handler中已经说过了。
8、更改sim的pin码。
private void tryChangePin() { Message callback = Message.obtain(mHandler, MSG_CHANGE_ICC_PIN_COMPLETE); mPhone.getIccCard().changeIccLockPassword(mOldPin, mNewPin, callback); }
同理。
主要说明就到这里,下面附 源码:
IccLockSettings.java
/*
* Copyright (C) 2008 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.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.os.AsyncResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.widget.Toast;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.TelephonyIntents;
/**
* Implements the preference screen to enable/disable ICC lock and
* also the dialogs to change the ICC PIN. In the former case, enabling/disabling
* the ICC lock will prompt the user for the current PIN.
* In the Change PIN case, it prompts the user for old pin, new pin and new pin
* again before attempting to change it. Calls the SimCard interface to execute
* these operations.
*
*/
public class IccLockSettings extends PreferenceActivity
implements EditPinPreference.OnPinEnteredListener {
private static final int OFF_MODE = 0; // State when enabling/disabling ICC lock private static final int ICC_LOCK_MODE = 1; // State when entering the old pin private static final int ICC_OLD_MODE = 2; // State when entering the new pin - first time private static final int ICC_NEW_MODE = 3; // State when entering the new pin - second time private static final int ICC_REENTER_MODE = 4;
// Keys in xml file
private static final String PIN_DIALOG = "sim_pin";
private static final String PIN_TOGGLE = "sim_toggle";
// Keys in icicle
private static final String DIALOG_STATE = "dialogState";
private static final String DIALOG_PIN = "dialogPin";
private static final String DIALOG_ERROR = "dialogError";
private static final String ENABLE_TO_STATE = "enableState";
// Save and restore inputted PIN code when configuration changed
// (ex. portrait<-->landscape) during change PIN code
private static final String OLD_PINCODE = "oldPinCode";
private static final String NEW_PINCODE = "newPinCode";
private static final int MIN_PIN_LENGTH = 4; private static final int MAX_PIN_LENGTH = 8;
// Which dialog to show next when popped up
private int mDialogState = OFF_MODE;
private String mPin;
private String mOldPin;
private String mNewPin;
private String mError;
// Are we trying to enable or disable ICC lock?
private boolean mToState;
private Phone mPhone;
private EditPinPreference mPinDialog;
private CheckBoxPreference mPinToggle;
private Resources mRes;
// For async handler to identify request type
private static final int MSG_ENABLE_ICC_PIN_COMPLETE = 100;
private static final int MSG_CHANGE_ICC_PIN_COMPLETE = 101;
private static final int MSG_SIM_STATE_CHANGED = 102;
// For replies from IccCard interface
private Handler mHandler = new Handler() { public void handleMessage(Message msg) { AsyncResult ar = (AsyncResult) msg.obj; switch (msg.what) { case MSG_ENABLE_ICC_PIN_COMPLETE: iccLockChanged(ar.exception == null); break; case MSG_CHANGE_ICC_PIN_COMPLETE: iccPinChanged(ar.exception == null); break; case MSG_SIM_STATE_CHANGED: updatePreferences(); break; } return; } };
private final BroadcastReceiver mSimStateReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_SIM_STATE_CHANGED));
}
}
};
// For top-level settings screen to query
static boolean isIccLockEnabled() {
return PhoneFactory.getDefaultPhone().getIccCard().getIccLockEnabled();
}
static String getSummary(Context context) {
Resources res = context.getResources();
String summary = isIccLockEnabled()
? res.getString(R.string.sim_lock_on)
: res.getString(R.string.sim_lock_off);
return summary;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Utils.isMonkeyRunning()) {
finish();
return;
}
addPreferencesFromResource(R.xml.sim_lock_settings);
mPinDialog = (EditPinPreference) findPreference(PIN_DIALOG);
mPinToggle = (CheckBoxPreference) findPreference(PIN_TOGGLE);
if (savedInstanceState != null && savedInstanceState.containsKey(DIALOG_STATE)) {
mDialogState = savedInstanceState.getInt(DIALOG_STATE);
mPin = savedInstanceState.getString(DIALOG_PIN);
mError = savedInstanceState.getString(DIALOG_ERROR);
mToState = savedInstanceState.getBoolean(ENABLE_TO_STATE);
// Restore inputted PIN code
switch (mDialogState) {
case ICC_NEW_MODE:
mOldPin = savedInstanceState.getString(OLD_PINCODE);
break;
case ICC_REENTER_MODE:
mOldPin = savedInstanceState.getString(OLD_PINCODE);
mNewPin = savedInstanceState.getString(NEW_PINCODE);
break;
case ICC_LOCK_MODE:
case ICC_OLD_MODE:
default:
break;
}
}
mPinDialog.setOnPinEnteredListener(this);
// Don't need any changes to be remembered
getPreferenceScreen().setPersistent(false);
mPhone = PhoneFactory.getDefaultPhone();
mRes = getResources();
updatePreferences();
}
private void updatePreferences() {
mPinToggle.setChecked(mPhone.getIccCard().getIccLockEnabled());
}
@Override
protected void onResume() { super.onResume(); // ACTION_SIM_STATE_CHANGED is sticky, so we'll receive current state after this call, // which will call updatePreferences(). final IntentFilter filter = new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED); registerReceiver(mSimStateReceiver, filter); if (mDialogState != OFF_MODE) { showPinDialog(); } else { // Prep for standard click on "Change PIN" resetDialogState(); } }
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mSimStateReceiver);
}
@Override
protected void onSaveInstanceState(Bundle out) {
// Need to store this state for slider open/close
// There is one case where the dialog is popped up by the preference
// framework. In that case, let the preference framework store the
// dialog state. In other cases, where this activity manually launches
// the dialog, store the state of the dialog.
if (mPinDialog.isDialogOpen()) {
out.putInt(DIALOG_STATE, mDialogState);
out.putString(DIALOG_PIN, mPinDialog.getEditText().getText().toString());
out.putString(DIALOG_ERROR, mError);
out.putBoolean(ENABLE_TO_STATE, mToState);
// Save inputted PIN code
switch (mDialogState) {
case ICC_NEW_MODE:
out.putString(OLD_PINCODE, mOldPin);
break;
case ICC_REENTER_MODE:
out.putString(OLD_PINCODE, mOldPin);
out.putString(NEW_PINCODE, mNewPin);
break;
case ICC_LOCK_MODE:
case ICC_OLD_MODE:
default:
break;
}
} else {
super.onSaveInstanceState(out);
}
}
private void showPinDialog() {
if (mDialogState == OFF_MODE) {
return;
}
setDialogValues();
mPinDialog.showPinDialog();
}
private void setDialogValues() { mPinDialog.setText(mPin); String message = ""; switch (mDialogState) { case ICC_LOCK_MODE: message = mRes.getString(R.string.sim_enter_pin); mPinDialog.setDialogTitle(mToState ? mRes.getString(R.string.sim_enable_sim_lock) : mRes.getString(R.string.sim_disable_sim_lock)); break; case ICC_OLD_MODE: message = mRes.getString(R.string.sim_enter_old); mPinDialog.setDialogTitle(mRes.getString(R.string.sim_change_pin)); break; case ICC_NEW_MODE: message = mRes.getString(R.string.sim_enter_new); mPinDialog.setDialogTitle(mRes.getString(R.string.sim_change_pin)); break; case ICC_REENTER_MODE: message = mRes.getString(R.string.sim_reenter_new); mPinDialog.setDialogTitle(mRes.getString(R.string.sim_change_pin)); break; } if (mError != null) { message = mError + "\n" + message; mError = null; } mPinDialog.setDialogMessage(message); }
public void onPinEntered(EditPinPreference preference, boolean positiveResult) { if (!positiveResult) { resetDialogState(); return; } mPin = preference.getText(); if (!reasonablePin(mPin)) { // inject error message and display dialog again mError = mRes.getString(R.string.sim_bad_pin); showPinDialog(); return; } switch (mDialogState) { case ICC_LOCK_MODE: tryChangeIccLockState(); break; case ICC_OLD_MODE: mOldPin = mPin; mDialogState = ICC_NEW_MODE; mError = null; mPin = null; showPinDialog(); break; case ICC_NEW_MODE: mNewPin = mPin; mDialogState = ICC_REENTER_MODE; mPin = null; showPinDialog(); break; case ICC_REENTER_MODE: if (!mPin.equals(mNewPin)) { mError = mRes.getString(R.string.sim_pins_dont_match); mDialogState = ICC_NEW_MODE; mPin = null; showPinDialog(); } else { mError = null; tryChangePin(); } break; } }
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
if (preference == mPinToggle) {
// Get the new, preferred state
mToState = mPinToggle.isChecked();
// Flip it back and pop up pin dialog
mPinToggle.setChecked(!mToState);
mDialogState = ICC_LOCK_MODE;
showPinDialog();
} else if (preference == mPinDialog) {
mDialogState = ICC_OLD_MODE;
return false;
}
return true;
}
private void tryChangeIccLockState() { // Try to change icc lock. If it succeeds, toggle the lock state and // reset dialog state. Else inject error message and show dialog again. Message callback = Message.obtain(mHandler, MSG_ENABLE_ICC_PIN_COMPLETE); mPhone.getIccCard().setIccLockEnabled(mToState, mPin, callback); }
private void iccLockChanged(boolean success) { if (success) { mPinToggle.setChecked(mToState); } else { Toast.makeText(this, mRes.getString(R.string.sim_lock_failed), Toast.LENGTH_SHORT) .show(); } resetDialogState(); }
private void iccPinChanged(boolean success) {
if (!success) {
Toast.makeText(this, mRes.getString(R.string.sim_change_failed),
Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(this, mRes.getString(R.string.sim_change_succeeded),
Toast.LENGTH_SHORT)
.show();
}
resetDialogState();
}
private void tryChangePin() { Message callback = Message.obtain(mHandler, MSG_CHANGE_ICC_PIN_COMPLETE); mPhone.getIccCard().changeIccLockPassword(mOldPin, mNewPin, callback); }
private boolean reasonablePin(String pin) { if (pin == null || pin.length() < MIN_PIN_LENGTH || pin.length() > MAX_PIN_LENGTH) { return false; } else { return true; } }
private void resetDialogState() { mError = null; mDialogState = ICC_OLD_MODE; // Default for when Change PIN is clicked mPin = ""; setDialogValues(); mDialogState = OFF_MODE; }
}
相关文章推荐
- android Launcher源码解析07:Workspace 02——设置壁纸
- Android恢复出厂设置流程分析【Android源码解析十】
- spring默认启动位置以及contextConfigLocation设置源码解析
- spring默认启动位置以及contextConfigLocation设置源码解析
- Android恢复出厂设置流程分析【Android源码解析十】
- Mybatis3源码分析(15)-Sql解析执行-Statement初始化和参数设置
- Mybatis源码解析 —— 动态设置参数机制
- Android恢复出厂设置流程分析【Android源码解析十】
- 设置ZooKeeper服务器地址列表源码解析及扩展
- spring默认启动位置以及contextConfigLocation设置源码解析
- android输入法02:openwnn源码解析04—设置界面
- spring默认启动位置以及contextConfigLocation设置源码解析
- Android恢复出厂设置流程分析【Android源码解析十】
- Android恢复出厂设置流程分析【Android源码解析十】
- Android恢复出厂设置流程分析【Android源码解析十】
- Heritrix 3.1.0 源码解析(十)
- VMWare网络拓扑解析和网络设置方法
- caffe之python接口实战 :00-classification 官方教程源码解析
- 谷歌Cartographer学习(2)-原理阐述与源码解析
- SpringMVC源码解析-LocaleResolver