package com.android.phone; import java.util.Hashtable; import java.util.Set; import java.util.Timer; import java.util.TimerTask; import android.app.Dialog; import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; 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.provider.Settings; import android.provider.Settings.System; import android.telephony.PhoneStateListener; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.util.Config; import android.util.Log; import android.view.View; import android.widget.ImageButton; import android.widget.TextView; import android.widget.Toast; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneFactory; public class SelectSimCard extends PreferenceActivity implements View.OnClickListener{ private static final String STANDBY_CHECKED = "standbyChecked"; ImageButton mSim1Checked; ImageButton mSim2Checked; CheckBoxPreference mStandbyChecked; private boolean standbyCheckedStatus = false; private boolean standbyCheckedStatusOld = false; private boolean isStandbySim1Card=true; private boolean isStandbySim2Card=true; private boolean hasCard1 = false; private boolean hasCard2 = false; private boolean isAirplaneModeOn; private boolean isStandby[]; private int phoneCount; private Phone mPhones[]; private IntentFilter mIntentFilter; private TextView mOkButton, mCancelButton; private static final int EVENT_SET_SUBSCRIPTION_DONE = 100; private static final int EVENT_SET_SUBSCRIPTION_TIMEOUT = 200; private static final int DIALOG_WAIT_MAX_TIME= 60000; private static final String LOG_TAG = "SelectSimCard"; Hashtable<Integer,Boolean> waitTable = new Hashtable<Integer,Boolean>(); Hashtable<Integer,Boolean> busyTable = new Hashtable<Integer,Boolean>(); private PhoneStateListener[] mPhoneStateListener; private TelephonyManager[] mTelephonyManagers; private boolean mIsForeground; private Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case EVENT_SET_SUBSCRIPTION_DONE: Log.d(LOG_TAG,"EVENT_SET_SUBSCRIPTION_DONE"); finishSettingsWait(); break; case EVENT_SET_SUBSCRIPTION_TIMEOUT: if (mIsForeground) Toast.makeText(SelectSimCard.this, R.string.sim_state_set_timeout, Toast.LENGTH_LONG).show(); Log.d(LOG_TAG,"EVENT_SET_SUBSCRIPTION_TIMEOUT"); finishSettingsWait(); break; } return; } }; private void finishSettingsWait() { Log.d(LOG_TAG, "Finish dual settings wait."); PhoneFactory.autoSetDefaultPhoneId(true); removeDialog(0); closeTimer(); mSubDialog = null; waitTable.clear(); busyTable.clear(); finish(); } private BroadcastReceiver mBroadcastReceiver=new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.d(LOG_TAG,"onReceive "+action); if(Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)){ if (mIsForeground) { isAirplaneModeOn = Settings.System.getInt(getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0; if (hasCard1&& !isAirplaneModeOn) { mSim1Checked.setOnClickListener(SelectSimCard.this); } if (hasCard2&& !isAirplaneModeOn) { mSim2Checked.setOnClickListener(SelectSimCard.this); } mStandbyChecked.setEnabled(!isAirplaneModeOn); mOkButton.setEnabled(!isAirplaneModeOn); updateStatus(); }else{ finish(); } } } }; private ProgressDialog mSubDialog; @Override protected Dialog onCreateDialog(int id) { if (mSubDialog==null) { ProgressDialog dialog = new ProgressDialog(this); dialog.setTitle(getText(R.string.updating_dualsim_title)); dialog.setIndeterminate(true); dialog.setCancelable(false); dialog.setMessage(getText(R.string.updating_settings)); mSubDialog = dialog; } return mSubDialog; } @Override protected void onDestroy() { Log.d(LOG_TAG,"activity onDestroy()"); super.onDestroy(); if (mPhoneStateListener!=null&&mTelephonyManagers!=null) { for (int i =0;i<mTelephonyManagers.length;i++) { mTelephonyManagers[i].listen(mPhoneStateListener[i], PhoneStateListener.LISTEN_NONE); mPhoneStateListener[i] = null; mTelephonyManagers[i] = null; } } mTelephonyManagers = null; mPhoneStateListener = null; } @Override protected void onPause() { super.onPause(); this.unregisterReceiver(mBroadcastReceiver); mIsForeground = false; } @Override public void onConfigurationChanged(Configuration newConfig) { // TODO Auto-generated method stub super.onConfigurationChanged(newConfig); } // private void handleResult(AsyncResult ar) { // if (ar.exception == null) { // Log.v(LOG_TAG, "handleResult: success!"); // // TODO: show success feedback // if (null != mPhones[0]) { // //cienet add liqiangwu 2011-6-13: //// mPhones[0].setPreferredRadioPower(mSim1Checked.isChecked()); // } // if (null != mPhones[1]) { //// mPhones[1].setPreferredRadioPower(mSim2Checked.isChecked()); // } // //cienet end liqiangwu. // Intent i = new Intent(Intent.ACTION_REBOOT); // i.putExtra("nowait", 1); // i.putExtra("interval", 1); // i.putExtra("window", 0); // sendBroadcast(i); // // } else if (ar.exception instanceof CommandException) { // Log.v(LOG_TAG, "handleResult: failed!"); // // CommandException ce = (CommandException) ar.exception; // if (ce.getCommandError() == CommandException.Error.GENERIC_FAILURE) { // Log.v(LOG_TAG, "handleResult: generic failure!"); // // TODO: show generic failure feedback // Toast.makeText(this, R.string.sim_state_changed_failed, Toast.LENGTH_LONG).show(); // } // } // } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.selectsimcard); setContentView(R.layout.set_subscription_pref_layout); hasCard1 = PhoneFactory.isCardExist(0); hasCard2 = PhoneFactory.isCardExist(1); isAirplaneModeOn = Settings.System.getInt(getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0; mOkButton = (TextView) findViewById(R.id.ok); mOkButton.setOnClickListener(this); mCancelButton = (TextView) findViewById(R.id.cancel); mCancelButton.setOnClickListener(this); mSim1Checked = (ImageButton) findViewById(R.id.sub_0); if (hasCard1&& !isAirplaneModeOn) { mSim1Checked.setOnClickListener(this); } mSim2Checked = (ImageButton) findViewById(R.id.sub_1); if (hasCard2&& !isAirplaneModeOn) { mSim2Checked.setOnClickListener(this); } mStandbyChecked=(CheckBoxPreference)findPreference(STANDBY_CHECKED); phoneCount = PhoneFactory.getPhoneCount(); isStandby = new boolean[phoneCount]; mPhoneStateListener = new PhoneStateListener[phoneCount]; mTelephonyManagers = new TelephonyManager[phoneCount]; for (int i = 0; i < phoneCount; i++) { isStandby[i] = System.getInt(getContentResolver(), PhoneFactory.getSetting(System.SIM_STANDBY, i), 1) == 1; mPhoneStateListener[i] = getPhoneStateListener(i); // register for phone state notifications. mTelephonyManagers[i] = (TelephonyManager) this.getSystemService(PhoneFactory .getServiceName(Context.TELEPHONY_SERVICE, i)); mTelephonyManagers[i].listen(mPhoneStateListener[i], PhoneStateListener.LISTEN_SERVICE_STATE); } isStandbySim1Card=isStandby[0]; isStandbySim2Card=isStandby[1]; standbyCheckedStatusOld = System.getInt(getContentResolver(), System.POWER_ON_STANDBY_SELECT, 0) == 1; standbyCheckedStatus = standbyCheckedStatusOld; //receiver intent mIntentFilter = new IntentFilter(); mIntentFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); } private PhoneStateListener getPhoneStateListener(final int phoneId) { PhoneStateListener phoneStateListener = new PhoneStateListener() { @Override public void onServiceStateChanged(ServiceState state) { Log.d(LOG_TAG, "SelectSimCard onServiceStateChanged Received on SIM_" + phoneId +" state:"+state.getState()); checkServiceState(phoneId); } }; return phoneStateListener; } private int getIconId(int phoneId,boolean isCheck) { mStandbyChecked.setEnabled(!isAirplaneModeOn); if ((!hasCard2 && !hasCard1) || isAirplaneModeOn) { mOkButton.setEnabled(false); }else{ mOkButton.setEnabled(true); } if (phoneId==1) { if (!hasCard2||isAirplaneModeOn) { mSim2Checked.setEnabled(false); return R.drawable.dual_sim2_invalid; } mSim2Checked.setEnabled(true); if (isCheck) { return R.drawable.dual_sim2_checked; } else { return R.drawable.dual_sim2; } }else{ if (!hasCard1||isAirplaneModeOn) { mSim1Checked.setEnabled(false); return R.drawable.dual_sim1_invalid; } mSim1Checked.setEnabled(true); if (isCheck) { return R.drawable.dual_sim1_checked; } else { return R.drawable.dual_sim1; } } } @Override protected void onResume() { super.onResume(); Log.d(LOG_TAG,"activity onResume()"); mStandbyChecked.setChecked(standbyCheckedStatus); if (TelephonyManager.getPhoneCount() > 1) { mPhones = new Phone[PhoneFactory.getPhoneCount()]; for (int i = 0; i < PhoneFactory.getPhoneCount(); i++) { mPhones[i] = (PhoneFactory.getPhones())[i]; } updateStatus(); } this.registerReceiver(mBroadcastReceiver, mIntentFilter); mIsForeground = true; } private void updateStatus() { Log.d(LOG_TAG,"updateStatus : isStandbySim1Card="+isStandbySim1Card+" isStandbySim2Card="+isStandbySim2Card); mSim1Checked.setImageResource(getIconId(0,isStandbySim1Card)); mSim2Checked.setImageResource(getIconId(1,isStandbySim2Card)); } public void onClick(View v) { // if(mSubDialog != null){ // return; // } if (v == mOkButton) { standbyCheckedStatus = mStandbyChecked.isChecked(); if (standbyCheckedStatusOld== standbyCheckedStatus&&isStandby[0] == isStandbySim1Card&&isStandby[1] == isStandbySim2Card){ Toast.makeText(getApplicationContext(), R.string.sim_state_not_changes, Toast.LENGTH_LONG).show(); finish(); return; } System.putInt(getContentResolver(), System.Standby_Select_Card_Show, 1);//set Standby_Select_Card_Show to true ,so can`t pop this time setSubscription(); } else if (v == mCancelButton) { finish(); } else if (v == mSim1Checked) { isStandbySim1Card = !isStandbySim1Card; mSim1Checked.setImageResource(getIconId(0,isStandbySim1Card)); } else if (v == mSim2Checked) { isStandbySim2Card = !isStandbySim2Card; mSim2Checked.setImageResource(getIconId(1,isStandbySim2Card)); } } @Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { if(preference == mStandbyChecked){//save standbyCheckedStatus when other application does works; standbyCheckedStatus = mStandbyChecked.isChecked(); } return true; } private Timer timer; private TimerTask timerTask; private void startTimer() { closeTimer(); timer = new Timer(true); timerTask = new TimerTask() { public void run() { //force execute busy act execBusyAct(true); mHandler.sendEmptyMessage(EVENT_SET_SUBSCRIPTION_TIMEOUT); } }; Log.d(LOG_TAG, "startTimer,timer start"); timer.schedule(timerTask, DIALOG_WAIT_MAX_TIME); } private void closeTimer() { Log.d(LOG_TAG, "closeTimer,timer end"); if (timerTask != null) { timerTask.cancel(); timerTask = null; } if (timer != null) { timer.cancel(); timer.purge(); timer = null; } } private void setSubscription() { try{ if (isStandby[0] != isStandbySim1Card) { if (isStandbySim1Card) { System.putInt(getContentResolver(), PhoneFactory.getSetting(System.SIM_STANDBY, 0), 1); } else { System.putInt(getContentResolver(), PhoneFactory.getSetting(System.SIM_STANDBY, 0), 0); } } if (isStandby[1] != isStandbySim2Card) { if (isStandbySim2Card) { System.putInt(getContentResolver(), PhoneFactory.getSetting(System.SIM_STANDBY, 1), 1); } else { System.putInt(getContentResolver(), PhoneFactory.getSetting(System.SIM_STANDBY, 1), 0); } } if (standbyCheckedStatusOld!= standbyCheckedStatus) { if (standbyCheckedStatus) { System.putInt(getContentResolver(), System.POWER_ON_STANDBY_SELECT, 1); } else { System.putInt(getContentResolver(), System.POWER_ON_STANDBY_SELECT, 0); } } if (Config.LOGD) { Log.d(LOG_TAG, "isStandby[0]= " + isStandby[0] + " isStandby[1] =" + isStandby[1] + " isStandbySim1Card =" + isStandbySim1Card + " isStandbySim2Card =" + isStandbySim2Card); } if (isStandby[0] != isStandbySim1Card||isStandby[1] != isStandbySim2Card) { Intent intent=new Intent("android.intent.action.SelectSimCard"); if (isStandby[0] != isStandbySim1Card) { waitTable.put(0, isStandbySim1Card); busyTable.put(0, isStandbySim1Card); intent.putExtra("SIM1", true);//true ,StandbySim1Card has changed } if (isStandby[1] != isStandbySim2Card) { waitTable.put(1,isStandbySim2Card); busyTable.put(1,isStandbySim2Card); intent.putExtra("SIM2", true);//true ,StandbySim2Card has changed } setDefaultSim(); startChangeSimStandby(); //for ds-contacts, Log.d(LOG_TAG,"setSubscription:sent StandBySimCard action,sim1="+intent.getBooleanExtra("SIM1", false)+" ,sim2="+intent.getBooleanExtra("SIM2", false)); this.sendBroadcast(intent); }else{ Log.d(LOG_TAG,"only change POWER_ON_STANDBY_SELECT"); mHandler.sendEmptyMessage(EVENT_SET_SUBSCRIPTION_DONE); } }catch(Exception e){ mHandler.sendEmptyMessage(EVENT_SET_SUBSCRIPTION_DONE); Log.d(LOG_TAG,"run finish exception:"+e); e.printStackTrace(); } } private void setDefaultSim() { if (Config.LOGD) Log.d(LOG_TAG, "setDefaultSim:hasCard1 " + hasCard1 + ",hasCard2 " + hasCard2 + ",isStandbySim1Card " + isStandbySim1Card + ",isStandbySim2Card " + isStandbySim2Card); if (hasCard1 || hasCard2) { if (isStandbySim1Card && !isStandbySim2Card) { TelephonyManager.setDefaultSim(this, TelephonyManager.MODE_MMS, 0); TelephonyManager.setDefaultSim(this, TelephonyManager.MODE_TEL, 0); TelephonyManager.setDefaultSim(this, TelephonyManager.MODE_VTEL, 0); } else if (!isStandbySim1Card && isStandbySim2Card) { TelephonyManager.setDefaultSim(this, TelephonyManager.MODE_MMS, 1); TelephonyManager.setDefaultSim(this, TelephonyManager.MODE_TEL, 1); TelephonyManager.setDefaultSim(this, TelephonyManager.MODE_VTEL, 1); } } } private void startChangeSimStandby() { mOkButton.setEnabled(false); Log.d(LOG_TAG,"startChangeSimStandby"); try{ showDialog(0); } catch (RuntimeException e){ Log.d(LOG_TAG,"An exception occurs"); } execBusyAct(false); startTimer(); } private void execBusyAct(boolean isForce) { boolean isStart = false; if (!isForce&&busyTable.size()>1) { Set<Integer> keySet = busyTable.keySet(); for(Integer key:keySet) { boolean onOrOff = busyTable.get(key); if (!onOrOff) { mPhones[key].setRadioPower(onOrOff); busyTable.remove(key); isStart = true; Log.d(LOG_TAG,"start change Sim "+key+" power to "+(onOrOff?"On":"Off")); break; } } if (!isStart) { for(Integer key:keySet) { boolean onOrOff = busyTable.get(key); mPhones[key].setRadioPower(onOrOff); busyTable.remove(key); Log.d(LOG_TAG,"start change Sim "+key+" power to "+(onOrOff?"On":"Off")); break; } } }else{ Set<Integer> keySet = busyTable.keySet(); for(Integer key:keySet) { boolean onOrOff = busyTable.get(key); mPhones[key].setRadioPower(onOrOff); busyTable.remove(key); Log.d(LOG_TAG,"start change Sim "+key+" power to "+(onOrOff?"On":"Off")); } } } // public void onDismiss(DialogInterface dialog) { // // } // // public void onClick(DialogInterface dialog, int which) { // // } private void checkServiceState(int phoneId) { if (phoneId>=0&&waitTable.size()>0) { Boolean simCardOpen = waitTable.get(phoneId); if (simCardOpen!=null) { if (hasService(mPhones[phoneId].getServiceState())==simCardOpen) { waitTable.remove(phoneId); Log.d(LOG_TAG,"change Sim "+phoneId+" power finish success!"); if (busyTable.size()>0) { execBusyAct(false); } } } if (waitTable.size()==0) { mHandler.sendEmptyMessage(EVENT_SET_SUBSCRIPTION_DONE); Log.d(LOG_TAG,"change Sim power all finish success!"); } } } private boolean hasService(ServiceState ss) { if (ss != null) { switch (ss.getState()) { case ServiceState.STATE_POWER_OFF: return false; default: return true; } } else { return false; } } }