简书链接:荣耀84g选择了3g卡导致默认数据重启后自动跟随bug研究分析以及编写xposed修复bug
文章字数:2051,阅读全文大约需要8分钟
反馈过荣耀官方很多次,这次打电话说确实有bug,说已经更新了,等更新,我特么等了快1个月了。。于是无奈自己分析了.

我其实也是比较懒的,但是现在的情况是红米note4x压根不能让我的联通3g卡用于接听,让另外一张卡用于上网,荣耀也有bug,但是至少可以让我得另外一张上网的4g卡可以上网,只是关机自动还原,扣费扣得非常惨,因为这个问题搞的我欠费很多次了,这方便比如小米了,小米是设置没毛病,就是没信号。

首先我的荣耀8root了,所以找起来比较简单
apk是双卡管理_com.huawei.android.dsdscardmanager_3.0.5.14_build3050.apk
根据文件字符串和选择框特征定位到class HWCardManagerPrefsFragment

1
2
3
4
5
6
7
8
9
10
11
12

private void initPreferences() {
addPreferencesResource();
PreferenceScreen screen = getPreferenceScreen();
this.mDataEnablePreference = (SwitchPreference) screen.findPreference("data_enabled");
this.mDataEnablePreference.setOnPreferenceChangeListener(this);
screen.removePreference(this.mDataEnablePreference);
this.mDefault4GSlotPreference = (CardSelectPreference) screen.findPreference("switch_dual_card_slots");
if (Constants.IS_4G_DATA_BIND) {
this.mDefault4GSlotPreference.setTitle(R.string.default_data_network_emui);
} else {
this

如何定位的呢,

1
2
3
4
5
6
7
8
9
10
11
12
ing name="card2_manual_select_network_telecomiot">卡槽二手动选网</string>
<string name="card1_manual_select_network_telecomiot">卡槽一手动选网</string>
<string name="switch_dual_card_slots_emui">4G/3G 卡槽选择</string>
<string name="switch_dual_card_slots_emui">电信4G/3G卡槽</string>
<string name="set_sdcs_failed_emui">4G/3G 卡槽切换失败</string>
<string name="set_sdcs_failed_emui">电信4G/3G卡槽设置失败</string>
<string name="switch_dual_card_slots_summary_emui">此卡槽支持更多频段及更好的网络信号</string>
<string name="dualcard_switch_alert_title_emui">4G/3G 卡槽选择</string>
<string name="dualcard_switch_alert_title_emui">电信4G/3G卡槽选择</string>
<string name="sim_card_name">卡名称</string>
<string name="default_data_network_emui">默认移动数据</string>
<string name="deactivating_card_conform">此操作将导致%s 不可用,是否继续?</stri
1
2
3
4
5
6

![img](https://upload-images.jianshu.io/upload_images/2815884-ba25cfb909460674.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/500)

要做的是编写一个系统程序,开机后自动重新设置一遍,这样的话泄露的流量就不会太多了,之前是网上找过相关设置默认移动数据的教程,发现并不行,出现什么invvxxexception,应该是没找到class了。

整体源码如下

package com.huawei.android.dsdscardmanager.fragments;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemProperties;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceScreen;
import android.preference.SwitchPreference;
import android.provider.Settings.Global;
import android.text.TextUtils;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.huawei.android.dsdscardmanager.CallForwardingManagerActivity;
import com.huawei.android.dsdscardmanager.Constants;
import com.huawei.android.dsdscardmanager.HWCardManagerActivity;
import com.huawei.android.dsdscardmanager.HwCustCardManagerActivity;
import com.huawei.android.dsdscardmanager.HwLog;
import com.huawei.android.dsdscardmanager.HwVsimUtils;
import com.huawei.android.dsdscardmanager.ItemUseStat;
import com.huawei.android.dsdscardmanager.MLog;
import com.huawei.android.dsdscardmanager.R;
import com.huawei.android.dsdscardmanager.Utils;
import com.huawei.android.dsdscardmanager.model.Card;
import com.huawei.android.dsdscardmanager.model.CardManager;
import com.huawei.android.dsdscardmanager.utils.CallForwardingManager;
import com.huawei.android.dsdscardmanager.widget.CallForwardingPreference;
import com.huawei.android.dsdscardmanager.widget.CardSelectPreference;
import com.huawei.android.dsdscardmanager.widget.CardView;
import com.huawei.android.dsdscardmanager.widget.PreferenceCategoryug;
import com.huawei.android.dsdscardmanager.widget.TipToastManager;
import com.huawei.android.telephony.TelephonyManagerEx;

public class HWCardManagerPrefsFragment extends InstrumentedFragment implements OnPreferenceChangeListener, OnPreferenceClickListener {
private static final int CDMA_MODE = 0;
public static final boolean IS_FULL_NETWORK_SUPPORTED = SystemProperties.getBoolean(“ro.config.all_network_4Gswitch”, false);
private static final boolean NOT_INSERT_CARD_BOTH_2G_3G_4G = SystemProperties.getBoolean(“ro.config.hw_both_2g3g4g”, false);
private static final String PREF_KEY_CALL_FORWARDING_ENABLE = “call_forwarding_enable”;
private static final String PREF_KEY_CALL_FORWARDING_ENABLE_DIVIDER = “call_forwarding_enable_divider”;
private static final String PREF_KEY_CARD_AND_DATA_DIVIDER = “card_and_data_divider”;
private static final String PREF_KEY_DATA_ENABLED = “data_enabled”;
private static final String PREF_KEY_DEFAULT_CARD_MODE = “default_card_mode”;
private static final String PREF_KEY_DEFAULT_DATA_NETWORK = “default_data_network”;
private static final String PREF_KEY_DSDS_PREFERENCE_CATEGORY = “dsds_preference_category”;
private static final String PREF_KEY_SWITCH_DUAL_CARD_SLOTS = “switch_dual_card_slots”;
private static final String TAG = “HWCardManagerPrefsFragment”;
private HwCustCardManagerActivity hwCust;
private HWCardManagerActivity mActivity;
private CallForwardingPreference mCallForwardingEnablePreference;
private Preference mCardDataDividerPerence;
private CardManager mCardManager;
private CardView[] mCardViews = new CardView[]{new CardView(), new CardView()};
protected Card[] mCards = null;
private Context mContext;
private SwitchPreference mDataEnablePreference;
private Preference mDefCallPreference;
private CardSelectPreference mDefDataPreference;
private CardSelectPreference mDefault4GSlotPreference;
private RelativeLayout mGlobalInternetServiceDesRL;
private TextView mGlobalInternetServiceDesTV;
private LinearLayout mGlobalInternetServiceTitleLL;
private LayoutInflater mInflater = null;
private CardNameDialogFragment mRenameFragment;
private OnCheckedChangeListener onActivateViewClicked = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!Utils.isAirplaneModeOn(HWCardManagerPrefsFragment.this.mContext)) {
if (HWCardManagerPrefsFragment.this.checkSlotsChanging()) {
MLog.e(“HWCardManagerPrefsFragment”, “has slot is activiting…”);
return;
}
HWCardManagerPrefsFragment.this.hideToast();
for (int i = 0; i < 2; i++) {
if (buttonView == HWCardManagerPrefsFragment.this.mCardViews[i].mActivateCheckBox) {
HWCardManagerPrefsFragment.this.mActivity.tryActivatedCard(i, !HWCardManagerPrefsFragment.this.mCards[i].isActivated());
}
}
}
}
};
private OnClickListener onChangeOperatorViewClicked0 = new OnClickListener() {
public void onClick(View view) {
if (!Utils.isAirplaneModeOn(HWCardManagerPrefsFragment.this.mContext)) {
ItemUseStat.getInstance().handleClick(HWCardManagerPrefsFragment.this.mContext, 2, “dual_card_manager_card1”);
HWCardManagerPrefsFragment.this.hideToast();
HWCardManagerPrefsFragment.this.showEditorNameDialog(0);
}
}
};
private OnClickListener onChangeOperatorViewClicked1 = new OnClickListener() {
public void onClick(View view) {
if (!Utils.isAirplaneModeOn(HWCardManagerPrefsFragment.this.mContext)) {
ItemUseStat.getInstance().handleClick(HWCardManagerPrefsFragment.this.mContext, 2, “dual_card_manager_card2”);
HWCardManagerPrefsFragment.this.hideToast();
HWCardManagerPrefsFragment.this.showEditorNameDialog(1);
}
}
};
private OnClickListener onChangeTextViewClicked = new OnClickListener() {
public void onClick(View view) {
if (!Utils.isAirplaneModeOn(HWCardManagerPrefsFragment.this.mContext)) {
HwVsimUtils.startVsimActivity(HWCardManagerPrefsFragment.this.mContext);
}
}
};

public HWCardManagerPrefsFragment(HWCardManagerActivity activity, HwCustCardManagerActivity cust) {
    this.mActivity = activity;
    this.mContext = activity.getApplicationContext();
    this.mCardManager = activity.getCardManager();
    this.mCards = this.mCardManager.getCards();
    this.hwCust = cust;
}

public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    initHeaderView();
}

public void onCreate(Bundle arg0) {
    super.onCreate(arg0);
    initPreferences();
    initCustPreferences();
}

public View getView() {
    return super.getView();
}

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    return inflater.inflate(R.layout.dsdsframe_main_list, null);
}

private void initHeaderView() {
    if (this.mInflater == null) {
        this.mInflater = LayoutInflater.from(new ContextThemeWrapper(this.mContext, this.mContext.getResources().getIdentifier("androidhwext:style/Theme.Emui", null, null)));
    }
    View view = this.mInflater.inflate(R.layout.dsdsframe_header, null);
    initCardsView(view);
    initVsimPromptView(view);
    ListView list = getListView();
    if (list != null) {
        list.addHeaderView(view);
        list.setOnTouchListener(new OnTouchListener() {
            public boolean onTouch(View view, MotionEvent event) {
                if (event.getAction() == 0) {
                    HWCardManagerPrefsFragment.this.hideToast();
                }
                return false;
            }
        });
        list.setDivider(null);
    }
}

private void initVsimPromptView(View view) {
    if (HwVsimUtils.isSupportVsim(this.mContext) && view != null) {
        HwLog.d("HWCardManagerPrefsFragment", "initVsimPromptView...");
        this.mGlobalInternetServiceTitleLL = (LinearLayout) view.findViewById(R.id.globalInternetServiceTitleLL);
        this.mGlobalInternetServiceDesRL = (RelativeLayout) view.findViewById(R.id.globalInternetServiceDesRL);
        this.mGlobalInternetServiceDesRL.setOnClickListener(this.onChangeTextViewClicked);
        this.mGlobalInternetServiceDesTV = (TextView) view.findViewById(R.id.globalInternetServiceDesTV);
    }
}

private void initCardsView(View view) {
    if (view != null) {
        TextView card1_categary = (TextView) view.findViewById(R.id.card1_categary);
        TextView card1_label = (TextView) view.findViewById(R.id.card_label_1);
        String card1Text = String.format(getResources().getString(R.string.card_option_ex), new Object[]{Integer.valueOf(1)});
        card1_categary.setText(card1Text);
        card1_label.setText(card1Text);
        TextView card2_categary = (TextView) view.findViewById(R.id.card2_categary);
        TextView card2_label = (TextView) view.findViewById(R.id.card_label_2);
        String card2Text = String.format(getResources().getString(R.string.card_option_ex), new Object[]{Integer.valueOf(2)});
        card2_categary.setText(card2Text);
        card2_label.setText(card2Text);
        this.mCardViews = CardView.initCardViews(view);
        this.mCardViews[0].mImageViewCard.setImageResource(getCardShapRes(0));
        this.mCardViews[1].mImageViewCard.setImageResource(getCardShapRes(1));
        this.mCardViews[0].setOperatorNameOnClickListener(this.onChangeOperatorViewClicked0);
        this.mCardViews[1].setOperatorNameOnClickListener(this.onChangeOperatorViewClicked1);
    }
}

private boolean checkSlotsChanging() {
    for (int i = 0; i < 2; i++) {
        if (this.mCards[i].isActivateChanging()) {
            return true;
        }
    }
    return false;
}

private void showEditorNameDialog(int subscription) {
    if (this.mRenameFragment == null) {
        this.mRenameFragment = new CardNameDialogFragment();
    }
    this.mRenameFragment.show(getFragmentManager(), "rename", subscription);
}

private int getCardShapRes(int slotId) {
    boolean isLargerCard = false;
    MLog.i("HWCardManagerPrefsFragment", "slotId=" + slotId + " DualSimShapesType=" + this.mActivity.getDualSimShapesType());
    switch (this.mActivity.getDualSimShapesType()) {
        case 1:
            if (slotId != 0) {
                isLargerCard = false;
                break;
            }
            isLargerCard = true;
            break;
        case 2:
            if (slotId != 1) {
                isLargerCard = false;
                break;
            }
            isLargerCard = true;
            break;
    }
    if (isLargerCard) {
        if (this.mCards[slotId].isInserted()) {
            return R.drawable.micro_sim_card_normal;
        }
        return R.drawable.micro_sim_card_off;
    } else if (this.mCards[slotId].isInserted()) {
        return R.drawable.nano_sim_card_normal;
    } else {
        return R.drawable.nano_sim_card_off;
    }
}

private void addPreferencesResource() {
    if (this.hwCust == null || !Constants.IS_CF_OPTION_ON) {
        addPreferencesFromResource(R.xml.dsds_ug);
    } else {
        this.hwCust.addCustPreferencesFromResource();
    }
}

private void initPreferences() {
    addPreferencesResource();
    PreferenceScreen screen = getPreferenceScreen();
    this.mDataEnablePreference = (SwitchPreference) screen.findPreference("data_enabled");
    this.mDataEnablePreference.setOnPreferenceChangeListener(this);
    screen.removePreference(this.mDataEnablePreference);
    this.mDefault4GSlotPreference = (CardSelectPreference) screen.findPreference("switch_dual_card_slots");
    if (Constants.IS_4G_DATA_BIND) {
        this.mDefault4GSlotPreference.setTitle(R.string.default_data_network_emui);
    } else {
        this.mDefault4GSlotPreference.setTitle(Utils.check3GString(R.string.switch_dual_card_slots_emui));
    }
    this.mCardDataDividerPerence = screen.findPreference("card_and_data_divider");
    this.mDefault4GSlotPreference.setOnPreferenceChangeListener(this);
    if (!CardManager.isSupportedSetDefault4GSlotId()) {
        screen.removePreference(this.mDefault4GSlotPreference);
        if (this.mCardDataDividerPerence != null) {
            screen.removePreference(this.mCardDataDividerPerence);
        }
    }
    this.mDefDataPreference = (CardSelectPreference) screen.findPreference("default_data_network");
    this.mDefDataPreference.setOnPreferenceChangeListener(this);
    this.mDefCallPreference = screen.findPreference("default_card_mode");
    this.mDefCallPreference.setOnPreferenceClickListener(this);
    this.mCallForwardingEnablePreference = (CallForwardingPreference) screen.findPreference("call_forwarding_enable");
    if (this.mCallForwardingEnablePreference != null) {
        this.mCallForwardingEnablePreference.setOnPreferenceClickListener(this);
    }
    if (Constants.IS_4G_DATA_BIND) {
        screen.removePreference(this.mDefDataPreference);
        if (this.mCardDataDividerPerence != null) {
            screen.removePreference(this.mCardDataDividerPerence);
            return;
        }
        return;
    }
    PreferenceCategoryug preferenceCategory = (PreferenceCategoryug) screen.findPreference("dsds_preference_category");
    if (preferenceCategory != null) {
        Preference enableDivider = screen.findPreference("call_forwarding_enable_divider");
        if (enableDivider != null) {
            preferenceCategory.removePreference(enableDivider);
        }
        if (this.mCallForwardingEnablePreference != null) {
            preferenceCategory.removePreference(this.mCallForwardingEnablePreference);
        }
    }
}

private void initCustPreferences() {
    if (this.hwCust != null) {
        this.hwCust.initCustPreferences();
    }
}

public void onStart() {
    super.onStart();
}

public void onStop() {
    super.onStop();
}

public void onAttach(Activity activity) {
    super.onAttach(activity);
}

public void onDestroy() {
    super.onDestroy();
}

public void onPause() {
    super.onPause();
}

public void onResume() {
    super.onResume();
}

public void onTrimMemory(int level) {
    super.onTrimMemory(level);
}

public void updateView() {
    if (isAdded() && getActivity() != null) {
        updateCardsView();
        updatePreferences();
    }
}

private void updateCardsView() {
    if (this.mCardViews[0].mIsInitView) {
        boolean isSlot2Disabled = isSlot2Disabled();
        int i = 0;
        while (i < 2) {
            boolean activated;
            boolean activateSwitchChecked;
            boolean z;
            this.mCardViews[i].mImageViewCard.setImageResource(getCardShapRes(i));
            boolean inserted = this.mCards[i].isInserted();
            if (!this.mCards[i].isActivated() || this.mCards[i].isPinLocked()) {
                activated = false;
            } else {
                activated = !this.mCards[i].isPukLocked();
            }
            if (activated) {
                activateSwitchChecked = inserted;
            } else {
                activateSwitchChecked = false;
            }
            setActivateSwitchChecked(i, activateSwitchChecked);
            CardView cardView = this.mCardViews[i];
            if (!inserted || Utils.isAirplaneModeOn(this.mContext)) {
                z = false;
            } else {
                z = true;
            }
            cardView.setEnabled(z);
            if (1 == i && isSlot2Disabled) {
                setActivateSwitchChecked(i, false);
                this.mCardViews[i].setEnabled(false);
            }
            if (inserted) {
                this.mCardViews[i].setOperaterNameChangeEnabled(activated);
                if (activated) {
                    String iSimCardName = this.mActivity.getDataAccessor().getSimCardName(i);
                    HwLog.d("HWCardManagerPrefsFragment", "iSimCardName" + i + "=" + iSimCardName);
                    if (TextUtils.isEmpty(iSimCardName)) {
                        iSimCardName = this.mCards[i].getOperatorName();
                        HwLog.d("HWCardManagerPrefsFragment", "mOperatorName" + i + "=" + iSimCardName);
                    } else {
                        this.mCardViews[i].setTitle(iSimCardName);
                    }
                    this.mCardViews[i].setTitle(iSimCardName);
                } else {
                    this.mCardViews[i].setTitle((int) R.string.inactive);
                }
                String phoneNumber = CardManager.getPhoneNumber(i);
                if (TextUtils.isEmpty(phoneNumber)) {
                    this.mCardViews[i].setSummary("");
                } else {
                    this.mCardViews[i].setSummary(phoneNumber);
                }
                if (this.mCards[i].isPinLocked()) {
                    this.mCardViews[i].setSummary((int) R.string.pinlocked);
                } else if (this.mCards[i].isPukLocked()) {
                    this.mCardViews[i].setSummary((int) R.string.puklocked);
                }
            } else {
                this.mCardViews[i].setTitle((int) R.string.nocard);
                this.mCardViews[i].setSummary("");
                dismissDialogFragment();
            }
            this.mCardViews[i].hideSummaryIfEmpty();
            i++;
        }
        String card1Type = this.mContext.getString(Utils.check3GString(R.string.cardstatus1));
        if (this.hwCust != null) {
            card1Type = this.hwCust.updateTitleToLTE(card1Type);
        }
        String card2Type = getCustCardType(this.mContext.getString(R.string.cardstatus2));
        if (CardManager.getDefault4GSlotId() == 0) {
            this.mCardViews[0].mTypeStatusTextView.setText(card1Type);
            this.mCardViews[1].mTypeStatusTextView.setText(card2Type);
        } else if (1 == CardManager.getDefault4GSlotId()) {
            this.mCardViews[0].mTypeStatusTextView.setText(card2Type);
            this.mCardViews[1].mTypeStatusTextView.setText(card1Type);
        }
        updateVsimPromptView();
    }
}

private void setActivateSwitchChecked(int index, boolean checked) {
    if (!this.mCards[index].isActivateChanging()) {
        this.mCardViews[index].mActivateCheckBox.setOnCheckedChangeListener(null);
        this.mCardViews[index].mActivateCheckBox.setChecked(checked);
        this.mCardViews[index].mActivateCheckBox.setOnCheckedChangeListener(this.onActivateViewClicked);
    }
}

private void updateVsimPromptView() {
    if (HwVsimUtils.isSupportVsim(this.mContext)) {
        if (HwVsimUtils.isVsimOpen()) {
            boolean isInserted = this.mCards[0].isInserted() ? this.mCards[1].isInserted() : false;
            int vsimSlotId = HwVsimUtils.getVsimSlotId();
            HwLog.d("HWCardManagerPrefsFragment", "updateVsimPromptView isDualCardInserted=" + isInserted + ", vsimSlotId=" + vsimSlotId);
            if (isInserted && Constants.isValidSlotId(vsimSlotId)) {
                this.mCardViews[vsimSlotId].setEnabled(false);
                this.mCardViews[vsimSlotId].mImageViewCard.setImageResource(R.drawable.nano_sim_card_off);
            }
            if (HwVsimUtils.isSupportThreeModem() && isInserted && vsimSlotId == 2) {
                String card1Type = getResources().getString(R.string.cardstatus2);
                String card2Type = getCustCardType(getResources().getString(R.string.cardstatus2));
                if (CardManager.getDefault4GSlotId() == 0) {
                    this.mCardViews[0].mTypeStatusTextView.setText(card1Type);
                    this.mCardViews[1].mTypeStatusTextView.setText(card2Type);
                } else if (1 == CardManager.getDefault4GSlotId()) {
                    this.mCardViews[0].mTypeStatusTextView.setText(card2Type);
                    this.mCardViews[1].mTypeStatusTextView.setText(card1Type);
                }
            }
            this.mGlobalInternetServiceDesTV.setText(HwVsimUtils.getVsimSummary(this.mContext, this.mCards));
            this.mGlobalInternetServiceDesRL.setVisibility(0);
            this.mGlobalInternetServiceTitleLL.setVisibility(0);
        } else if (!(this.mGlobalInternetServiceDesRL == null || this.mGlobalInternetServiceTitleLL == null)) {
            this.mGlobalInternetServiceDesRL.setVisibility(8);
            this.mGlobalInternetServiceTitleLL.setVisibility(8);
        }
    }
}

private String getCustCardType(String cardType) {
    boolean notInserted = (this.mCards[0].isInserted() || this.mCards[1].isInserted()) ? false : true;
    if (TelephonyManagerEx.checkCdmaSlaveCardMode(0) || Constants.IS_VICE_WCDMA) {
        cardType = this.mContext.getString(R.string.cardtype);
    }
    if (NOT_INSERT_CARD_BOTH_2G_3G_4G && notInserted) {
        return this.mContext.getString(R.string.cardstatus1);
    }
    return cardType;
}

public boolean onPreferenceChange(Preference preference, Object newValue) {
    String key = preference.getKey();
    String value = String.valueOf(newValue);
    MLog.d("HWCardManagerPrefsFragment", "onPreferenceChange key = " + key + " value=" + value);
    int slotId;
    if ("default_data_network".equals(key)) {
        ItemUseStat.getInstance().handleClick(this.mContext, 2, key, value);
        slotId = CardSelectPreference.getSlotIdValueBy(value);
        this.mActivity.clearSwitchDataAfterSet4G();
        if (this.hwCust == null || !IS_FULL_NETWORK_SUPPORTED) {
            this.mActivity.startChangeDefaultDataCard(slotId);
        } else {
            this.hwCust.switchDefaultDataforAllNetwork(slotId);
        }
    } else if ("switch_dual_card_slots".equals(key)) {
        slotId = CardSelectPreference.getSlotIdValueBy(value);
        if (this.hwCust == null || !IS_FULL_NETWORK_SUPPORTED) {
            ItemUseStat.getInstance().handleClick(this.mContext, 2, "switch_sim_card_slots", slotId);
            this.mActivity.trySetDefault4GSlotId(slotId);
        } else {
            this.hwCust.switchDefault4GforAllNetwork(slotId);
        }
    } else if ("data_enabled".equals(key)) {
        this.mCardManager.setDataEnabled(Boolean.parseBoolean(value));
    }
    return true;
}

public boolean onPreferenceClick(Preference preference) {
    TipToastManager.getInstance().hide();
    if (preference == this.mDataEnablePreference) {
        boolean isSelected = this.mDataEnablePreference.isChecked();
        this.mCardManager.setDataEnabled(isSelected);
        this.mDataEnablePreference.setChecked(isSelected);
    } else if (preference == this.mDefCallPreference) {
        callCardSettings();
        ItemUseStat.getInstance().handleClick(this.mContext, 2, "default_card_mode");
    } else if (preference == this.mCallForwardingEnablePreference) {
        this.mActivity.startActivity(new Intent(this.mActivity, CallForwardingManagerActivity.class));
    }
    return true;
}

private void updatePreferences() {
    boolean z = true;
    if (this.mDefault4GSlotPreference != null) {
        boolean canChangePefCard = this.mCardManager.canChangePefCard() ? !Utils.isAirplaneModeOn(this.mContext) : false;
        CardSelectPreference cardSelectPreference;
        boolean z2;
        if (Constants.IS_4G_DATA_BIND) {
            cardSelectPreference = this.mDefault4GSlotPreference;
            if (Utils.isAirplaneModeOn(this.mContext)) {
                z2 = false;
            } else {
                z2 = CardManager.isSetDefault4GSlotIdEnabled();
            }
            cardSelectPreference.setEnabled(z2);
            if (HwVsimUtils.isVsimOpen(this.mContext)) {
                HwLog.d("HWCardManagerPrefsFragment", "updatePreferences Vsim opened, disabale 4GSlotPreference");
                this.mDefault4GSlotPreference.setEnabled(false);
            }
            this.mDefCallPreference.setEnabled(canChangePefCard);
            this.mDefCallPreference.setSummary(getDefCallSettingsStrId());
            if (this.mActivity.isUpdateDef4GSlotView) {
                this.mDefault4GSlotPreference.setValue(CardSelectPreference.getValueBySlotId(CardManager.getDefault4GSlotId()));
                this.mDefault4GSlotPreference.updateNetherSummaryTextView();
            } else {
                return;
            }
        }
        cardSelectPreference = this.mDefDataPreference;
        z2 = canChangePefCard && !CardManager.phoneIsOffhook(this.mContext);
        cardSelectPreference.setEnabled(z2);
        this.mDefCallPreference.setEnabled(canChangePefCard);
        cardSelectPreference = this.mDefault4GSlotPreference;
        if (Utils.isAirplaneModeOn(this.mContext)) {
            z2 = false;
        } else {
            z2 = CardManager.isSetDefault4GSlotIdEnabled();
        }
        cardSelectPreference.setEnabled(z2);
        if (!this.mActivity.isDataDailogWaiting().booleanValue()) {
            updateDefDataPrefercenceValue();
            updateDefault4GSlotPreference();
        }
        this.mDefCallPreference.setSummary(getDefCallSettingsStrId());
        if (this.hwCust != null) {
            this.hwCust.updateCustPreferences(this.mDefault4GSlotPreference);
        }
        if (HwVsimUtils.isSupportVsim(this.mContext) && HwVsimUtils.isVsimOpen()) {
            HwLog.d("HWCardManagerPrefsFragment", "updatePreferences Vsim opened, disabale 4GSlotPreference and DataPreference");
            this.mDefault4GSlotPreference.setEnabled(false);
            this.mDefDataPreference.setEnabled(false);
        }
        if (!(Constants.IS_4G_DATA_BIND || this.hwCust == null)) {
            this.hwCust.updatePreferenceTitleToLTE(this.mDefault4GSlotPreference);
        }
        boolean phoneIsOffhook = CardManager.phoneIsOffhook(this.mContext);
        if (!canChangePefCard || phoneIsOffhook) {
            z = false;
        }
        updateCallForwardingPreference(z);
        if (phoneIsOffhook) {
            this.mDefault4GSlotPreference.setEnabled(false);
        }
        boolean isSlot2Disable = isSlot2Disabled();
        if (isSlot2DataConnectivityDisabled() || isSlot2Disable) {
            if (this.mDefDataPreference != null) {
                this.mDefDataPreference.setEnabled(false);
            }
            this.mDefault4GSlotPreference.setEnabled(false);
        }
    }
}

public void updatePhoneStatePreferences(boolean enable) {
    if (isAdded() && getActivity() != null) {
        if (this.mDefault4GSlotPreference != null) {
            this.mDefault4GSlotPreference.setEnabled(enable);
        }
        if (this.mCallForwardingEnablePreference != null) {
            this.mCallForwardingEnablePreference.setEnabled(enable);
        }
    }
}

public String getDefCallSettingsStrId() {
    return getCallCardSettingsString(this.mContext, Global.getInt(this.mContext.getContentResolver(), "default_simcard_slotid", -1));
}

private void updateDefDataPrefercenceValue() {
    this.mDefDataPreference.setValue(CardSelectPreference.getValueBySlotId(this.mCardManager.getRealCardForMobileData()));
}

private void updateDefault4GSlotPreference() {
    this.mDefault4GSlotPreference.setValue(CardSelectPreference.getValueBySlotId(CardManager.getDefault4GSlotId()));
}

private void hideToast() {
    if (TipToastManager.getInstance().isShowing()) {
        TipToastManager.getInstance().hide();
    }
}

private void updateCallForwardingPreference(boolean enable) {
    boolean z = false;
    if (this.mCallForwardingEnablePreference != null) {
        CallForwardingPreference callForwardingPreference = this.mCallForwardingEnablePreference;
        if (enable && !hasCdmaCard()) {
            z = true;
        }
        callForwardingPreference.setEnabled(z);
        this.mCallForwardingEnablePreference.setNetherSummary((int) R.string.call_forward_summary);
        this.mCallForwardingEnablePreference.setSummary(CallForwardingManager.getCallForwardingModeValue(this.mContext, this.mCardManager));
    }
}

private boolean hasCdmaCard() {
    return !CardManager.isCdmaCard(0) ? CardManager.isCdmaCard(1) : true;
}

}

1
2

切换数据连接应该是
    this.mDataEnablePreference.setOnPreferenceChangeListener(this);
1
触发的代码

if (preference == this.mDataEnablePreference) {
boolean isSelected = this.mDataEnablePreference.isChecked();
this.mCardManager.setDataEnabled(isSelected);
this.mDataEnablePreference.setChecked(isSelected);
}

1
关闭数据连接的代码就得到了
public void setDataEnabled(boolean enabled) {
    try {
        ((TelephonyManager) this.mContext.getSystemService("phone")).setDataEnabled(enabled);
    } catch (NullPointerException e) {
        MLog.e("CardManager", "Phone module did not start!");
    }
}
1
2
但是这里似乎不对劲呀,我要的是切换的。
观看别人源码能学到很多东西啊,cardmanager的源码如下

package com.huawei.android.dsdscardmanager.model;

import android.content.Context;
import android.content.Intent;
import android.os.Message;
import android.os.SystemProperties;
import android.provider.Settings.Global;
import android.provider.Settings.SettingNotFoundException;
import android.telephony.HwTelephonyManager;
import android.telephony.MSimTelephonyManager;
import android.telephony.PhoneNumberUtils;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.internal.telephony.HwSubscriptionManager;
import com.android.internal.telephony.OperatorInfo;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import com.huawei.android.dsdscardmanager.Constants;
import com.huawei.android.dsdscardmanager.ItemUseStat;
import com.huawei.android.dsdscardmanager.MLog;
import com.huawei.telephony.HuaweiTelephonyManager;
import java.lang.reflect.InvocationTargetException;

public class CardManager {
public static final boolean BPROPERTY_MAX_SUPPORT_4G = isSupportedSet4G();
public static final int NETWORK_CLASS_3G = 2;
public static final int STATE_ACTIVATED = 1;
public static final int STATE_DEACTIVATED = 0;
private static final String TAG = “CardManager”;
private static final String USER_DATACALL_SUBSCRIPTION = “user_datacall_sub”;
private static final String USER_DEFAULT_SUBSCRIPTION = “user_default_sub”;
private Card[] cards = new Card[]{new Card(0), new Card(1)};
private int mCardCount = 0;
private Context mContext;

public CardManager(Context context) {
    this.mContext = context;
}

public static Phone getPhone(int slotId) {
    Phone phone = null;
    try {
        phone = PhoneFactory.getPhone(slotId);
    } catch (Exception e) {
        MLog.e("CardManager", "error!getphone exception!");
        e.printStackTrace();
    }
    return phone;
}

public static boolean isMultiSimEnabled() {
    try {
        return MSimTelephonyManager.getDefault().isMultiSimEnabled();
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

public static boolean isChinaTelecom() {
    if (SystemProperties.get("ro.config.hw_opta", "").equals("92")) {
        return SystemProperties.get("ro.config.hw_optb", "").equals("156");
    }
    return false;
}

public static int getSimState(int slotId) {
    return MSimTelephonyManager.getDefault().getSimState(slotId);
}

public static int getSlotId(long subId) {
    int slotId = SubscriptionManager.getSlotId((int) subId);
    if (Constants.isValidSlotId(slotId)) {
        return slotId;
    }
    MLog.e("CardManager", "getSlotId is invalid, we use the defualt slotid.slotId=" + slotId);
    return 0;
}

public static long getSubId(int slotId) {
    if (SubscriptionManager.getSubId(slotId) == null || SubscriptionManager.getSubId(slotId).length <= 0) {
        MLog.e("CardManager", "getSubId return null, we use the defualt subId 0");
        return 0;
    }
    MLog.i("CardManager", "getSubId(" + slotId + ") = " + SubscriptionManager.getSubId(slotId)[0]);
    return (long) SubscriptionManager.getSubId(slotId)[0];
}

public static boolean activateCard(int slotId, boolean activate, Message onCompleteMsg) {
    try {
        MLog.i("CardManager", "setSubscription card:slotId=" + slotId + " activate=" + activate);
        boolean rs = HwSubscriptionManager.getInstance().setSubscription(slotId, activate, onCompleteMsg);
        MLog.i("CardManager", "setSubscription res:" + rs);
        return rs;
    } catch (Exception e) {
        MLog.w("CardManager", "setSubscription card failed");
        e.printStackTrace();
        return false;
    }
}

public static boolean isCardActivate(int slotId) {
    return getCardActivateState(slotId) == 1;
}

public static int getCardActivateState(int slotId) {
    int state = 0;
    try {
        MLog.i("CardManager", "isCardActivate slotId=" + slotId + " subId:" + getSubId(slotId));
        state = HwTelephonyManager.getDefault().getSubState(getSubId(slotId));
    } catch (Exception e) {
        MLog.w("CardManager", "get card activated state failed!");
        e.printStackTrace();
    }
    MLog.i("CardManager", "isCardActivate slotId=" + slotId + " result=" + state);
    return state;
}

public static boolean isTelecomiot() {
    return SystemProperties.getBoolean("ro.config.dsds_telecomiot", false);
}

public static boolean isSupportedSetDefault4GSlotId() {
    return SystemProperties.getBoolean("persist.sys.dualcards", false);
}

public static boolean isSupportedSet4G() {
    return SystemProperties.getBoolean("ro.config.hw_lte_support", true);
}

public static boolean isSetDefault4GSlotIdEnabled() {
    try {
        boolean enabled = reflectIsSetDefault4GSlotIdEnabled();
        MLog.i("CardManager", "isSetDefault4GSlotIdEnabled enabled=" + enabled);
        return enabled;
    } catch (Exception e) {
        MLog.w("CardManager", "isSetDefault4GSlotIdEnabled card failed");
        e.printStackTrace();
        return false;
    }
}

private static boolean reflectIsSetDefault4GSlotIdEnabled() {
    try {
        return Boolean.parseBoolean(HuaweiTelephonyManager.class.getMethod("isSetDefault4GSlotIdEnabled", new Class[0]).invoke(HuaweiTelephonyManager.getDefault(), new Object[0]).toString());
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
        MLog.e("CardManager", "error!method isSetDefault4GSlotIdEnabled is not suppported!");
        return false;
    } catch (IllegalAccessException e2) {
        e2.printStackTrace();
        MLog.e("CardManager", "error!method isSetDefault4GSlotIdEnabled is not suppported!");
        return false;
    } catch (IllegalArgumentException e3) {
        e3.printStackTrace();
        MLog.e("CardManager", "error!method isSetDefault4GSlotIdEnabled is not suppported!");
        return false;
    } catch (InvocationTargetException e4) {
        e4.printStackTrace();
        MLog.e("CardManager", "error!method isSetDefault4GSlotIdEnabled is not suppported!");
        return false;
    }
}

public static void setDefault4GSlotId(int slotId, Message msg) {
    try {
        MLog.i("CardManager", "setDefault4GSlotId card:slotId=" + slotId);
        reflectSetDefault4GSlotId(slotId, msg);
    } catch (Exception e) {
        MLog.w("CardManager", "setDefault4GCard card failed");
        e.printStackTrace();
    }
}

private static void reflectSetDefault4GSlotId(int slotId, Message msg) {
    try {
        HuaweiTelephonyManager.class.getMethod("setDefault4GSlotId", new Class[]{Integer.TYPE, Message.class}).invoke(HuaweiTelephonyManager.getDefault(), new Object[]{Integer.valueOf(slotId), msg});
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
        MLog.e("CardManager", "error! method setDefault4GSlotId is not suppported!");
    } catch (IllegalAccessException e2) {
        e2.printStackTrace();
        MLog.e("CardManager", "error! method setDefault4GSlotId is not suppported!");
    } catch (IllegalArgumentException e3) {
        e3.printStackTrace();
        MLog.e("CardManager", "error! method setDefault4GSlotId is not suppported!");
    } catch (InvocationTargetException e4) {
        e4.printStackTrace();
        MLog.e("CardManager", "error! method setDefault4GSlotId is not suppported!");
    }
}

public static boolean isCdmaCard(int slotId) {
    Phone phone = getPhone(slotId);
    if (phone != null) {
        return 2 == phone.getPhoneType();
    } else {
        return false;
    }
}

public static int getDefault4GSlotId() {
    try {
        MLog.i("CardManager", "getDefault4GSlotId");
        int slotId = reflectGetDefault4GSlotId();
        MLog.i("CardManager", "getDefault4GSlotId rs=" + slotId);
        if (Constants.isValidSlotId(slotId)) {
            return slotId;
        }
    } catch (Exception e) {
        MLog.w("CardManager", "getDefault4GSlotId card failed");
        e.printStackTrace();
    }
    return 0;
}

private static int reflectGetDefault4GSlotId() {
    try {
        return Integer.parseInt(HuaweiTelephonyManager.class.getMethod("getDefault4GSlotId", new Class[0]).invoke(HuaweiTelephonyManager.getDefault(), new Object[0]).toString());
    } catch (NumberFormatException e) {
        e.printStackTrace();
        MLog.e("CardManager", "error!method getDefault4GSlotId is not suppported!");
        return 0;
    } catch (NoSuchMethodException e2) {
        e2.printStackTrace();
        MLog.e("CardManager", "error!method getDefault4GSlotId is not suppported!");
        return 0;
    } catch (IllegalAccessException e3) {
        e3.printStackTrace();
        MLog.e("CardManager", "error!method getDefault4GSlotId is not suppported!");
        return 0;
    } catch (IllegalArgumentException e4) {
        e4.printStackTrace();
        MLog.e("CardManager", "error!method getDefault4GSlotId is not suppported!");
        return 0;
    } catch (InvocationTargetException e5) {
        e5.printStackTrace();
        MLog.e("CardManager", "error!method getDefault4GSlotId is not suppported!");
        return 0;
    }
}

public static void setPrefCardForMobileData(int slotId) {
    try {
        MLog.i("CardManager", "card setPrefCardForMobileData:" + slotId);
        HwSubscriptionManager.getInstance().setUserPrefDataSlotId(slotId);
    } catch (Exception e) {
        MLog.w("CardManager", "set default card for mobile data failed!");
        e.printStackTrace();
    }
}

public int getPreCardForMobileData() {
    try {
        int slotId = Global.getInt(this.mContext.getContentResolver(), "user_datacall_sub", 0);
        MLog.i("CardManager", "getPreCardForMobileData:" + slotId);
        if (Constants.isValidSlotId(slotId)) {
            return slotId;
        }
        return 0;
    } catch (Exception e) {
        MLog.w("CardManager", "get default card for mobile data failed!");
        e.printStackTrace();
    }
}

public int getRealCardForMobileData() {
    int slotId = readSlotId("multi_sim_data_call");
    MLog.i("CardManager", "real def data:" + slotId);
    if (Constants.isValidSlotId(slotId)) {
        return slotId;
    }
    return 0;
}

public static void setPrefCardForCallSms(int slotId) {
    try {
        MLog.i("CardManager", "card setPrefCardForCallSms:" + slotId);
        HwSubscriptionManager.getInstance().setUserPrefDefaultSlotId(slotId);
    } catch (Exception e) {
        MLog.w("CardManager", "set default card for call and sms failed!");
        e.printStackTrace();
    }
}

public int getPrefCardForCallSms() {
    try {
        int slotId = Global.getInt(this.mContext.getContentResolver(), "user_default_sub", 0);
        MLog.i("CardManager", "getPreCardForMobileData:" + slotId);
        if (Constants.isValidSlotId(slotId)) {
            return slotId;
        }
        return 0;
    } catch (Exception e) {
        MLog.w("CardManager", "get default card for mobile data failed!");
        e.printStackTrace();
    }
}

public int getRealCardForCallSms() {
    int slotId = readSlotId("multi_sim_sms");
    MLog.i("CardManager", "real def SMS:" + slotId);
    if (Constants.isValidSlotId(slotId)) {
        return slotId;
    }
    slotId = readSlotId("multi_sim_voice_call");
    MLog.i("CardManager", "real def voice:" + slotId);
    if (Constants.isValidSlotId(slotId)) {
        return slotId;
    }
    return 0;
}

private int readSlotId(String name) {
    long subId;
    try {
        subId = (long) Global.getInt(this.mContext.getContentResolver(), name);
    } catch (SettingNotFoundException e) {
        MLog.e("CardManager", "Settings Exception reading values of " + name);
        subId = 0;
    }
    return getSlotId(subId);
}

public static String getPhoneNumber(int slotId) {
    Phone phone = null;
    try {
        phone = PhoneFactory.getPhone(slotId);
    } catch (Exception ex) {
        MLog.w("CardManager", "get Phone exception for sub:" + slotId);
        ex.printStackTrace();
    }
    if (phone != null) {
        String rawNumber = phone.getLine1Number();
        if (!TextUtils.isEmpty(rawNumber)) {
            return PhoneNumberUtils.formatNumber(rawNumber);
        }
    }
    MLog.w("CardManager", "phone number is empty");
    return null;
}

public static String getPhoneNumber(Phone phone) {
    if (phone != null) {
        return phone.getLine1Number();
    }
    MLog.w("CardManager", "phone number is empty");
    return null;
}

public boolean canChangePefCard() {
    int i = 0;
    while (i < 2) {
        if (!this.cards[i].isActivated() || getSimState(i) != 5) {
            return false;
        }
        i++;
    }
    return true;
}

public void resumeCardsStates() {
    int mCount = 0;
    for (int i = 0; i < 2; i++) {
        boolean z;
        int state = getSimState(i);
        Card card = this.cards[i];
        if (state == 1) {
            z = true;
        } else {
            z = false;
        }
        card.setAbsent(z);
        MLog.i("CardManager", "slotId=" + i + " simstate=" + state);
        this.cards[i].setInserted(false);
        this.cards[i].setCardIOError(false);
        this.cards[i].setPinLocked(false);
        this.cards[i].setPukLocked(false);
        this.cards[i].setReady(false);
        switch (state) {
            case 0:
            case 6:
                this.cards[i].setInserted(true);
                break;
            case 2:
            case 4:
                this.cards[i].setInserted(true);
                this.cards[i].setPinLocked(true);
                break;
            case 3:
                this.cards[i].setInserted(true);
                this.cards[i].setPukLocked(true);
                break;
            case 5:
                this.cards[i].setInserted(true);
                this.cards[i].setReady(true);
                break;
        }
        if (8 == state) {
            this.cards[i].setInserted(true);
            this.cards[i].setCardIOError(true);
        }
        if (this.cards[i].isInserted()) {
            mCount++;
        }
    }
    if (this.mCardCount != mCount) {
        ItemUseStat.getInstance().handleClick(this.mContext, 2, "card_count", mCount);
        this.mCardCount = mCount;
    }
    if (!this.cards[0].isInserted() && !this.cards[1].isInserted() && isSetDefault4GSlotIdEnabled()) {
        this.cards[0].setInserted(true);
        this.cards[1].setInserted(true);
    }
}

public Card[] getCards() {
    resumeCardsActivatedState();
    return this.cards;
}

public void resumeCardsActivatedState() {
    for (int i = 0; i < 2; i++) {
        if (!this.cards[i].isActivateChanging()) {
            this.cards[i].setActivated(isCardActivate(i));
        }
    }
}

public void onCardsActivateStarted(int slotId, boolean activated) {
    this.cards[slotId].setActivateChanging(true);
}

public void onCardsActivateCompleted(int slotId) {
    this.cards[slotId].setActivateChanging(false);
    this.cards[slotId].setActivated(isCardActivate(slotId));
}

public void setDataEnabled(boolean enabled) {
    try {
        ((TelephonyManager) this.mContext.getSystemService("phone")).setDataEnabled(enabled);
    } catch (NullPointerException e) {
        MLog.e("CardManager", "Phone module did not start!");
    }
}

public boolean getDataEnabled() {
    try {
        return ((TelephonyManager) this.mContext.getSystemService("phone")).getDataEnabled();
    } catch (NullPointerException e) {
        MLog.e("CardManager", "Phone module did not start!");
        return false;
    }
}

public static boolean isCTCdmaCardInGsmMode() {
    try {
        return Boolean.parseBoolean(String.valueOf(HuaweiTelephonyManager.class.getMethod("isCTCdmaCardInGsmMode", new Class[0]).invoke(HuaweiTelephonyManager.getDefault(), new Object[0])));
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
        MLog.e("CardManager", "error! method isCTCdmaCardInGsmMode is not suppported!");
        return false;
    } catch (IllegalAccessException e2) {
        e2.printStackTrace();
        MLog.e("CardManager", "error! method isCTCdmaCardInGsmMode is not suppported!");
        return false;
    } catch (IllegalArgumentException e3) {
        e3.printStackTrace();
        MLog.e("CardManager", "error! method isCTCdmaCardInGsmMode is not suppported!");
        return false;
    } catch (InvocationTargetException e4) {
        e4.printStackTrace();
        MLog.e("CardManager", "error! method isCTCdmaCardInGsmMode is not suppported!");
        return false;
    }
}

public static boolean isCountryAccessTest() {
    return SystemProperties.getBoolean("ro.config.dsds_telecomcta", false);
}

public static boolean isChangeDefaultLTE() {
    return SystemProperties.getBoolean("ro.config.change_default_LTE", true);
}

public static String getRadioTech(OperatorInfo operatorInfo) {
    if (operatorInfo == null) {
        return "";
    }
    try {
        Object obj = OperatorInfo.class.getMethod("getRadioTech", new Class[0]).invoke(operatorInfo, new Object[0]);
        if (!"".equals(String.valueOf(obj))) {
            return "+" + String.valueOf(obj);
        }
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e2) {
        e2.printStackTrace();
    } catch (IllegalArgumentException e3) {
        e3.printStackTrace();
    } catch (InvocationTargetException e4) {
        e4.printStackTrace();
    }
    MLog.w("CardManager", "error! method operatorInfo.getRadioTech() is not suppported!");
    return "";
}

public static void launcherHome(Context context) {
    Intent home = new Intent("android.intent.action.MAIN", null);
    home.addCategory("android.intent.category.HOME");
    home.addFlags(270565376);
    try {
        context.startActivity(home);
    } catch (Exception e) {
        MLog.e("CardManager", "start home error because of " + e.getMessage());
    }
}

public static boolean phoneIsOffhook(Context context) {
    if (isMultiSimEnabled()) {
        for (int i = 0; i < 2; i++) {
            int callState = MSimTelephonyManager.from(context).getCallState(i);
            if (callState == 2 || callState == 1) {
                MLog.i("CardManager", "Dual card and one is in calling.");
                return true;
            }
        }
    }
    return false;
}

}

1
2

这里

public void callCardSettings() {
ArrayList callCardSettingsList = new ArrayList(3);
callCardSettingsList.add(getCallCardSettingsItem(-1));
callCardSettingsList.add(getCallCardSettingsItem(0));
callCardSettingsList.add(getCallCardSettingsItem(1));
CallCardSettingsDialogFragment.show(getFragmentManager(), callCardSettingsList);
}

1
2
3
应该对应的是默认拨号卡 不设置,卡1 ,卡2 ,之类的。

切换4g卡槽的时候有一个重要提示是否同时将默认移动数据切换到卡2,搜索之后得到如下代码
private void confirmSwitchDefaultData(final int slotId) {
    if (!isFinishing()) {
        this.mNeedSwitchDataAfterSetDefault4G = false;
        new Builder(this).setTitle(R.string.sync_switch_default_data_title).setMessage(getString(R.string.sync_switch_default_data_content, new Object[]{getCardLabel(slotId)})).setOnCancelListener(new OnCancelListener() {
            public void onCancel(DialogInterface dialog) {
                ItemUseStat.getInstance().handleClick(AbstractCardManagerDrawer.this.getBaseContext(), 2, "cancel_switch_sync_data", slotId);
                AbstractCardManagerDrawer.this.startSetDefault4GSlotId(slotId);
                MLog.w("CardMgrAbs", "oncancel start set default 4G");
            }
        }).setPositiveButton(R.string.doswitch, new OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                ItemUseStat.getInstance().handleClick(AbstractCardManagerDrawer.this.getBaseContext(), 2, "switch_sync_data", slotId);
                AbstractCardManagerDrawer.this.mNeedSwitchDataAfterSetDefault4G = true;
                AbstractCardManagerDrawer.this.startSetDefault4GSlotId(slotId);
                MLog.d("CardMgrAbs", "on positive click start set default 4G");
            }
        }).setNegativeButton(R.string.noswitch, new OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                ItemUseStat.getInstance().handleClick(AbstractCardManagerDrawer.this.getBaseContext(), 2, "cancel_switch_sync_data", slotId);
                AbstractCardManagerDrawer.this.startSetDefault4GSlotId(slotId);
                MLog.d("CardMgrAbs", "on nagative click start set default 4G");
            }
        }).create().show();
    }
}
1
2

关键代码
public boolean onPreferenceChange(Preference preference, Object newValue) {
    String key = preference.getKey();
    String value = String.valueOf(newValue);
    int slotId;
    if ("switch_dual_card_slots".equals(key)) {
        slotId = CardSelectPreference.getSlotIdValueBy(value);
        this.mActivity.trySetDefault4GSlotId(slotId);
        ItemUseStat.getInstance().handleClick(getActivity(), 3, "4g_3g_solt", slotId);
    } else if ("default_data_network".equals(key)) {
        slotId = CardSelectPreference.getSlotIdValueBy(value);
        startChangeDefaultDataCard(slotId);
        ItemUseStat.getInstance().handleClick(getActivity(), 3, "default_data_network", slotId);
    } else if ("switch_lte".equals(key)) {
        this.mActivity.getCardManager().setDataEnabled(Boolean.parseBoolean(value));
    } else if ("manual_select_network_card2".equals(key)) {
        boolean z;
        boolean on = Boolean.parseBoolean(value);
        this.mActivity.handleCard2Manual(on);
        if (on) {
            z = false;
        } else {
            z = true;
        }
        preference.setEnabled(z);
        ItemUseStat.getInstance().handleClick(getActivity(), 3, "manual_select_network_card2");
    }
    return true;
}
1
所处class

SimSettingsInfoFragment

1
2

最后结论
public static void setPrefCardForMobileData(int slotId) {
    try {
        MLog.i("CardManager", "card setPrefCardForMobileData:" + slotId);
        HwSubscriptionManager.getInstance().setUserPrefDataSlotId(slotId);
    } catch (Exception e) {
        MLog.w("CardManager", "set default card for mobile data failed!");
        e.printStackTrace();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
```
}

public void startChangeDefaultDataCard(int slotId) {
clearShowAutoChangeDefaultData();
CardManager.setPrefCardForMobileData(slotId);
this.mAscHandler.removeMessages(12);
Message msgTimeout = this.mAscHandler.obtainMessage(12);
msgTimeout.arg1 = slotId;
this.mAscHandler.sendMessageDelayed(msgTimeout, 120000);
if (!this.mNeedSwitchDataAfterSetDefault4G) {
showWaiting(getString(R.string.switching_default_def_data_tip), 102);
}
if (this.mCust != null) {
this.mCust.saveDefaultDataSlotId(slotId);
}
}


···

总结,这个app有2个类
其中一个类```SimSettingsInfoFragment```
protected void startChangeDefaultDataCard(int slotId) {
    if (slotId != this.mCardManager.getRealCardForMobileData()) {
        CardManager.setPrefCardForMobileData(slotId);
        this.mAscHandler.removeMessages(12);
        Message msgTimeout = this.mAscHandler.obtainMessage(12);
        msgTimeout.arg1 = slotId;
        this.mAscHandler.sendMessageDelayed(msgTimeout, 120000);
        showWaiting(getString(R.string.switching_default_def_data_tip), 102);
    }
}
1
以及

AbstractCardManagerDrawer

1
2


}

public void startChangeDefaultDataCard(int slotId) {
    clearShowAutoChangeDefaultData();
    CardManager.setPrefCardForMobileData(slotId);
    this.mAscHandler.removeMessages(12);
    Message msgTimeout = this.mAscHandler.obtainMessage(12);
    msgTimeout.arg1 = slotId;
    this.mAscHandler.sendMessageDelayed(msgTimeout, 120000);
    if (!this.mNeedSwitchDataAfterSetDefault4G) {
        showWaiting(getString(R.string.switching_default_def_data_tip), 102);
    }
    if (this.mCust != null) {
        this.mCust.saveDefaultDataSlotId(slotId);
    }
}
1
都大同小异的感觉,重要的代码还是拿到``` CardManager.setPrefCardForMobileData(slotId);

而这个类,我这边估计需要反射才能实现。 HwCustAbstractCardManager.saveDefaultDataSlotId则是一个空的方法,没有写任何逻辑。

image.png

image.png

1
2
3
4
5
6
7
8
9
10
11

public static int getSlotId(long subId) {
int slotId = SubscriptionManager.getSlotId((int) subId);
if (Constants.isValidSlotId(slotId)) {
return slotId;
}
MLog.e("CardManager", "getSlotId is invalid, we use the defualt slotid.slotId=" + slotId);
return 0;
}


从这里分析出来一个官方类
SubscriptionManager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

/**
* @return true if a valid subId else false
* @hide
*/
public static boolean isValidSubscriptionId(int subId) {
return subId > INVALID_SUBSCRIPTION_ID ;
}

/**
* @return true if subId is an usable subId value else false. A
* usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID.
* @hide
*/
public static boolean isUsableSubIdValue(int subId) {
return subId >= MIN_SUBSCRIPTION_ID_VALUE && subId <= MAX_SUBSCRIPTION_ID_VALUE;
}

/** @hide */
public static boolean isValidSlotIndex(int slotIndex) {
return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getSimCount();
}

/** @hide */
public static boolean isValidPhoneId(int phoneId) {
return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount();
}

/** @hide */
public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) {
int[] subIds = SubscriptionManager.getSubId(phoneId);
if (subIds != null && subIds.length > 0) {
putPhoneIdAndSubIdExtra(intent, phoneId, subIds[0]);
} else {
logd("putPhoneIdAndSubIdExtra: no valid subs");
}
}
1
SimDialogActivity.java

官方源码中,24是我的荣耀手机

1
public static int getSlotId(int subId) {

//https://blog.csdn.net/firedancer0089/article/details/59518976
这个subid怎么得到呢?

1
subId
1
2
  public int getSimState(int slotIdx) 
public String getSimOperator(int subId)

都是int类型,但是一定要瞪大眼睛看清楚是subid还是slotid,按照一般情况双卡机器一般也就插两张卡,那么subid可以是1和2,slotid是0和1,拿一张卡做开发的同学可能掉到坑里,因为1对subid还是slotid都是合法的值

https://www.cnblogs.com/caidi/p/4581816.html

androidL中使用一张数据表来保存sim卡信息:telephony.db中有一张记录SIM卡信息的表,siminfo:

1
2
3
4
5
CREATE TABLE siminfo(_id INTEGER PRIMARY KEY AUTOINCREMENT,
icc_id TEXT NOT NULL,sim_id INTEGER DEFAULT -1,display_name TEXT,carrier_name TEXT,name_source
INTEGER DEFAULT 0,color INTEGER DEFAULT 0,number TEXT,display_number_format

INTEGER NOT NULL DEFAULT 1,data_roaming INTEGER DEFAULT 0,mcc INTEGER DEFAULT 0,mnc INTEGER DEFAULT 0);

一行记录实例如下:

1
INSERT INTO "siminfo" VALUES(1,'89860114831010865147',0,'中国联通','中国联通3G',0,-16746133,'+8618516657794',1,0,460,1);

其中,主键_id就类似SIM卡的id,其值是从1开始递增的,sim_id类似于slot id,在双卡版本中一般只有-1/0/1三个值;其余的属性都好理解。

那如何去对应_id和sim_id呢?如函数:

1
2
3
4
5
SubscriptionController.getPhoneId(subId): // 根据subId取得phoneId
foreach entry: mSlotIdxToSubId.entrySet() // 具体代码,遍历mSlotIdxToSubId
int sim = entry.getKey(); // 对应siminfo表中的sim_id字段
int sub = entry.getValue(); // 对应siminfo表中的_id字段
if (subId == sub) { return sim; } // 正常流程下,这里返回的值会作为phoneId;

就是说传入的参数subId值等于siminfo表中的某行SIM的_id值,返回其sim_id字段,这个字段代表了phone id。

可以参考mSlotIdxToSubId 中的元素是这样填充的:

1
mSlotIdxToSubId.put(slotId, subId); // slotId:the slot which the SIM is inserted; 

subId:siminfo表中_id字段,一个例子:

           _id = 3
           icc_id = 89860114831010865147
           sim_id = 1