From bd58d8a05a17d8db668538f7588e4746b115d512 Mon Sep 17 00:00:00 2001 From: pppscn <35696959@qq.com> Date: Thu, 11 Mar 2021 14:07:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=8E=B7=E5=8F=96SIM?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=EF=BC=88=E5=85=BC=E5=AE=B9=E9=AB=98=E7=89=88?= =?UTF-8?q?=E6=9C=ACAndroid=EF=BC=89=20&=20=E8=87=AA=E5=8A=A8=E5=A1=AB?= =?UTF-8?q?=E5=86=99=E8=AE=BE=E5=A4=87=E5=A4=87=E6=B3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 30 +- .../SmsForwarderBroadcastReceiver.java | 16 +- .../idormy/sms/forwarder/MainActivity.java | 25 +- .../idormy/sms/forwarder/MyApplication.java | 9 +- .../sms/forwarder/utils/PhoneUtils.java | 597 ++++++++++++++++++ .../sms/forwarder/utils/SettingUtil.java | 11 +- .../idormy/sms/forwarder/utils/SimUtil.java | 68 +- 7 files changed, 647 insertions(+), 109 deletions(-) create mode 100644 app/src/main/java/com/idormy/sms/forwarder/utils/PhoneUtils.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0a998f4a..9bed9a2c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,24 @@ + + + + + + + + + + + + + + - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/SmsForwarderBroadcastReceiver.java b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/SmsForwarderBroadcastReceiver.java index 12a78044..90d1f631 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/SmsForwarderBroadcastReceiver.java +++ b/app/src/main/java/com/idormy/sms/forwarder/BroadCastReceiver/SmsForwarderBroadcastReceiver.java @@ -7,7 +7,6 @@ import android.os.Bundle; import android.telephony.SmsMessage; import android.util.Log; -import com.idormy.sms.forwarder.MyApplication; import com.idormy.sms.forwarder.model.vo.SmsVo; import com.idormy.sms.forwarder.sender.SendUtil; import com.idormy.sms.forwarder.utils.SettingUtil; @@ -32,6 +31,8 @@ public class SmsForwarderBroadcastReceiver extends BroadcastReceiver { try { Bundle extras = intent.getExtras(); + Log.d(TAG, "subscription = " + extras.getInt("subscription")); + Log.d(TAG, "simId = " + extras.getInt("simId")); Object[] object = (Object[]) Objects.requireNonNull(extras).get("pdus"); if (object != null) { @@ -39,15 +40,12 @@ public class SmsForwarderBroadcastReceiver extends BroadcastReceiver { String simInfo = ""; try { //获取卡槽ID - String simInfoId = String.valueOf(SimUtil.getSimId(extras)); - Map sim = MyApplication.SimInfo.get(simInfoId); - int sim_id = Integer.parseInt(sim.get("sim_id")) + 1; - - simInfo = sim_id == 2 ? SettingUtil.getAddExtraSim2() : SettingUtil.getAddExtraSim1(); - if (!simInfo.isEmpty()) { - simInfo = "SIM" + sim_id + "_" + simInfo; + int simId = SimUtil.getSimId(extras); + simInfo = simId == 2 ? SettingUtil.getAddExtraSim2() : SettingUtil.getAddExtraSim1(); + if (!simInfo.isEmpty()) { //自定义备注优先 + simInfo = "SIM" + simId + "_" + simInfo; } else { - simInfo = "SIM" + sim_id + "_" + sim.get("carrier_name") + "_" + sim.get("phone_number"); + simInfo = SimUtil.getSimInfo(simId); } } catch (Exception e) { Log.e(TAG, "获取接收手机号失败:" + e.getMessage()); diff --git a/app/src/main/java/com/idormy/sms/forwarder/MainActivity.java b/app/src/main/java/com/idormy/sms/forwarder/MainActivity.java index aced9dc6..2029ab3e 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/MainActivity.java +++ b/app/src/main/java/com/idormy/sms/forwarder/MainActivity.java @@ -1,14 +1,12 @@ package com.idormy.sms.forwarder; import android.Manifest; -import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; -import android.telephony.TelephonyManager; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; @@ -26,7 +24,7 @@ import com.idormy.sms.forwarder.BroadCastReceiver.SmsForwarderBroadcastReceiver; import com.idormy.sms.forwarder.adapter.LogAdapter; import com.idormy.sms.forwarder.model.vo.LogVo; import com.idormy.sms.forwarder.utils.LogUtil; -import com.idormy.sms.forwarder.utils.SimUtil; +import com.idormy.sms.forwarder.utils.PhoneUtils; import com.idormy.sms.forwarder.utils.aUtil; import com.umeng.analytics.MobclickAgent; @@ -45,29 +43,20 @@ public class MainActivity extends AppCompatActivity implements ReFlashListView.I @Override protected void onCreate(Bundle savedInstanceState) { + LogUtil.init(this); Log.d(TAG, "oncreate"); + super.onCreate(savedInstanceState); //检查权限是否获取 checkPermission(); - //获取本机号码(注意:这里获取的不一定是卡槽1的) - String Line1Number = ""; - try { - TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); - Line1Number = mTelephonyMgr.getLine1Number(); - Log.d(TAG, "Line1Number: " + Line1Number); - } catch (Exception e) { - Log.e(TAG, "getLine1Number fail:" + e.getMessage()); - Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show(); - } - - //获取SIM卡信息 - MyApplication appContext = ((MyApplication) getApplicationContext()); - SimUtil.getSimInfo(appContext, Line1Number); + //获取SIM信息 + PhoneUtils.init(this); + MyApplication.SimInfoList = PhoneUtils.getSimMultiInfo(); + Log.d(TAG, "SimInfoList = " + MyApplication.SimInfoList); setContentView(R.layout.activity_main); - LogUtil.init(this); } @Override diff --git a/app/src/main/java/com/idormy/sms/forwarder/MyApplication.java b/app/src/main/java/com/idormy/sms/forwarder/MyApplication.java index 2641f0db..64fd03c9 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/MyApplication.java +++ b/app/src/main/java/com/idormy/sms/forwarder/MyApplication.java @@ -12,18 +12,19 @@ import android.util.Log; import com.idormy.sms.forwarder.sender.SendHistory; import com.idormy.sms.forwarder.utils.Define; +import com.idormy.sms.forwarder.utils.PhoneUtils; import com.idormy.sms.forwarder.utils.SettingUtil; import com.smailnet.emailkit.EmailKit; import com.umeng.analytics.MobclickAgent; import com.umeng.commonsdk.UMConfigure; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; public class MyApplication extends Application { private static final String TAG = "MyApplication"; //SIM卡信息 - public static Map SimInfo = new HashMap(); + public static List SimInfoList = new ArrayList<>(); //是否关闭页面提示 public static boolean showHelpTip = true; //企业微信 @@ -97,7 +98,5 @@ public class MyApplication extends Application { SharedPreferences sp = MyApplication.this.getSharedPreferences(Define.SP_CONFIG, Context.MODE_PRIVATE); showHelpTip = sp.getBoolean(Define.SP_CONFIG_SWITCH_HELP_TIP, true); - String jsonSimInfo = sp.getString(Define.SP_CONFIG_SIM_INFO, ""); - } } diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/PhoneUtils.java b/app/src/main/java/com/idormy/sms/forwarder/utils/PhoneUtils.java new file mode 100644 index 00000000..728135f3 --- /dev/null +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/PhoneUtils.java @@ -0,0 +1,597 @@ +package com.idormy.sms.forwarder.utils; + +import android.Manifest; +import android.annotation.SuppressLint; +import android.content.ContentResolver; +import android.content.Context; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.provider.Settings; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; +import android.text.TextUtils; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.app.ActivityCompat; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +public class PhoneUtils { + static Boolean hasInit = false; + static Context context; + private static String TAG = "PhoneUtils"; + + /** + * 构造类 + */ + private PhoneUtils() { + throw new UnsupportedOperationException("u can't instantiate me..."); + } + + public static void init(Context context1) { + synchronized (hasInit) { + if (hasInit) return; + hasInit = true; + context = context1; + } + } + + /** + * 判断设备是否是手机 + * + * @return {@code true}: 是
{@code false}: 否 + */ + public static boolean isPhone() { + TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + return tm != null && tm.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE; + } + + /** + * 判断设备是否root + * + * @return the boolean{@code true}: 是
{@code false}: 否 + */ + public static boolean isDeviceRoot() { + String su = "su"; + String[] locations = {"/system/bin/", "/system/xbin/", "/sbin/", "/system/sd/xbin/", "/system/bin/failsafe/", + "/data/local/xbin/", "/data/local/bin/", "/data/local/"}; + for (String location : locations) { + if (new File(location + su).exists()) { + return true; + } + } + return false; + } + + /** + * 获取设备系统版本号 + * + * @return 设备系统版本号 + */ + public static int getSDKVersion() { + return android.os.Build.VERSION.SDK_INT; + } + + /** + * 获取设备AndroidID + * + * @return AndroidID + */ + @SuppressLint("HardwareIds") + public static String getAndroidID() { + return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID); + } + + /** + * 获取IMEI码 + *

需添加权限 {@code }

+ * + * @return IMEI码 + */ + @SuppressLint("HardwareIds") + public static String getIMEI() { + TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + try { + return tm != null ? tm.getDeviceId() : null; + } catch (Exception ignored) { + + } + return getUniquePsuedoID(); + } + + /** + * 通过读取设备的ROM版本号、厂商名、CPU型号和其他硬件信息来组合出一串15位的号码 + * 其中“Build.SERIAL”这个属性来保证ID的独一无二,当API < 9 无法读取时,使用AndroidId + * + * @return 伪唯一ID + */ + public static String getUniquePsuedoID() { + String m_szDevIDShort = "35" + + Build.BOARD.length() % 10 + Build.BRAND.length() % 10 + + Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 + + Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 + + Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 + + Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 + + Build.TAGS.length() % 10 + Build.TYPE.length() % 10 + + Build.USER.length() % 10; + + String serial; + try { + serial = android.os.Build.class.getField("SERIAL").get(null).toString(); + return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString(); + } catch (Exception e) { + //获取失败,使用AndroidId + serial = getAndroidID(); + if (TextUtils.isEmpty(serial)) { + serial = "serial"; + } + } + + return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString(); + } + + /** + * 获取IMSI码 + *

需添加权限 {@code }

+ * + * @return IMSI码 + */ + @SuppressLint("HardwareIds") + public static String getIMSI() { + TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + try { + return tm != null ? tm.getSubscriberId() : null; + } catch (Exception ignored) { + } + return null; + } + + /** + * 判断sim卡是否准备好 + * + * @return {@code true}: 是
{@code false}: 否 + */ + public static boolean isSimCardReady() { + TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + return tm != null && tm.getSimState() == TelephonyManager.SIM_STATE_READY; + } + + /** + * 获取Sim卡运营商名称 + *

中国移动、如中国联通、中国电信

+ * + * @return sim卡运营商名称 + */ + public static String getSimOperatorName() { + TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + return tm != null ? tm.getSimOperatorName() : null; + } + + /** + * 获取Sim卡运营商名称 + *

中国移动、如中国联通、中国电信

+ * + * @return 移动网络运营商名称 + */ + public static String getSimOperatorByMnc() { + TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + String operator = tm != null ? tm.getSimOperator() : null; + if (operator == null) { + return null; + } + switch (operator) { + case "46000": + case "46002": + case "46007": + return "中国移动"; + case "46001": + return "中国联通"; + case "46003": + return "中国电信"; + default: + return operator; + } + } + + /** + * 获取Sim卡序列号 + *

+ * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * + * @return 序列号 + */ + public static String getSimSerialNumber() { + try { + TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + String serialNumber = tm != null ? tm.getSimSerialNumber() : null; + + return serialNumber != null ? serialNumber : ""; + } catch (Exception e) { + } + + return ""; + } + + /** + * 获取Sim卡的国家代码 + * + * @return 国家代码 + */ + public static String getSimCountryIso() { + TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + return tm != null ? tm.getSimCountryIso() : null; + } + + /** + * 读取电话号码 + *

+ * Requires Permission: + * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * OR + * {@link android.Manifest.permission#READ_SMS} + *

+ * + * @return 电话号码 + */ + @SuppressLint("MissingPermission") + public static String getPhoneNumber() { + TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + try { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_NUMBERS) != PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + return null; + } + return tm != null ? tm.getLine1Number() : null; + } catch (Exception ignored) { + } + return null; + } + + /** + * 获得卡槽数,默认为1 + * + * @return 返回卡槽数 + */ + public static int getSimCount() { + int count = 1; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { + try { + SubscriptionManager mSubscriptionManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); + if (mSubscriptionManager != null) { + count = mSubscriptionManager.getActiveSubscriptionInfoCountMax(); + return count; + } + } catch (Exception ignored) { + } + } + try { + count = Integer.parseInt(getReflexMethod(context, "getPhoneCount")); + } catch (MethodNotFoundException ignored) { + } + return count; + } + + /** + * 获取Sim卡使用的数量 + * + * @return 0, 1, 2 + */ + public static int getSimUsedCount() { + int count = 0; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { + try { + SubscriptionManager mSubscriptionManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + return count; + } + count = mSubscriptionManager.getActiveSubscriptionInfoCount(); + return count; + } catch (Exception ignored) { + } + } + + TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + if (tm.getSimState() == TelephonyManager.SIM_STATE_READY) { + count = 1; + } + try { + if (Integer.parseInt(getReflexMethodWithId(context, "getSimState", "1")) == TelephonyManager.SIM_STATE_READY) { + count = 2; + } + } catch (MethodNotFoundException ignored) { + } + return count; + } + + /** + * 获取多卡信息 + * + * @return 多Sim卡的具体信息 + */ + public static List getSimMultiInfo() { + List infos = new ArrayList<>(); + Log.d(TAG, "Build.VERSION.SDK_INT = " + Build.VERSION.SDK_INT); + Log.d(TAG, "Build.VERSION_CODES.LOLLIPOP_MR1 = " + Build.VERSION_CODES.LOLLIPOP_MR1); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { + //1.版本超过5.1,调用系统方法 + SubscriptionManager mSubscriptionManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); + List activeSubscriptionInfoList = null; + if (mSubscriptionManager != null) { + try { + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { + //TODO + } + activeSubscriptionInfoList = mSubscriptionManager.getActiveSubscriptionInfoList(); + } catch (Exception ignored) { + } + } + if (activeSubscriptionInfoList != null && activeSubscriptionInfoList.size() > 0) { + //1.1.1 有使用的卡,就遍历所有卡 + for (SubscriptionInfo subscriptionInfo : activeSubscriptionInfoList) { + SimInfo simInfo = new SimInfo(); + simInfo.mCarrierName = subscriptionInfo.getCarrierName(); + simInfo.mIccId = subscriptionInfo.getIccId(); + simInfo.mSimSlotIndex = subscriptionInfo.getSimSlotIndex(); + simInfo.mNumber = subscriptionInfo.getNumber(); + simInfo.mCountryIso = subscriptionInfo.getCountryIso(); + simInfo.mSubscriptionId = subscriptionInfo.getSubscriptionId(); + try { + simInfo.mImei = getReflexMethodWithId(context, "getDeviceId", String.valueOf(simInfo.mSimSlotIndex)); + simInfo.mImsi = getReflexMethodWithId(context, "getSubscriberId", String.valueOf(subscriptionInfo.getSubscriptionId())); + } catch (MethodNotFoundException ignored) { + } + infos.add(simInfo); + } + } + } else { + //2.版本低于5.1的系统,首先调用数据库,看能不能访问到 + Uri uri = Uri.parse("content://telephony/siminfo"); //访问raw_contacts表 + ContentResolver resolver = context.getContentResolver(); + Cursor cursor = resolver.query(uri, new String[]{"_id", "icc_id", "sim_id", "display_name", "carrier_name", "name_source", "color", "number", "display_number_format", "data_roaming", "mcc", "mnc"}, null, null, null); + if (cursor != null) { + while (cursor.moveToNext()) { + SimInfo simInfo = new SimInfo(); + simInfo.mCarrierName = cursor.getString(cursor.getColumnIndex("carrier_name")); + simInfo.mIccId = cursor.getString(cursor.getColumnIndex("icc_id")); + simInfo.mSimSlotIndex = cursor.getInt(cursor.getColumnIndex("sim_id")); + simInfo.mNumber = cursor.getString(cursor.getColumnIndex("number")); + simInfo.mCountryIso = cursor.getString(cursor.getColumnIndex("mcc")); + String id = cursor.getString(cursor.getColumnIndex("_id")); + + try { + simInfo.mImei = getReflexMethodWithId(context, "getDeviceId", String.valueOf(simInfo.mSimSlotIndex)); + simInfo.mImsi = getReflexMethodWithId(context, "getSubscriberId", String.valueOf(id)); + } catch (MethodNotFoundException ignored) { + } + infos.add(simInfo); + } + cursor.close(); + } + } + + //3.通过反射读取卡槽信息,最后通过IMEI去重 + for (int i = 0; i < getSimCount(); i++) { + infos.add(getReflexSimInfo(context, i)); + } + List simInfos = removeDuplicateWithOrder(infos); + if (simInfos.size() < getSimCount()) { + for (int i = simInfos.size(); i < getSimCount(); i++) { + simInfos.add(new SimInfo()); + } + } + return simInfos; + } + + @Nullable + public static String getSecondIMSI() { + int maxCount = 20; + if (TextUtils.isEmpty(getIMSI())) { + return null; + } + for (int i = 0; i < maxCount; i++) { + String imsi = null; + try { + imsi = getReflexMethodWithId(context, "getSubscriberId", String.valueOf(i)); + } catch (MethodNotFoundException ignored) { + Log.d(TAG, String.valueOf(ignored)); + } + if (!TextUtils.isEmpty(imsi) && !imsi.equals(getIMSI())) { + return imsi; + } + } + return null; + } + + /** + * 通过反射获得SimInfo的信息 + * 当index为0时,读取默认信息 + * + * @param index 位置,用来当subId和phoneId + * @return {@link SimInfo} sim信息 + */ + @NonNull + private static SimInfo getReflexSimInfo(Context context, int index) { + SimInfo simInfo = new SimInfo(); + simInfo.mSimSlotIndex = index; + try { + simInfo.mImei = getReflexMethodWithId(context, "getDeviceId", String.valueOf(simInfo.mSimSlotIndex)); + //slotId,比较准确 + simInfo.mImsi = getReflexMethodWithId(context, "getSubscriberId", String.valueOf(simInfo.mSimSlotIndex)); + //subId,很不准确 + simInfo.mCarrierName = getReflexMethodWithId(context, "getSimOperatorNameForPhone", String.valueOf(simInfo.mSimSlotIndex)); + //PhoneId,基本准确 + simInfo.mCountryIso = getReflexMethodWithId(context, "getSimCountryIso", String.valueOf(simInfo.mSimSlotIndex)); + //subId,很不准确 + simInfo.mIccId = getReflexMethodWithId(context, "getSimSerialNumber", String.valueOf(simInfo.mSimSlotIndex)); + //subId,很不准确 + simInfo.mNumber = getReflexMethodWithId(context, "getLine1Number", String.valueOf(simInfo.mSimSlotIndex)); + //subId,很不准确 + } catch (MethodNotFoundException ignored) { + } + return simInfo; + } + + /** + * 通过反射调取@hide的方法 + * + * @param predictedMethodName 方法名 + * @return 返回方法调用的结果 + * @throws MethodNotFoundException 方法没有找到 + */ + private static String getReflexMethod(Context context, String predictedMethodName) throws MethodNotFoundException { + String result = null; + TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + try { + Class telephonyClass = Class.forName(telephony.getClass().getName()); + Method getSimID = telephonyClass.getMethod(predictedMethodName); + Object ob_phone = getSimID.invoke(telephony); + if (ob_phone != null) { + result = ob_phone.toString(); + } + } catch (Exception e) { + Log.d(TAG, String.valueOf(e.fillInStackTrace())); + throw new MethodNotFoundException(predictedMethodName); + } + return result; + } + + /** + * 通过反射调取@hide的方法 + * + * @param predictedMethodName 方法名 + * @param id 参数 + * @return 返回方法调用的结果 + * @throws MethodNotFoundException 方法没有找到 + */ + private static String getReflexMethodWithId(Context context, String predictedMethodName, String id) throws MethodNotFoundException { + String result = null; + TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + try { + Class telephonyClass = Class.forName(telephony.getClass().getName()); + Class[] parameter = new Class[1]; + parameter[0] = int.class; + Method getSimID = telephonyClass.getMethod(predictedMethodName, parameter); + Class[] parameterTypes = getSimID.getParameterTypes(); + Object[] obParameter = new Object[parameterTypes.length]; + if (parameterTypes[0].getSimpleName().equals("int")) { + obParameter[0] = Integer.valueOf(id); + } else if (parameterTypes[0].getSimpleName().equals("long")) { + obParameter[0] = Long.valueOf(id); + } else { + obParameter[0] = id; + } + Object ob_phone = getSimID.invoke(telephony, obParameter); + if (ob_phone != null) { + result = ob_phone.toString(); + } + } catch (Exception e) { + Log.d(TAG, String.valueOf(e.fillInStackTrace())); + throw new MethodNotFoundException(predictedMethodName); + } + return result; + } + + // 删除ArrayList中重复元素,保持顺序 + public static List removeDuplicateWithOrder(List list) { + Set set = new HashSet(); + List newList = new ArrayList(); + for (Iterator iter = list.iterator(); iter.hasNext(); ) { + Object element = iter.next(); + if (set.add(element)) + newList.add(element); + } + list.clear(); + list.addAll(newList); + return list; + } + + /** + * SIM 卡信息 + */ + public static class SimInfo { + /** + * 运营商信息:中国移动 中国联通 中国电信 + */ + public CharSequence mCarrierName; + /** + * 卡槽ID,SimSerialNumber + */ + public CharSequence mIccId; + /** + * 卡槽id, -1 - 没插入、 0 - 卡槽1 、1 - 卡槽2 + */ + public int mSimSlotIndex; + /** + * 号码 + */ + public CharSequence mNumber; + /** + * 城市 + */ + public CharSequence mCountryIso; + /** + * 设备唯一识别码 + */ + public CharSequence mImei = getIMEI(); + /** + * SIM的编号 + */ + public CharSequence mImsi; + /** + * SIM的 Subscription Id (SIM插入顺序) + */ + public int mSubscriptionId; + + /** + * 通过 IMEI 判断是否相等 + * + * @param obj + * @return + */ + @Override + public boolean equals(Object obj) { + return obj != null && obj instanceof SimInfo && (TextUtils.isEmpty(((SimInfo) obj).mImei) || ((SimInfo) obj).mImei.equals(mImei)); + } + + @Override + public String toString() { + return "SimInfo{" + + "mCarrierName=" + mCarrierName + + ", mIccId=" + mIccId + + ", mSimSlotIndex=" + mSimSlotIndex + + ", mNumber=" + mNumber + + ", mCountryIso=" + mCountryIso + + ", mImei=" + mImei + + ", mImsi=" + mImsi + + ", mSubscriptionId=" + mSubscriptionId + + '}'; + } + } + + /** + * 反射未找到方法 + */ + private static class MethodNotFoundException extends Exception { + + public static final long serialVersionUID = -3241033488141442594L; + + MethodNotFoundException(String info) { + super(info); + } + } + +} diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java index b25b2101..7d55ed4a 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SettingUtil.java @@ -44,7 +44,11 @@ public class SettingUtil { } public static String getAddExtraDeviceMark() { - return sp_setting.getString(Define.SP_MSG_KEY_STRING_ADD_EXTRA_DEVICE_MARK, ""); + String res = sp_setting.getString(Define.SP_MSG_KEY_STRING_ADD_EXTRA_DEVICE_MARK, ""); + if (res == null || res.equals("")) { + res = android.os.Build.MODEL; + } + return res; } public static void setAddExtraDeviceMark(String addExtraDeviceMark) { @@ -67,9 +71,8 @@ public class SettingUtil { public static String getAddExtraSim1() { String res = sp_setting.getString(Define.SP_MSG_KEY_STRING_ADD_EXTRA_SIM1, ""); - Log.d(TAG, "res=" + res); if (res == null || res.equals("")) { - res = SimUtil.getSimExtra(1); + res = SimUtil.getSimInfo(1); } return res; } @@ -84,7 +87,7 @@ public class SettingUtil { public static String getAddExtraSim2() { String res = sp_setting.getString(Define.SP_MSG_KEY_STRING_ADD_EXTRA_SIM2, ""); if (res == null || res.equals("")) { - res = SimUtil.getSimExtra(2); + res = SimUtil.getSimInfo(2); } return res; } diff --git a/app/src/main/java/com/idormy/sms/forwarder/utils/SimUtil.java b/app/src/main/java/com/idormy/sms/forwarder/utils/SimUtil.java index dcbe131e..613242b0 100644 --- a/app/src/main/java/com/idormy/sms/forwarder/utils/SimUtil.java +++ b/app/src/main/java/com/idormy/sms/forwarder/utils/SimUtil.java @@ -1,35 +1,18 @@ package com.idormy.sms.forwarder.utils; -import android.content.ContentResolver; -import android.database.Cursor; -import android.net.Uri; import android.os.Bundle; import android.util.Log; import com.idormy.sms.forwarder.MyApplication; -import java.util.HashMap; -import java.util.Map; - public class SimUtil { private static String TAG = "SimUtil"; - //获取卡槽ID + //获取卡槽信息ID public static int getSimId(Bundle bundle) { int whichSIM = -1; - if (bundle == null) { - return whichSIM; - } - - if (bundle.containsKey("subscription")) { - whichSIM = bundle.getInt("subscription"); - } - if (whichSIM >= 0 && whichSIM < 5) { - /*In some device Subscription id is return as subscriber id*/ - //TODO:不确定能不能直接返回 - Log.d(TAG, "whichSIM >= 0 && whichSIM < 5:" + whichSIM); - } else { + if (bundle != null) { if (bundle.containsKey("simId")) { whichSIM = bundle.getInt("simId"); } else if (bundle.containsKey("com.android.phone.extra.slot")) { @@ -47,51 +30,16 @@ public class SimUtil { } Log.d(TAG, " Slot Number " + whichSIM); - return whichSIM; - } - - - //获取SIM卡信息 - public static void getSimInfo(MyApplication appContext, String Line1Number) { - try { - Uri uri = Uri.parse("content://telephony/siminfo"); //访问raw_contacts表 - ContentResolver resolver = appContext.getContentResolver(); - Cursor cursor = resolver.query(uri, new String[]{"_id", "icc_id", "sim_id", "display_name", "carrier_name", "name_source", "color", "number", "display_number_format", "data_roaming", "mcc", "mnc"}, "sim_id >= 0", null, "_id"); - if (cursor != null) { - while (cursor.moveToNext()) { - Log.d(TAG, "_id: " + cursor.getString(cursor.getColumnIndex("_id"))); - Log.d(TAG, "sim_id: " + cursor.getString(cursor.getColumnIndex("sim_id"))); - Log.d(TAG, "carrier_name: " + cursor.getString(cursor.getColumnIndex("carrier_name"))); - Log.d(TAG, "display_name: " + cursor.getString(cursor.getColumnIndex("display_name"))); - Map sim = new HashMap(); - String id = cursor.getString(cursor.getColumnIndex("_id")); - sim.put("_id", id); - sim.put("sim_id", cursor.getString(cursor.getColumnIndex("sim_id"))); - sim.put("carrier_name", cursor.getString(cursor.getColumnIndex("carrier_name"))); - sim.put("display_name", cursor.getString(cursor.getColumnIndex("display_name"))); - sim.put("phone_number", Line1Number); - if (Line1Number != "Unknown") { - Line1Number = "Unknown"; - } - MyApplication.SimInfo.put(id, sim); - } - cursor.close(); - } - } catch (Exception e) { - Log.e(TAG, "getSimInfo fail:" + e.getMessage()); - //Toast.makeText(MainActivity.this, "获取SIM卡信息失败:请先手动设置", Toast.LENGTH_LONG).show(); - } + return whichSIM + 1; } //获取卡槽备注 - public static String getSimExtra(int simId) { + public static String getSimInfo(int simId) { String res = ""; try { - for (Map.Entry entry : MyApplication.SimInfo.entrySet()) { - Map sim = entry.getValue(); - int sim_id = Integer.parseInt(sim.get("sim_id")) + 1; - if (sim_id == simId) { - res = sim.get("carrier_name") + "_" + sim.get("phone_number"); + for (PhoneUtils.SimInfo simInfo : MyApplication.SimInfoList) { + if (simInfo.mSimSlotIndex + 1 == simId) { + res = simInfo.mCarrierName + "_" + simInfo.mNumber; break; } } @@ -99,6 +47,6 @@ public class SimUtil { Log.d(TAG, "getSimExtra Fail: " + e.getMessage()); } - return res; + return res.replace("null", "unknown"); } }