查看运营商与网络类型

虽然现在4G网络很普及了,但是我国幅员辽阔,4G信号在某些地方接收不良,手机连接很容易掉到3G甚至2G网络。为了让用户在低速环境也能使用App的基础功能,而不至于还在老牛破车地缓慢下载大图,App就得判断当前所处的网络环境,从而针对不同的网络连接提供相应的访问模式;比如在4G网络下默认完整模式,在2G/3G网络下默认切换到极简模式。

查看网络类型等信息,用到了电话管理器TelephonyManager,它的对象从系统服务TELEPHONY_SERVICE中获取,相关方法说明如下:
getNetworkOperator : 获取运营商代码。返回五位数字的字符串,前三位表示移动国家代码(Mobile Country Code,简称MCC),后两位表示移动网络代码(Mobile Network Code,简称MNC)。
getNetworkOperatorName : 获取运营商名称。如中国移动、中国联通、中国电信等等。
getPhoneType : 获取电话类型。返回1表示GSM,2表示CDMA,3表示SIP。
getNetworkType : 获取网络类型。这个网络类型包含每代网络的细分类型,可表示GPRS、CDMA、EvDo、HSPA、LTE等等。
getNetworkTypeName : 获取网络类型的名称。隐藏方法,需使用反射机制调用。
getNetworkClass : 获取网络分代。隐藏方法,需使用反射技术调用。返回1表示2G,返回2表示3G,返回3表示4G。

下面是查看具体手机上网络类型的截图,第一张图片为使用移动号码的网络信息,第二张图片为使用联通号码的网络信息。
 

下面是查看网络类型的代码例子:

 private void initOperator() {TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);String desc = "";// MCC,Mobile Country Code,移动国家代码(中国的为460);// MNC,Mobile Network Code,移动网络代码(中国移动为0,中国联通为1,中国电信为2);String operator = tm.getNetworkOperator();int mcc = Integer.parseInt(operator.substring(0, 3));int mnc = Integer.parseInt(operator.substring(3, 5)); desc = String.format("%s\n 国家代码=%d", desc, mcc);desc = String.format("%s\n 网络代码=%d", desc, mnc);desc = String.format("%s\n 运营商名称=%s", desc, tm.getNetworkOperatorName());desc = String.format("%s\n 手机类型=%s", desc, SignalUtils.mVoiceArray[tm.getPhoneType()]);desc = String.format("%s\n 网络类型=%s", desc, SignalUtils.getNetworkTypeName(tm, tm.getNetworkType()));desc = String.format("%s\n 网络分代=%s", desc, SignalUtils.getClassName(tm, tm.getNetworkType()));tv_operator.setText(desc);}

查看双卡双待信息

标准的Android系统只支持一张sim卡,不支持一个手机同时插两张卡。可是许多人都希望手机插两张卡,一张卡用于工作,一张卡用于私人,所以双卡双待手机最早由山寨机厂商推出后,就大受国人追捧,使得国内各大厂商纷纷跟进推出双卡手机。时至今日,中国的智能手机市场,早已是双卡手机的天下,Android标准的单卡手机反而沦为少数群体了。

现在有些App的用户账号与手机是绑定的,一部手机只能注册一个账号,然而注册用户应该以手机号码做为唯一标识,像双卡手机同时插了两张卡,就应当允许注册两个账号,每个帐号都对应一个手机号码,才符合正常的处理逻辑。因此,App在用户注册帐号时,可先判断当前手机是否支持双卡,且是否两个卡槽都插了sim卡,如果用户手机找到两个手机卡,则允许这部手机按照号码分别注册两个账号。

既然广大用户存在双卡手机的需求,而且App也需要校验双卡信息,那么Android理当响应广大人民的呼声,顺势推出双卡功能才对。遗憾的是,原生的Android一直坚守单卡方案,反而是芯片厂商在底层对Android系统做了深度定制,使得采用这些芯片的手机也能支持双卡功能。因为双卡模块由各家芯片厂商自行定制,所以查询双卡信息没有统一的标准,开发者只有获得各厂商的私有查询API,然后在App中各显神通,想办法知道当前手机用的是哪套双卡方案,详细的双卡信息又是什么。

双卡方案的实现方式各有不同,市面上的Android智能手机,大多采用了高通芯片或者联发科芯片,于是双卡方案也形成了高通与联发科两大阵营。它们都提供了查询两个卡槽的imei和imsi信息,不过由于是隐藏方法,故而要通过反射机制来调用。

下面是查看具体手机上双卡信息的截图,第一张图片为使用高通方案的双卡信息,第二张图片为使用联发科方案的双卡信息。
 

下面是查看双卡信息的代码例子:

 public static int SINGLE_STANDARD = 0, DOUBLE_MTK = 1, DOUBLE_GC = 2;public static String[] mSolutionDesc = {"标准单卡", "联发科双卡", "高通双卡"};private void setCardInfo() {//读取电话信息需要授权android.permission.READ_PHONE_STATEtm = ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE));mCardInfo.imei1 = tm.getDeviceId();mCardInfo.imsi1 = tm.getSubscriberId();try {mCardInfo.imei1 = getByReflect(mContext, "getDeviceIdGemini", 0);mCardInfo.imei2 = getByReflect(mContext, "getDeviceIdGemini", 1);setSolutionType(DOUBLE_MTK);  //联发科方案mCardInfo.imsi1 = getByReflect(mContext, "getSubscriberIdGemini", 0);mCardInfo.imsi2 = getByReflect(mContext, "getSubscriberIdGemini", 1);} catch (Exception e) {e.printStackTrace();try {mCardInfo.imei1 = getByReflect(mContext, "getDeviceId", 0);mCardInfo.imei2 = getByReflect(mContext, "getDeviceId", 1);setSolutionType(DOUBLE_GC);  //高通方案mCardInfo.imsi1 = getByReflect(mContext, "getSubscriberId", 0);mCardInfo.imsi2 = getByReflect(mContext, "getSubscriberId", 1);} catch (Exception e1) {e1.printStackTrace();}}}private String getByReflect(Context context, String method, int seq) throws Exception {String inumeric = null;Class<?> telephonyClass = Class.forName(tm.getClass().getName());Class<?>[] parameter = new Class[1];parameter[0] = int.class;Method getSimID = telephonyClass.getMethod(method, parameter);Object[] obParameter = new Object[1];obParameter[0] = seq;Object ob_phone = getSimID.invoke(tm, obParameter);if (ob_phone != null) {inumeric = ob_phone.toString();}return inumeric;}private void setSolutionType(int solutionType) {mCardInfo.solutionType = solutionType;mCardInfo.solutionDesc = mSolutionDesc[solutionType];if (solutionType > 0) {mCardInfo.bDouble = true;}}

Android5.1增加支持多sim卡

国内的双卡手机已占市场主流,即使Android长期固守单卡,那也不能无视广大人民的呼声呀,所以从Android5.1开始,Android正式支持多张sim卡。其实也没有增加新的管理类,只是给TelephonyManager重载了几个sim卡信息获取接口,允许传入序号参数,比如传0表示获取第一个卡槽的sim卡信息,传1表示获取第二个卡槽的sim卡信息。

下面是新增的几个重载方法说明:
getDeviceId : 获取指定卡槽的imei号。如果该卡槽是cdma制式,则返回meid值。
getImei: 获取指定卡槽的imei号。
getSubscriberId: 获取指定sim卡的imsi。
getSimOperator: 获取指定sim卡的运营商名称。
getNetworkType: 获取指定sim卡的网络类型。
getCurrentPhoneType: 获取指定sim卡的手机类型。
getNetworkOperatorName: 获取指定sim卡的网络运营商名称。
isNetworkRoaming: 获取指定sim卡是否处于网络漫游。

另需注意,以上方法都是隐藏方法,不能直接调用,得通过反射机制调用才行。有关反射机制的说明参见《 Android开发笔记(六十)网络的检测与连接》。

点击下载本文用到的手机制式适配的工程代码

点此查看Android开发笔记的完整目录

Android开发笔记(一百二十八)手机制式适配相关推荐

  1. Android开发笔记(二十八)利用Application实现内存读写

    全局变量 C/C++有所谓的全局变量,因为全局变量保存在内存中,所以操作全局变量就是操作内存,其速度远比操作数据库或者操作文件快得多,而且工程里的任何代码都可以引用全局变量,因此很多时候全局变量是共享 ...

  2. Android开发笔记(六十八)工程库打包

    写好一个Android模块,比如说一个自定义控件或某个功能的sdk,然后开放出来给别人使用,就得通过某种方式把源码提供给对方.常见的打包方式有: 一.直接给源码,由开发者把代码加入到自己的工程中 该方 ...

  3. Android开发笔记(二十四)res目录的结构与配置

    res目录结构 res是Android项目工程中存放各类的目录,主要包括布局.图形与配置等等.res的子目录主要有: anim : 存放动画的描述文件 drawable : 存放各类图形的描述文件,包 ...

  4. Android开发笔记(五十八)铃声与震动

    拖动条SeekBar SeekBar继承自进度条ProcessBar,有关ProcessBar的介绍见<Android开发笔记(四十九)异步任务处理AsyncTask>.SeekBar与P ...

  5. Android开发笔记(七十八)异常容错处理

    Exception Java的异常分两类,运行时异常RuntimeException和非运行时异常. 运行时异常包括空指针异常NullPointerException.数组越界异常IndexOutOf ...

  6. Android开发笔记(四十八)Thread类实现多线程

    Thread概述 Thread类是真正的线程,查看源码可见Thread也实现了Runnable接口,但它内部有创建新的工作线程,所以Thread对象运行在与主线程不一样的分线程上. 因为Thread对 ...

  7. Android开发笔记(二十)顶部导航栏ActionBar

    标题栏ActionBar ActionBar是在Android3.0之后引入的,所以Android2.x之前的版本不能直接使用ActionBar.现在ActionBar广泛用做APP的顶部导航栏,它在 ...

  8. Android开发笔记(三十八)列表类视图

    AdapterView AdapterView顾名思义是适配器视图,Spinner.ListView和GridView都间接继承自AdapterView,这三个视图都存在多个元素并排展示的情况,所以需 ...

  9. Android开发笔记(二十九)使用SharedPreferences存取数据

    SharedPreferences使用场景 共享参数(SharedPreferences)是Android上的一个轻量级存储工具,存储结构是类似map的key-value键值对形式.它主要用于保存ap ...

  10. Android开发笔记(二十六)Java的容器类

    容器的分类 集合(Set/HashSet) 集合中的元素是没有顺序的,而且不可以重复.这意味着,集合只能遍历而无法通过索引访问指定元素,并且如果重复添加相同值将不会增大集合.因为Set只是接口,所以实 ...

最新文章

  1. HTML 5中SEO可以用那些代码来做优化
  2. 重磅!明略发布数据中台战略和三大解决方案
  3. RDS读写分离,海量数据一键搞定
  4. 生态伙伴 | 轻计划入驻飞书,轻松管理你的项目
  5. 皮一皮:这真是兄弟能做的事???
  6. 20162328蔡文琛week07
  7. 好嗨哟~谷歌量子神经网络新进展揭秘
  8. 超清晰的 DNS 原理入门指南
  9. Node操作Mysql的简单例子
  10. Android风格与主题
  11. SQL注入 mysql4.0版本_SQL注入(上)
  12. python解析GF1卫星数据.xml文件
  13. 酷派大观4 8970 刷android 4.4,酷派大观4电信版如何刷机?【图文教程】
  14. 2020计算机组成原理课程设计(桂电)
  15. 如何做决策?SWOT分析
  16. 汇编语言简明教程习题答案
  17. 全国计算机专业大学排名全部,全国计算机专业大学排名汇总
  18. 浅谈web前端工程师hr面试经典问题20+
  19. 系统稳定神器supervisor
  20. mac下怎么将终端命令安装的软件加进系统环境变量中

热门文章

  1. 操作系统(程序员必学简化版)
  2. C/语/言/自/学/笔记
  3. 计算矩形面积的程序python_python实现用类读取文件数据并计算矩形面积
  4. 图像进行反转:白变黑,黑变白
  5. 怎样使页面加载完再执行js代码
  6. “好男人不包二奶”的营销策略——奢侈品“奇葩”市场缘何存在?
  7. Linux——信号及其使用
  8. ONNX YOLOv6目标检测,GitHub搜索引擎,Tooll 3 实时动画创建,汇编通俗入门,AI前沿论文 | ShowMeAI资讯日报
  9. 求大家推荐一款好用的天气预报软件华为ma_硬磕到底!华为、字节跳动入局搜索市场,与百度正面刚...
  10. 国内五款主流外贸CRM优缺点综合评测