zoukankan      html  css  js  c++  java
  • 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
     
  • 相关阅读:
    js获取当前时间,日期格式为年月日
    create-react-app里添加less
    react css 模块化
    react 点击父级元素 不触发子级元素click事件
    react-router-dom 实现路由左右滑动进入页面的效果
    vue路由左右侧滑动 react路由左右侧滑动
    react 父组件不能直接在子组件上加className,也得用props传递过去
    react 父组件调用子组件方法
    css滚动相关问题记录
    javascript异步编程的几种方法
  • 原文地址:https://www.cnblogs.com/ldq2016/p/7028488.html
Copyright © 2011-2022 走看看