Android 监听双卡信号强度(附完整代码)

Android 监听双卡信号强度

监听单卡信号强度

监听单卡的信号强度非常简单直接用TelephonyManager.listen()去监听sim卡的信号强度.
TelephonyManager = mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE)
mTelephonyManager.listen(new PhoneStateListener(), PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);

 

单这只是针对单卡的时候, 现在手机基本标配双卡, 如果要监测sim卡的信号强度就要考虑到双卡, 然而百度了一下, 并没有博文去介绍怎么去监测双卡, 这下只能靠自己了.

监测sim卡1的信号强度

//SubscriptionManager  该类主要包含了所有sim卡的信息
SubscriptionManager mSubscriptionManager = SubscriptionManager.from(mContext);
//获取sim卡1的信息
SubscriptionInfo sub0 = mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(0);

if(null != sub0) {
    //如果不为空 说明sim卡1存在
    /*
        sub0.getSubscriptionId() 获取sim卡1的 subId 
    */
    Sim1SignalStrengthsListener mSim1SignalStrengthsListener = new Sim1SignalStrengthsListener(sub0.getSubscriptionId());
    //开始监听
     mTelephonyManager.listen(mSim1SignalStrengthsListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
}

上面只是设置并开始监听, 具体去监听哪一个sim卡的, 还需要具体去看 Sim1SignalStrengthsListener 中对 subId 的具体处理

PhoneStateListener 类中有一个成员变量 mSubId , 这个值就是当前默认操作的sim卡, 如果不明确指定, 默认值就是 SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, 看PhoneStateListener在有带参构造设置subId, 但是都是hide隐藏, 既然无法初始化去设置subId, 那么我们就用Java强大的功能”反射”去设置mSubId的值, 设置完成之后, PhoneStateListener 就成了我们指定监测的sim卡了.

/*
  * Subscription used to listen to the phone state changes
  * @hide
  */
 /** @hide */
 protected int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;

 /**
  * Create a PhoneStateListener for the Phone with the default subscription
  * using a particular non-null Looper.
  * @hide
  */
 public PhoneStateListener(Looper looper) {
     this(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, looper);
 }
/**
  * Create a PhoneStateListener for the Phone using the specified subscription
  * and non-null Looper.
  * @hide
  */
 public PhoneStateListener(int subId, Looper looper) {
  ...
 }

 

 public static final int DEFAULT_SUBSCRIPTION_ID = Integer.MAX_VALUE;
  • 1

 

class Sim1SignalStrengthsListener extends PhoneStateListener {

        public Sim1SignalStrengthsListener(int subId) {
            super();
            ReflectUtil.setFieldValue(this, "mSubId", subId);
        }

        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
            super.onSignalStrengthsChanged(signalStrength);
            int level = getSignalStrengthsLevel(signalStrength);
        }
    }

 

反射代码 ReflectUtil



public static void setFieldValue(final Object obj, final String fieldName, final Object value) {  
  Field field = getAccessibleField(obj, fieldName);  

  if (field == null) {  
      throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");  
  }  

  try {  
      field.set(obj, value);  
  } catch (IllegalAccessException e) {  
    e.printStackTrace();
  }  
}  

public static Field getAccessibleField(final Object obj, final String fieldName) {
  if (obj == null) {
      throw new IllegalArgumentException("object can't be null");  
}

  if (fieldName == null || fieldName.length() <= 0) {
throw new IllegalArgumentException("fieldName can't be blank");  
}

  for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {  
      try {  
          Field field = superClass.getDeclaredField(fieldName);  
          makeAccessible(field);  
          return field;  
      } catch (NoSuchFieldException e) {
          continue;
      }  
  }
  return null;  
} 

public static void makeAccessible(Field field) {
      if ((!Modifier.isPublic(field.getModifiers()) ||!Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) {  
         field.setAccessible(true);  
      }  
} 

 

监测sim卡2的信号强度

获取sim卡2的信息, 其他同sim卡1

...
SubscriptionInfo sub0 = mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(1);
...
  • 1

附完整代码

/**
 * 手机信号监控(双卡)
 * Created by zengyan on 2016/6/29.
 */
public class SignalStrengthsHandler {

    public static final String TAG = "SignalStrengthsManager";
    public static final int INDEX_SIM1 = 0;
    public static final int INDEX_SIM2 = 1;
    private static SignalStrengthsHandler mInstance = null;
    public static byte[] mLock = new byte[0];
    private final Context mContext;
    private final TelephonyManager mTelephonyManager;
    private final SubscriptionManager mSubscriptionManager;
    private final SimStateReceive mSimStateReceiver;

    private SimSignalInfo mSim1SignalInfo = new SimSignalInfo();
    private SimSignalInfo mSim2SignalInfo = new SimSignalInfo();

    private ArrayList<OnSignalStrengthsChangedListener> mOnSignalStrengthsChangedListeners = null;
    private Sim1SignalStrengthsListener mSim1SignalStrengthsListener;
    private Sim2SignalStrengthsListener mSim2SignalStrengthsListener;

    @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
    private SignalStrengthsHandler() {
        mSubscriptionManager = SubscriptionManager.from(mContext);
        mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        initListeners();

        mSimStateReceiver = new SimStateReceive();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(SimStateReceive.ACTION_SIM_STATE_CHANGED);
        mContext.registerReceiver(mSimStateReceiver, intentFilter);
    }

    public static SignalStrengthsHandler getInstance() {
        if (null == mInstance) {
            synchronized (mLock) {
                if (null == mInstance) {
                    mInstance = new SignalStrengthsHandler();
                }
            }
        }
        return mInstance;
    }

    public void destroyInstance() {
        if (null != mInstance) {
            synchronized (mLock) {
                if (null != mInstance) {
                    if (null != mOnSignalStrengthsChangedListeners) {
                        mOnSignalStrengthsChangedListeners.clear();
                        mOnSignalStrengthsChangedListeners = null;
                    }
                    mContext.unregisterReceiver(mSimStateReceiver);
                    mInstance = null;
                }
            }
        }
    }


    private void initListeners() {
        listenSimSignalStrengths(SimCard.SIM_CARD_1);
        listenSimSignalStrengths(SimCard.SIM_CARD_2);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
    private void listenSimSignalStrengths(SimCard simCard) {
        if (simCard == SimCard.SIM_CARD_1) {
            SubscriptionInfo sub0 = mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(INDEX_SIM1);
            if (sub0 != null && null == mSim1SignalStrengthsListener) {
                mSim1SignalStrengthsListener = new Sim1SignalStrengthsListener(sub0.getSubscriptionId());
            }
            mTelephonyManager.listen(mSim1SignalStrengthsListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
        } else if (simCard == SimCard.SIM_CARD_2) {
            SubscriptionInfo sub1 = mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(INDEX_SIM2);
            if (sub1 != null && null == mSim2SignalStrengthsListener) {
                mSim2SignalStrengthsListener = new Sim2SignalStrengthsListener(sub1.getSubscriptionId());
            }
            mTelephonyManager.listen(mSim2SignalStrengthsListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
        }
    }

    private void unListenSimSignalStrengths(SimCard simCard) {
        if (simCard == SimCard.SIM_CARD_1) {
            mSim1SignalInfo.mIsActive = false;
            mSim1SignalInfo.mLevel = 0;
            if (null != mSim1SignalStrengthsListener) {
                mTelephonyManager.listen(mSim1SignalStrengthsListener, PhoneStateListener.LISTEN_NONE);
            }
        } else if (simCard == SimCard.SIM_CARD_2) {
            mSim2SignalInfo.mIsActive = false;
            mSim2SignalInfo.mLevel = 0;
            if (null != mSim2SignalStrengthsListener) {
                mTelephonyManager.listen(mSim2SignalStrengthsListener, PhoneStateListener.LISTEN_NONE);
            }
        }

    }

    /**
     * 添加监听sim卡信号强度
     *
     * @param listener
     */
    public void registerOnSignalStrengthsChangedListener(OnSignalStrengthsChangedListener listener) {
        if (null == mOnSignalStrengthsChangedListeners) {
            mOnSignalStrengthsChangedListeners = new ArrayList<>();
        }

        if (mOnSignalStrengthsChangedListeners.contains(listener)) {
            return;
        }

        if (null != listener) {
            mOnSignalStrengthsChangedListeners.add(listener);
        }
    }

    public void unregisterOnSignalStrengthsChangedListener(OnSignalStrengthsChangedListener listener) {
        if (null == mOnSignalStrengthsChangedListeners) {
            return;
        }

        if (null == listener) {
            return;
        }

        if (mOnSignalStrengthsChangedListeners.contains(listener)) {
            mOnSignalStrengthsChangedListeners.remove(listener);
        }
    }

    public void notyfyStateChange(boolean isSim1Exist, boolean isSim2Exist) {
        if (null != mOnSignalStrengthsChangedListeners && !mOnSignalStrengthsChangedListeners.isEmpty()) {
            for (int i = 0; i < mOnSignalStrengthsChangedListeners.size(); i++) {
                OnSignalStrengthsChangedListener listener = mOnSignalStrengthsChangedListeners.get(i);
                if (null != listener) {
                    listener.onSimStateChanged(isSim1Exist, isSim2Exist);
                }
            }
        }
    }

    public void notifyChange(SimCard simCard, int level) {
        if (null != mOnSignalStrengthsChangedListeners && !mOnSignalStrengthsChangedListeners.isEmpty()) {
            for (int i = 0; i < mOnSignalStrengthsChangedListeners.size(); i++) {
                OnSignalStrengthsChangedListener listener = mOnSignalStrengthsChangedListeners.get(i);
                if (null != listener) {
                    listener.onSignalStrengthsChanged(simCard, level);
                }
            }
        }
    }

    public boolean isSimCardExist(int cardIndex) {
        boolean isSimCardExist = false;
        try {
            Method method = TelephonyManager.class.getMethod("getSimState", new Class[]{int.class});
            int simState = (Integer) method.invoke(mTelephonyManager, new Object[]{Integer.valueOf(cardIndex)});
            if (TelephonyManager.SIM_STATE_READY == simState) {
                isSimCardExist = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return isSimCardExist;
    }

    /**
     * 获取sim信号 状态信息
     *
     * @return int[]  index: 0:sim1 1:sim2
     */
    public SimSignalInfo[] getSimSignalInfos() {
        return new SimSignalInfo[]{mSim1SignalInfo, mSim2SignalInfo};
    }

    private int getSignalStrengthsLevel(SignalStrength signalStrength) {
        int level = -1;
        try {
            Method levelMethod = SignalStrength.class.getDeclaredMethod("getLevel");
            level = (int) levelMethod.invoke(signalStrength);
        } catch (Exception e) {
            LogUtil.e(TAG, e.getMessage());
        }
        return level;
    }

    private class Sim1SignalStrengthsListener extends PhoneStateListener {

        public Sim1SignalStrengthsListener(int subId) {
            super();
            //设置当前监听的sim卡
            ReflectUtil.setFieldValue(this, "mSubId", subId);
        }

        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
            super.onSignalStrengthsChanged(signalStrength);
            int level = getSignalStrengthsLevel(signalStrength);
            if (mSim1SignalInfo.mLevel == level) {
                return;
            }
            mSim1SignalInfo.mLevel = level;
            SignalStrengthsHandler.this.notifyChange(SimCard.SIM_CARD_1, mSim1SignalInfo.mLevel);
            LogUtil.d(TAG, "sim 1 signal strengths level = " + mSim1SignalInfo.mLevel);
        }
    }

    private class Sim2SignalStrengthsListener extends PhoneStateListener {

        public Sim2SignalStrengthsListener(int subId) {
            super();
            //设置当前监听的sim卡
            ReflectUtil.setFieldValue(this, "mSubId", subId);
        }

        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
            super.onSignalStrengthsChanged(signalStrength);
            int level = getSignalStrengthsLevel(signalStrength);
            if (mSim2SignalInfo.mLevel == level) {
                return;
            }
            mSim2SignalInfo.mLevel = level;
            SignalStrengthsHandler.this.notifyChange(SimCard.SIM_CARD_2, mSim2SignalInfo.mLevel);
            LogUtil.d(TAG, "sim 2 signal strengths level = " + mSim2SignalInfo.mLevel);
        }
    }

    public interface OnSignalStrengthsChangedListener {
        void onSignalStrengthsChanged(SimCard simCard, int level);

        void onSimStateChanged(boolean isSim1Exist, boolean isSim2Exist);
    }

    public enum SimCard {
        SIM_CARD_1, SIM_CARD_2
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
    class SimStateReceive extends BroadcastReceiver {
        private final static String ACTION_SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED";

        @Override
        public void onReceive(Context context, Intent intent) {
            LogUtil.i("SimStateReceive", "sim state changed");
            if (intent.getAction().equals(ACTION_SIM_STATE_CHANGED)) {
                mSim1SignalInfo.mIsActive = isSimCardExist(INDEX_SIM1)
                        && null != mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(INDEX_SIM1);
                mSim2SignalInfo.mIsActive = isSimCardExist(INDEX_SIM2)
                        && null != mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(INDEX_SIM2);

                mSim1SignalInfo.mLevel = 0;
                mSim2SignalInfo.mLevel = 0;
                if (mSim1SignalInfo.mIsActive) {
                    listenSimSignalStrengths(SimCard.SIM_CARD_1);
                } else {
                    unListenSimSignalStrengths(SimCard.SIM_CARD_1);
                }
                if (mSim2SignalInfo.mIsActive) {
                    listenSimSignalStrengths(SimCard.SIM_CARD_2);
                } else {
                    unListenSimSignalStrengths(SimCard.SIM_CARD_2);
                }
                notyfyStateChange(mSim1SignalInfo.mIsActive, mSim2SignalInfo.mIsActive);
            }
        }
    }

    public class SimSignalInfo {
        /**
         * 信号强度 0 - 5
         */
        public int mLevel;

        /**
         * sim卡是否有效
         */
        public boolean mIsActive;
    }
}
  • 1
 
posted @ 2017-06-16 17:19  一点点征服  阅读(5774)  评论(0编辑  收藏  举报