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
Android 监听双卡信号强度(附完整代码)的更多相关文章
- Android监听系统短信数据库变化-提取短信内容
由于监听系统短信广播受到权限的限制,所以很多手机可能使用这种方式没法监听广播,从而没办法获取到系统短信,所以又重新开辟一条路. Android监听系统短信数据库内容变化使用场景: 1.监听短信数据库的 ...
- Android监听应用程序安装和卸载
Android监听应用程序安装和卸载 第一. 新建监听类:BootReceiver继承BroadcastReceiver package com.rongfzh.yc; import android. ...
- 【Android】Android 监听apk安装替换卸载广播
[Android]Android 监听apk安装替换卸载广播 首先是要获取应用的安装状态,通过广播的形式 以下是和应用程序相关的Broadcast Action ACTION_PACKAGE_ADDE ...
- Android 监听 ScrollView 滑动到最底部。
做产品时,有一个需求,需要监听ScrollView滑动到最底部.在网上找了些方法,都有这样或那样的问题,要不就是监听不精确, 要不就是重复监听,那些代码没有产品化,很不可靠. 经过自己试验,终于找到了 ...
- Android监听返回键、Home键+再按一次返回键退出应用
Android监听返回键需重写onKeyDown()方法 Home键keyCode==KeyEvent.KEYCODE_HOME @Override public boolean onKeyDown( ...
- Android监听来电和去电
要监听android打电话和接电话,只需下面2步骤1.第一步,写一个Receiver继承自BroadcastReceiver import android.app.Service; import an ...
- Android监听ScrollView滑动到顶端和底部
Android监听ScrollView滑动到顶端和底部 package cn.testscrollview; import android.os.Bundle; import android. ...
- Android 监听网络变化
Android 监听网络变化
- android 监听返回键
android监听返回键 public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE ...
随机推荐
- IOS开发---菜鸟学习之路--(十七)-利用UITableView实现个人信息界面
首先来看下我们要实现的效果 需要实现这样的效果 然后我们开始动手吧. 首先选择添加一个新的ViewController 然后打开XIB文件,添加一UITableView 并将样式设置为分组 同时将按住 ...
- Python+Selenium练习篇之4-利用link text定位元素
本文介绍如何通过link text 来定位页面元素,我们打开网页,一些可以点击的链接跳转上面的文字,就是link text,用百度首页举例来看: 在上面图中,这一排上面的文字都是link text,例 ...
- Python学习-day13 SqlAlchemy
本节内容 ORM介绍 sqlalchemy安装 sqlalchemy基本使用 多外键关联 多对多关系 表结构设计作业 1. ORM介绍 orm英文全称object relational mapping ...
- Leetcode 655.输出二叉树
输出二叉树 在一个 m*n 的二维字符串数组中输出二叉树,并遵守以下规则: 行数 m 应当等于给定二叉树的高度. 列数 n 应当总是奇数. 根节点的值(以字符串格式给出)应当放在可放置的第一行正中间. ...
- Linux 基础命令、文档树 和 bash
最近发现了一个总结得更好的:bash cheatsheet 本文只是我对 linux 基础学习的一个总结,可能仅适用于复习用.算是我的 Linux 备忘录. 最基础 tab 补全 * 通配符 ctrl ...
- [oldboy-django][1初识django]阻止默认事件发生 + ajax + 模态编辑对话框
阻止默认事件发生 a 阻止a标签默认事件发生方法 <a href="http://www.baidu.com" onclick="modalEdit();" ...
- Lua 语法要点
table 默认键值都是从1开始 table array = { "A", "B" } array2 = array array[] = "D&quo ...
- This dependency was not found: * !!vue-style-loader!css-loader? 解决方案
但是当你新建一个vue项目时,需要重新安装stylus,否则报错: This dependency was not found: * !!vue-style-loader!css-loader?{&q ...
- Flask request获取参数问题
https://www.jianshu.com/p/ecd97b1c21c1 https://blog.csdn.net/lovebyz/article/details/52244330 https: ...
- 【HDOJ5996】dingyeye loves stone(Nim游戏)
题意:dingyeye喜欢和你玩石子游戏.dingyeye有一棵n个节点的有根树,节点编号为0到n−1,根为0号节点. 游戏开始时,第i个节点上有a[i]个石子.两位玩家轮流操作,每次操作玩家可以选择 ...