设置源码解析--Uim/Sim卡锁定

来源:互联网 发布:网络粑粑什么意思 编辑:程序博客网 时间:2024/05/16 10:57

 转载请注明出处: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码操作需要设定的状态。

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;    }}

 

1 0
原创粉丝点击