Android开发——反射获取双卡Sim卡信息

参考了前辈的博客:https://blog.csdn.net/ymcl_hx/article/details/53484797

直接封装出来一个工具类,记录一下

package com.dreamroom.device;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONObject;

import android.telephony.TelephonyManager;

public class SimUtils {

	public JSONArray getAllSimInfo(TelephonyManager tel) throws Exception {
		Class<?> clazz = tel.getClass();
		
		//获取可以进行反射的字段
		List<EMethod> list = new ArrayList<>();
		Map<String, Integer> listIgnore = new HashMap<>();

		Method[] methods = clazz.getDeclaredMethods();
		for(Method method : methods) {
			String name = method.getName();
			if(!name.startsWith("get"))
				continue;
			
			if(listIgnore.get(name) != null)
				continue;
			listIgnore.put(name, 0);

			Method m1 = null;
			Method m2 = null;
			Method m3 = null;
			try {m1 = clazz.getDeclaredMethod(name); } catch(Exception e) {}
			try {m2 = clazz.getDeclaredMethod(name, int.class); } catch(Exception e) {}
			try {m3 = clazz.getDeclaredMethod(name, long.class); } catch(Exception e) {}
			
			if(m1 != null && ((m2 == null && m3 != null) || (m2 != null && m3 == null))) {
				Class<?> c1 = m1.getReturnType();
				Class<?> c2 = m2 == null ? null : m2.getReturnType();
				Class<?> c3 = m3 == null ? null : m3.getReturnType();
				if(m2 == null) {
					if(c1 == null || c1 != c3)
						continue;
				} else {
					if(c1 == null || c1 != c2)
						continue;
				}
				EMethod item = new EMethod(name, m2 == null ? 1 : 0, c1);
				list.add(item);
			}
		}
		listIgnore.clear();
		
		JSONArray array = new JSONArray();
		for(int i=0; i<10; i++) {
			JSONObject json = new JSONObject();
			for(EMethod em : list) {
				Method method = null;
				Object param = null;
				if(em.type == 0) {
					method = clazz.getDeclaredMethod(em.name, int.class);
					param = i;
				} else {
					method = clazz.getDeclaredMethod(em.name, long.class);
					param = new Long(i);
				}
				if(!method.isAccessible())
					method.setAccessible(true);
				
				String name = em.name.substring(3);
				Object value = null;
				try {
					value = method.invoke(tel, param);
				} catch(Exception e) {
					//前面已经对private设置了可访问,有些还是会报错,就不管这个了
					continue;
				}
				
				json.put(name, value);
			}
			
			if(json.optInt("SimState") == TelephonyManager.SIM_STATE_UNKNOWN || json.optInt("SimState") == TelephonyManager.SIM_STATE_ABSENT)
				continue;
			
			String imsi = json.optString("SubscriberId");
			if(imsi == null || imsi.length() == 0)
				continue;
			
			//根据imsi去重
			boolean repeact = false;
			for(int j=0; j<array.length(); j++) {
				if(imsi.equals(array.optJSONObject(j).optString("SubscriberId"))) {
					repeact = true;
					break;
				}
			}
			if(repeact)
				continue;
			
			array.put(json);
		}
		return array;
	}

	static class EMethod {
		public String name;
		public int type;	//0为int,1为long
		public Class<?> returnType;	//返回类型
		public EMethod(String name, int type, Class<?> returnType) {
			this.name = name;
			this.type = type;
			this.returnType = returnType;
		}
	}
}

传入TelephonyManager对象进行获取,返回JSONArray数据

TelephonyManager tel = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
JSONArray simList = SimUtils.getAllSimInfo(tel);

我的是双卡,返回的数据如下(对imsi等敏感数据进行了脱敏):

[
    {
        "NetworkTypeName":"UNKNOWN",
        "PhoneId":0,
        "PhoneType":1,
        "PhoneTypeFromNetworkType":1,
        "PhoneTypeFromProperty":1,
        "SubId":0,
        "CallState":0,
        "CdmaEriIconIndex":-1,
        "CdmaEriIconMode":-1,
        "CdmaEriText":"GSM nw, no ERI",
        "CurrentPhoneType":1,
        "DataNetworkType":13,
        "DeviceId":"869377032908354",
        "DeviceSoftwareVersion":"8693770329083576",
        "EmergencyCallbackMode":false,
        "GroupIdLevel1":"ffffffff",
        "Imei":"869377032908354",
        "Line1AlphaTag":"",
        "Line1Number":"",
        "LteOnCdmaMode":0,
        "Meid":"A000008E9D208E",
        "Msisdn":"",
        "NetworkCountryIso":"cn",
        "NetworkOperator":"46000",
        "NetworkOperatorName":"中国移动",
        "NetworkType":13,
        "SimCountryIso":"cn",
        "SimOperator":"46000",
        "SimOperatorName":"CMCC",
        "SimOperatorNumeric":"46000",
        "SimSerialNumber":"898600831915854xxxxx",
        "SimState":5,
        "SubscriberId":"4600007826xxxxx",
        "VoiceMailAlphaTag":"语音信箱",
        "VoiceMessageCount":0,
        "VoiceNetworkType":13
    },
    {
        "NetworkTypeName":"GPRS",
        "PhoneId":1,
        "PhoneType":1,
        "PhoneTypeFromNetworkType":0,
        "PhoneTypeFromProperty":2,
        "SubId":1,
        "CallState":0,
        "CdmaEriIconIndex":1,
        "CdmaEriIconMode":0,
        "CdmaEriText":"漫游指示符正在闪烁",
        "CurrentPhoneType":2,
        "DataNetworkType":13,
        "DeviceId":"A000008E9D208E",
        "DeviceSoftwareVersion":"8693770329822076",
        "EmergencyCallbackMode":false,
        "GroupIdLevel1":"ffffffff",
        "Imei":"869377032982201",
        "Line1Number":"",
        "LteOnCdmaMode":0,
        "Meid":"A000008E9D208E",
        "Msisdn":"",
        "Nai":"460031250956445@mycdma.cn",
        "NetworkCountryIso":"cn",
        "NetworkOperator":"46011",
        "NetworkOperatorName":"中国电信",
        "NetworkType":13,
        "SimCountryIso":"cn",
        "SimOperator":"46011",
        "SimOperatorName":"中国电信",
        "SimOperatorNumeric":"46011",
        "SimSerialNumber":"898603189502004xxxxx",
        "SimState":5,
        "SubscriberId":"4600312509xxxxx",
        "VoiceMailAlphaTag":"语音信箱",
        "VoiceMailNumber":"*86",
        "VoiceMessageCount":0,
        "VoiceNetworkType":7
    }
]

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值