问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Android开发:高效获取IMSI值的技巧分享

创作时间:
作者:
@小白创作中心

Android开发:高效获取IMSI值的技巧分享

引用
CSDN
9
来源
1.
https://blog.csdn.net/ansondroider/article/details/128975045
2.
https://blog.csdn.net/wszzr999/article/details/125312220
3.
https://blog.csdn.net/qq85469769/article/details/75066668
4.
https://www.jianshu.com/p/1269e4ba99c9
5.
https://blog.csdn.net/u010429219/article/details/75112800
6.
https://www.cnblogs.com/linjiqin/archive/2011/02/26/1965682.html
7.
https://www.coolmuster.cn/phone-transfer/clone-sim-card.html
8.
https://open.oppomobile.com/new/developmentDoc/info?id=10724
9.
https://www.cnblogs.com/xgjblog/p/6212189.html

在Android开发中,获取设备的IMSI(国际移动用户识别码)是许多应用场景中的基本需求,比如设备管理、用户身份验证等。本文将深入探讨如何在Android系统中高效、安全地获取IMSI信息,并提供详细的代码示例和实战技巧。

01

获取IMSI的基本方法

单卡设备

在单卡设备上,获取IMSI相对简单。你可以直接使用TelephonyManagergetSubscriberId()方法:

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String imsi = telephonyManager.getSubscriberId();

双卡设备

双卡设备需要根据卡槽ID来获取IMSI。Android 5.0(API级别21)及以上版本可以通过SubscriptionManager来实现:

SubscriptionManager subscriptionManager = SubscriptionManager.from(this);
List<SubscriptionInfo> subscriptionInfoList = subscriptionManager.getActiveSubscriptionInfoList();

if (subscriptionInfoList != null) {
    for (SubscriptionInfo subscriptionInfo : subscriptionInfoList) {
        int slotIndex = subscriptionInfo.getSimSlotIndex();
        String imsi = subscriptionInfo.getIccId();
        Log.d("IMSI", "Slot " + slotIndex + ": " + imsi);
    }
}

对于Android 5.0以下的版本,可能需要使用反射机制:

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
try {
    Method getSubscriberId = telephonyManager.getClass().getMethod("getSubscriberId", int.class);
    String imsiSlot0 = (String) getSubscriberId.invoke(telephonyManager, 0);
    String imsiSlot1 = (String) getSubscriberId.invoke(telephonyManager, 1);
    Log.d("IMSI", "Slot 0: " + imsiSlot0);
    Log.d("IMSI", "Slot 1: " + imsiSlot1);
} catch (Exception e) {
    e.printStackTrace();
}
02

权限管理

从Android 6.0(API级别23)开始,Google引入了运行时权限模型。这意味着你不能仅仅在AndroidManifest.xml中声明权限,还需要在运行时动态申请。

声明权限

首先需要在AndroidManifest.xml中声明READ_PHONE_STATE权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

动态申请权限

在运行时检查并申请权限:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
        != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.READ_PHONE_STATE},
            MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);
}

处理权限结果

重写onRequestPermissionsResult方法来处理用户响应:

@Override
public void onRequestPermissionsResult(int requestCode,
        String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_PHONE_STATE: {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission was granted
            } else {
                // Permission denied
            }
            return;
        }
    }
}
03

兼容性处理

Android 11及更高版本

从Android 11开始,系统对设备标识符的访问进行了更严格的限制。你需要确保你的应用满足以下条件之一:

  • 应用具有READ_PRIVILEGED_PHONE_STATE权限(仅限系统应用)
  • 用户已将应用设置为设备的默认短信应用
  • 应用已获得用户通过Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION授予的存储访问权限

旧版本兼容

为了兼容旧版本,你可以在代码中添加版本检查:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
    // Use SubscriptionManager for API 22+
} else {
    // Use reflection for older versions
}
04

最佳实践

  1. 最小权限原则:只申请必要的权限,避免过度获取用户隐私信息。

  2. 透明度:在请求权限时,清晰地向用户解释为什么需要这个权限。

  3. 用户选择:尊重用户的决定,如果用户拒绝权限,应该提供合理的替代方案。

  4. 隐私保护:妥善处理获取到的IMSI信息,遵守相关隐私法规。

通过以上方法和注意事项,你可以在Android应用中安全、高效地获取IMSI信息。记住,随着Android系统的不断更新,权限管理越来越严格,因此在开发时一定要充分考虑权限和兼容性问题。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号