Using SubscriptionManager for fetching sim details, but for few users subscriptionManager.getActiveSubscriptionInfoList() is returning null(READ_PHONE_STATE permission is granted), even if sim is present in the device.
val subscriptionManager: SubscriptionManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
val subscriptionInfos = subscriptionManager.getActiveSubscriptionInfoList();
Is there any other way to fetch sim details?
Related
I have to check if the user is using same sim card, if not i have to logout, like google pay.
Now iam using
SubscriptionManager localSubscriptionManager = SubscriptionManager.from(this);
List<SubscriptionInfo> localList = localSubscriptionManager.getActiveSubscriptionInfoList();
SubscriptionInfo info = (SubscriptionInfo) localList.get(0);
info.getIccId()
this code to get the iccid
but it is returning empty string in some devices.
is there any solution for this?
can any one suggest an alternate methode to the same result.
Note: Phone state permission are granted
Thank you
I didn't get a unique ID, But using Subscription Id from SubscriptionInfo.
I have a use case where I need to check whether a SIM is active in the device. In older devices, I can use TelephonyManager to get the SIM state and check whether it is SIM_STATE_READY. The issue is with API 22 and above.
Using SubscriptionManager, when I call getActiveSubscriptionInfoList, it sends me details about the SIMs present, even if I have turned them off. I went through the documentation of SubscriptionManager but couldn't find a similar method to check SIM's state. Using TelephonyManager in API above 22 gives information only about the default SIM, I would like to know this about both slots in dual SIM phones. Also, I found an overloaded variant of getSimState in TelephonyManager which does accept the slot as a parameter, but that got introduced in API 26. I would like a solution that will work in APIs 22-25 as well.
Is there a way I could identify that even though the SIM is present in the device, it isn't active?
You can check by like this if Device is dual sim
SubscriptionManager sManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
SubscriptionInfo infoSim1 = sManager.getActiveSubscriptionInfoForSimSlotIndex(0);
SubscriptionInfo infoSim2 = sManager.getActiveSubscriptionInfoForSimSlotIndex(1);
int count = 0;
if (infoSim1 != null ) {
count++;
}
if (infoSim2 != null){
count++;
}
count decides that how many sims are active.
OR
You can get the count then check one by one
sManager.getActiveSubscriptionInfoCount()
Hope it's work.
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if (manager.getPhoneCount() == 2) {
// Dual sim
}
Examples here
As announced for Lollipop MR1, SubscriptionManager and its SubscriptionInfo provide lots of information about all (active) SIMs, but I'm missing their IMEIs.
I get info about SIMs like this:
SubscriptionManager sm = SubscriptionManager.from(context);
List<SubscriptionInfo> sil = sm.getActiveSubscriptionInfoList();
if (sil != null) {
for (SubscriptionInfo subInfo : sil) {
Log.d(TAG, "SubInfo:" + subInfo);
}
} else {
Log.d(TAG, "SubInfo: list is null");
}
Am I missing something or can we still only get the IMEI (only of the 1st SIM card) via telephonyManager.getDeviceId()?
The method
public String getDeviceId(int slotId)
is available under TelephonyManager in API 23. slotId is just a number from 0 to the number of SIMs - 1.
In API 22, the same method exists but is hidden. You need to use reflection to call it.
The IMEI is used to identify the device, not the SIMs.So yes, you can only get the IMEI through telephonyManager.getDeviceId().
UPDATE: So it turns out I was wrong and a device can have an IMEI for each SIM card. I've found this answer in StackOverflow that can help you.
Android : Check whether the phone is dual SIM
I am using below code to get the IMEI of the Android devices,
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
IMEI = tm.getDeviceId();
It is fine for the devices having a single sim active. If we apply the same code for the devices having two sim cards, then how can I get the DeviceID and tell whether I got SIM1 Id or SIM2 Id?
IMEI number should be associated with the phone and not with the sim, so also in dual sim devices you should have only one IMEI number.
"The IMEI is only used for identifying the device" [...] "Instead, the subscriber is identified by transmission of an IMSI number, which is stored on a SIM card" - ref: Wikipedia
EDIT:
Check the source code, maybe you can find some hint: Source of Settings app
Here a snippet of the "IMEI" part:
// NOTE "imei" is the "Device ID" since it represents
// the IMEI in GSM and the MEID in CDMA
if (mPhone.getPhoneName().equals("CDMA")) {
setSummaryText(KEY_MEID_NUMBER, mPhone.getMeid());
setSummaryText(KEY_MIN_NUMBER, mPhone.getCdmaMin());
if (getResources().getBoolean(R.bool.config_msid_enable)) {
findPreference(KEY_MIN_NUMBER).setTitle(R.string.status_msid_number);
}
setSummaryText(KEY_PRL_VERSION, mPhone.getCdmaPrlVersion());
removePreferenceFromScreen(KEY_IMEI_SV);
if (mPhone.getLteOnCdmaMode() == PhoneConstants.LTE_ON_CDMA_TRUE) {
// Show ICC ID and IMEI for LTE device
setSummaryText(KEY_ICC_ID, mPhone.getIccSerialNumber());
setSummaryText(KEY_IMEI, mPhone.getImei());
} else {
// device is not GSM/UMTS, do not display GSM/UMTS features
// check Null in case no specified preference in overlay xml
removePreferenceFromScreen(KEY_IMEI);
removePreferenceFromScreen(KEY_ICC_ID);
}
} else {
setSummaryText(KEY_IMEI, mPhone.getDeviceId());
setSummaryText(KEY_IMEI_SV,
((TelephonyManager) getSystemService(TELEPHONY_SERVICE))
.getDeviceSoftwareVersion());
// device is not CDMA, do not display CDMA features
// check Null in case no specified preference in overlay xml
removePreferenceFromScreen(KEY_PRL_VERSION);
removePreferenceFromScreen(KEY_MEID_NUMBER);
removePreferenceFromScreen(KEY_MIN_NUMBER);
removePreferenceFromScreen(KEY_ICC_ID);
// only show area info when SIM country is Brazil
if ("br".equals(mTelephonyManager.getSimCountryIso())) {
mShowLatestAreaInfo = true;
}
}
In Dual Sim Devices, they have two IMEI Numbers for each SIM Slots. both are static. First IMEI No. is for First Slot and Second No. is for Second Slot.
How can I get the ICCID number of the phone?
I looked in the TelephonyManager class, but didn't found there a way to get the ICCID number, there is only a method which tells if the ICC card is present.
I believe getSimSerialNumber() will get iccid.
UPDATE for Android 5.1 (credit Erick M Sprengel)
"Multiple SIM Card Support" was added for Android 5.1 (API 22).
Instead of using getSimSerialNumber, you can use SubscriptionManager.
SubscriptionManager sm = SubscriptionManager.from(mContext);
// it returns a list with a SubscriptionInfo instance for each simcard
// there is other methods to retrieve SubscriptionInfos (see [2])
List<SubscriptionInfo> sis = sm.getActiveSubscriptionInfoList();
// getting first SubscriptionInfo
SubscriptionInfo si = sis.get(0);
// getting iccId
String iccId = si.getIccId();
You will need the permission: (credit Damian)
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
It's best not to use this, as this is one of the identifiers that recently got restricted, just as was done recently on Android 10.
On Android 11 (API 30), even if you don't target it, you will most likely get just an empty string.
The recommendation of what to use is getSubscriptionId instead (requires READ_PHONE_STATE permission).
The reason:
Returns the ICC ID. Starting with API level 30, returns the ICC ID if
the calling app has been granted the READ_PRIVILEGED_PHONE_STATE
permission, has carrier privileges (see
TelephonyManager#hasCarrierPrivileges), or is a device owner or
profile owner that has been granted the READ_PHONE_STATE permission.
The profile owner is an app that owns a managed profile on the device;
for more details see Work profiles. Profile owner access is deprecated
and will be removed in a future release.
so it returns "the ICC ID, or an empty string if one of these requirements is not met" . For third party apps, this means you will probably always get an empty string.
If you don't meet these (and you usually don't), you can use it.
final SubscriptionManager subscriptionManager = SubscriptionManager.from(context);
final List<SubscriptionInfo> activeSubscriptionInfoList = subscriptionManager.getActiveSubscriptionInfoList();
And then for each of them, you can use subscriptionInfo.getIccId() .
#Jakar, thank you very much! Here's the same code in C# using Xamarin / Mono.Android
Requires the permission set in your AndroidManifest.xml
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Simple C#
using System.Collections.Generic;
using Android.Telephony;
// ...
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Requires, android.permission.READ_PHONE_STATE
SubscriptionManager sm = Android.Telephony.SubscriptionManager.From(Android.App.Application.Context);
IList<SubscriptionInfo> sis = sm.ActiveSubscriptionInfoList;
SubscriptionInfo si = sis[0];
string carrier = si.CarrierName;
string iccId = si.IccId;
string phoneNum = si.Number;
System.Diagnostics.Debug.WriteLine("Carrier: " + carrier);
System.Diagnostics.Debug.WriteLine("SIM Card IccId: " + iccId);
System.Diagnostics.Debug.WriteLine("Phone Number: " + phoneNum);
// Bonus, Get the IMEI Id (aka, DeviceId)
TelephonyManager tm = (TelephonyManager)GetSystemService(Android.Content.Context.TelephonyService);
string deviceId = tm.DeviceId;
System.Diagnostics.Debug.WriteLine("Device Id: " + deviceId);
}
Both SubscriptionManager and SubscriptionInfo are found under the Android.Telephony namespace
Truth be told this example was needed to activate my phone on the fly and not having the SIM card tool handy to pull it out. And, my eyes aren't what they use to be. View it on DroidTelephonySimInfo.cs on gist.github.com