专栏首页老欧说安卓Android开发笔记(一百二十八)手机制式适配

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

查看运营商与网络类型

虽然现在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_STATE
		tm = ((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开发笔记的完整目录

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android开发笔记(一百)折叠式列表

    经常看朋友圈的动态,有的动态内容较多就只展示前面一段,如果用户想看完整的再点击展开,这样整个页面的动态列表比较均衡,不会出现个别动态占用大片屏幕的情况。同样...

    用户4464237
  • Kotlin入门(11)江湖绝技之特殊函数

    上一篇文章介绍了Kotlin对函数的输入参数所做的增强之处,其实函数这块Kotlin还有好些重大改进,集中体现在几类特殊函数,...

    用户4464237
  • Android开发笔记(四十六)手机相关事件

    有一类事件必须依赖于手机信号方能触发,如果把设备中的sim卡拔出,或者该设备本身不支持sim卡(如ipad),那么这类事件将永远不会被触发。在Android...

    用户4464237
  • 网络安全后花园-数据中心运维管理区域顶层设计

    本期我们来揭秘数据中心运维管理区域安全顶层设计,数据中心流量经过广域网接入区域的安全过滤后会进入各个逻辑区域,为保障各个区域的安全性,我们在规划设计...

    ICT售前新说
  • Spring Boot + MyBatis + Druid + PageHelper 实现多数据源并分页

    本篇文章主要讲述的是 Spring Boo t整合Mybatis、Druid和PageHelper 并实现多数据源和分页。其中Spring Boot整合Myba...

    java思维导图
  • SpringBoot+Mybatis+ Druid+PageHelper 实现多数据源并分页

    本篇文章主要讲述的是SpringBoot整合Mybatis、Druid和PageHelper 并实现多数据源和分页。其中SpringBoot整合Mybatis这...

    用户4143945
  • SpringBoot+Mybatis+ Druid+PageHelper 实现多数据源并分页

    本篇文章主要讲述的是SpringBoot整合Mybatis、Druid和PageHelper 并实现多数据源和分页。其中SpringBoot整合Mybatis这...

    Java团长
  • 关于博客的数据库分类

    这个分类是在上一次修改文章分类的时候加上的,但一直都没有添加文章,原因很简单,因为数据库是我较弱的一环,肚里确实没多少可以记录的"墨水"。所在的公司分工忒细致,...

    张戈
  • 【数据分析】盘点五一期间最受欢迎的几个景区

    五一假期已经结束,小伙伴是不是都还没有玩过瘾?但是没办法,还有很多bug等着我们去写,同样还有需要money需要我们去赚。为了生活总的拼搏。

    周三不加班
  • 警惕钓鱼陷阱:95%赌球网站是钓鱼网站

    这一届世界杯,阿根廷、德国、西班牙接连败北,让球迷连呼意外。而网络赌球更是害人害己,前不久深圳一男子欲跳水库,只因押车卖房套现60万元赌球,哪知不断的冷门,让他...

    安恒信息

扫码关注云+社区

领取腾讯云代金券