I know how to get user's phone number, but let's say the user's phone is dual SIM. Is there any way to get both phone numbers? Currently I am getting the active phone number only.
If the phone number is indeed stored in the SIM card, then you can use subscriptionmanager API (https://developer.android.com/reference/android/telephony/SubscriptionManager.html) to get the details on each subscription i.e for each SIM card.
You can call
getActiveSubscriptionInfoList() which will return list. In your case if there are 2 SIM cards inserted, it should return 2 subscription infos
In subscription info, you can call getNumber() API (https://developer.android.com/reference/android/telephony/SubscriptionInfo.html#getNumber()) to get the number
Please note that for this to work, the SIM card should have the phone number in it.
Please note this API is only supported from API level 22
Adding example code :
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
SubscriptionManager subscriptionManager = SubscriptionManager.from(getApplicationContext());
List<SubscriptionInfo> subsInfoList = subscriptionManager.getActiveSubscriptionInfoList();
Log.d("Test", "Current list = " + subsInfoList);
for (SubscriptionInfo subscriptionInfo : subsInfoList) {
String number = subscriptionInfo.getNumber();
Log.d("Test", " Number is " + number);
}
}
I have Kotlinized #manishg code (from 5 years ago):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
val subscriptionManager = SubscriptionManager.from(applicationContext)
val subsInfoList = subscriptionManager.activeSubscriptionInfoList
Log.d("Test", "Current list = $subsInfoList")
for (subscriptionInfo in subsInfoList) {
val number = subscriptionInfo.number
Log.d("Test", " Number is $number")
}
}
Note #1: you must add to the manifest:
uses-permission android:name="android.permission.READ_PHONE_STATE"
Note #2: you should have a permission check on your code, like:
val subsInfoList = if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
// ActivityCompat#requestPermissions
return
} else {
//todo return "no permissions"
}
Related
I am getting the IMEI ID null from the telephonymanager. What to do?
is there any workaround for that?
Android Q has restricted to access for both IMEI and serial no. It is available only for platform and apps with special carrier permission. Also the permission READ_PRIVILEGED_PHONE_STATE is not available for non platform apps.
If you try to access it throws below exception
java.lang.SecurityException: getImeiForSlot: The user 10180 does not meet the requirements to access device identifiers.
Please refer documentation:
https://developer.android.com/preview/privacy/data-identifiers#device-ids
Also refer Issue
I am late to post answer. I still believe my answer will help someone.
Android 10 Restricted developer to Access IMEI number.
You can have a alternate solution by get Software ID. You can use software id as a unique id. Please find below code as i use in Application.
public static String getDeviceId(Context context) {
String deviceId;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID);
} else {
final TelephonyManager mTelephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
deviceId = mTelephony.getDeviceId();
} else {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID);
}
}
return deviceId;
}
This just would not work as of Android Q. Third party apps can not use IMEI nor the serial number of a phone and other non-resettable device identifiers.
The only permissions that are able to use those is READ_PRIVILEGED_PHONE_STATE and that cannot be used by any third party apps - Manufacture and Software Applications. If you use that method you will get an error Security exception or get null .
You can still try to get a unique id by using:
import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),Secure.ANDROID_ID);
The best way to get the IMEI number is as follows:
public static String getIMEIDeviceId(Context context) {
String deviceId;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
} else {
final TelephonyManager mTelephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (context.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
return "";
}
}
assert mTelephony != null;
if (mTelephony.getDeviceId() != null)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
deviceId = mTelephony.getImei();
}else {
deviceId = mTelephony.getDeviceId();
}
} else {
deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
}
}
Log.d("deviceId", deviceId);
return deviceId;
}
Just copy the method and use it. It will definitely. However, you might know you can't get IMEI in android Q (version 10). In this code, you can get a unique identifier (alternative id) through any device or any API level.
It works 100%
Thank You!!
And Enjoy Coding :)
As the best practices suggest. " you can avoid using hardware identifiers, such as SSAID (Android ID) and IMEI, without limiting required functionality."
Rather go for an instance ID such as String uniqueID = UUID.randomUUID().toString(); or FirebaseInstanceId.getInstance().getId();
Not sure about IMEI number, but you can get the simSerialNumber and other carrier info this way.
getSimSerialNumber() needs privileged permissions from Android 10 onwards, and third party apps can't register this permission.
See : https://developer.android.com/about/versions/10/privacy/changes#non-resettable-device-ids
A possible solution is to use the TELEPHONY_SUBSCRIPTION_SERVICE from Android 5.1, to retrieve the sim serial number. Steps below:
Check for READ_PHONE_STATE permission.
Get Active subscription list.( Returns the list of all active sim cards)
Retrieve the sim details from Subscription Object.
if ( isPermissionGranted(READ_PHONE_STATE) ) {
String simSerialNo="";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
SubscriptionManager subsManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
List<SubscriptionInfo> subsList = subsManager.getActiveSubscriptionInfoList();
if (subsList!=null) {
for (SubscriptionInfo subsInfo : subsList) {
if (subsInfo != null) {
simSerialNo = subsInfo.getIccId();
}
}
}
} else {
TelephonyManager tMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
simSerialNo = tMgr.getSimSerialNumber();
}
}
Check if this helps
you can change other way, i use uuid to replace devices id.
String uniquePseudoID = "35" +
Build.BOARD.length() % 10 +
Build.BRAND.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 = Build.getRadioVersion();
String uuid = new UUID(uniquePseudoID.hashCode(), serial.hashCode()).toString();
AppLog.d("Device ID",uuid);
If your app targets Android 10 or higher, a SecurityException occurs.
Following modules are affected...
Build
getSerial()
TelephonyManager
getImei()
getDeviceId()
getMeid()
getSimSerialNumber()
getSubscriberId()
So you cant get IMEI no for android 10 , You have to used another unique identifier for this like Android ID
It unique 64 bit hex no for device
private String android_id = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
According to google docs.
Restriction on non-resettable device identifiers
Starting in Android 10, apps must have the READ_PRIVILEGED_PHONE_STATE privileged permission in order to access the device's non-resettable identifiers, which include both IMEI and serial number.
Caution: Third-party apps installed from the Google Play Store cannot
declare privileged permissions.
So, Instead of imei you can get Android unique ID.
String imei = "";
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
if (telephonyManager != null) {
try {
imei = telephonyManager.getImei();
} catch (Exception e) {
e.printStackTrace();
imei = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
}
}
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1010);
}
} else {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
if (telephonyManager != null) {
imei = telephonyManager.getDeviceId();
}
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1010);
}
}
Targeting Android Q, third party apps can't access IMEI at all. Android Q doc is misleading while stating
Starting in Android Q, apps must have the READ_PRIVILEGED_PHONE_STATE
privileged permission in order to access the device's non-resettable
identifiers, which include both IMEI and serial number.
https://developer.android.com/preview/privacy/data-identifiers#device-ids
But when I actually tried to implement it, I am receiving this exception:
java.lang.SecurityException: getDeviceId: The user 10132 does not meet the requirements to access device identifiers.
Someone had reported this on google's issue tracker where a Googler said that this is intended behaviour and IMEI on Q+ is only available for system level apps.
Status: Won't Fix (Intended Behavior) This is Working As Intended.
IMEI is a personal identifier and this is not given out to apps as a
matter of policy. There is no workaround.
https://issuetracker.google.com/issues/129583175#comment10
They mentioned:
If your app is the device or profile owner app, you need only the READ_PHONE_STATE permission to access non-resettable device identifiers, even if your app targets Android 10 or higher.
I tried deploying via EMM as device owner app but not success.
If you needed, you can try to install a work profile in to the mobile phone and include your app in the same package or vice versa.
I tried and it works, it's simple if yo follow this repo: https://github.com/googlesamples/android-testdpc
When you install the Work Profile your app is installed in this profile and you will have acces to the IMEI.
And now there is another example fixed yesterday to Android 10:
https://github.com/android/enterprise-samples/pull/29
I am getting the IMEI ID null from the telephonymanager. What to do?
is there any workaround for that?
Android Q has restricted to access for both IMEI and serial no. It is available only for platform and apps with special carrier permission. Also the permission READ_PRIVILEGED_PHONE_STATE is not available for non platform apps.
If you try to access it throws below exception
java.lang.SecurityException: getImeiForSlot: The user 10180 does not meet the requirements to access device identifiers.
Please refer documentation:
https://developer.android.com/preview/privacy/data-identifiers#device-ids
Also refer Issue
I am late to post answer. I still believe my answer will help someone.
Android 10 Restricted developer to Access IMEI number.
You can have a alternate solution by get Software ID. You can use software id as a unique id. Please find below code as i use in Application.
public static String getDeviceId(Context context) {
String deviceId;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID);
} else {
final TelephonyManager mTelephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
deviceId = mTelephony.getDeviceId();
} else {
deviceId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID);
}
}
return deviceId;
}
This just would not work as of Android Q. Third party apps can not use IMEI nor the serial number of a phone and other non-resettable device identifiers.
The only permissions that are able to use those is READ_PRIVILEGED_PHONE_STATE and that cannot be used by any third party apps - Manufacture and Software Applications. If you use that method you will get an error Security exception or get null .
You can still try to get a unique id by using:
import android.provider.Settings.Secure;
private String android_id = Secure.getString(getContext().getContentResolver(),Secure.ANDROID_ID);
The best way to get the IMEI number is as follows:
public static String getIMEIDeviceId(Context context) {
String deviceId;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
} else {
final TelephonyManager mTelephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (context.checkSelfPermission(Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
return "";
}
}
assert mTelephony != null;
if (mTelephony.getDeviceId() != null)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
deviceId = mTelephony.getImei();
}else {
deviceId = mTelephony.getDeviceId();
}
} else {
deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
}
}
Log.d("deviceId", deviceId);
return deviceId;
}
Just copy the method and use it. It will definitely. However, you might know you can't get IMEI in android Q (version 10). In this code, you can get a unique identifier (alternative id) through any device or any API level.
It works 100%
Thank You!!
And Enjoy Coding :)
As the best practices suggest. " you can avoid using hardware identifiers, such as SSAID (Android ID) and IMEI, without limiting required functionality."
Rather go for an instance ID such as String uniqueID = UUID.randomUUID().toString(); or FirebaseInstanceId.getInstance().getId();
Not sure about IMEI number, but you can get the simSerialNumber and other carrier info this way.
getSimSerialNumber() needs privileged permissions from Android 10 onwards, and third party apps can't register this permission.
See : https://developer.android.com/about/versions/10/privacy/changes#non-resettable-device-ids
A possible solution is to use the TELEPHONY_SUBSCRIPTION_SERVICE from Android 5.1, to retrieve the sim serial number. Steps below:
Check for READ_PHONE_STATE permission.
Get Active subscription list.( Returns the list of all active sim cards)
Retrieve the sim details from Subscription Object.
if ( isPermissionGranted(READ_PHONE_STATE) ) {
String simSerialNo="";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
SubscriptionManager subsManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
List<SubscriptionInfo> subsList = subsManager.getActiveSubscriptionInfoList();
if (subsList!=null) {
for (SubscriptionInfo subsInfo : subsList) {
if (subsInfo != null) {
simSerialNo = subsInfo.getIccId();
}
}
}
} else {
TelephonyManager tMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
simSerialNo = tMgr.getSimSerialNumber();
}
}
Check if this helps
you can change other way, i use uuid to replace devices id.
String uniquePseudoID = "35" +
Build.BOARD.length() % 10 +
Build.BRAND.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 = Build.getRadioVersion();
String uuid = new UUID(uniquePseudoID.hashCode(), serial.hashCode()).toString();
AppLog.d("Device ID",uuid);
If your app targets Android 10 or higher, a SecurityException occurs.
Following modules are affected...
Build
getSerial()
TelephonyManager
getImei()
getDeviceId()
getMeid()
getSimSerialNumber()
getSubscriberId()
So you cant get IMEI no for android 10 , You have to used another unique identifier for this like Android ID
It unique 64 bit hex no for device
private String android_id = Secure.getString(getContext().getContentResolver(),
Secure.ANDROID_ID);
According to google docs.
Restriction on non-resettable device identifiers
Starting in Android 10, apps must have the READ_PRIVILEGED_PHONE_STATE privileged permission in order to access the device's non-resettable identifiers, which include both IMEI and serial number.
Caution: Third-party apps installed from the Google Play Store cannot
declare privileged permissions.
So, Instead of imei you can get Android unique ID.
String imei = "";
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
if (telephonyManager != null) {
try {
imei = telephonyManager.getImei();
} catch (Exception e) {
e.printStackTrace();
imei = Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
}
}
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1010);
}
} else {
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
if (telephonyManager != null) {
imei = telephonyManager.getDeviceId();
}
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1010);
}
}
Targeting Android Q, third party apps can't access IMEI at all. Android Q doc is misleading while stating
Starting in Android Q, apps must have the READ_PRIVILEGED_PHONE_STATE
privileged permission in order to access the device's non-resettable
identifiers, which include both IMEI and serial number.
https://developer.android.com/preview/privacy/data-identifiers#device-ids
But when I actually tried to implement it, I am receiving this exception:
java.lang.SecurityException: getDeviceId: The user 10132 does not meet the requirements to access device identifiers.
Someone had reported this on google's issue tracker where a Googler said that this is intended behaviour and IMEI on Q+ is only available for system level apps.
Status: Won't Fix (Intended Behavior) This is Working As Intended.
IMEI is a personal identifier and this is not given out to apps as a
matter of policy. There is no workaround.
https://issuetracker.google.com/issues/129583175#comment10
They mentioned:
If your app is the device or profile owner app, you need only the READ_PHONE_STATE permission to access non-resettable device identifiers, even if your app targets Android 10 or higher.
I tried deploying via EMM as device owner app but not success.
If you needed, you can try to install a work profile in to the mobile phone and include your app in the same package or vice versa.
I tried and it works, it's simple if yo follow this repo: https://github.com/googlesamples/android-testdpc
When you install the Work Profile your app is installed in this profile and you will have acces to the IMEI.
And now there is another example fixed yesterday to Android 10:
https://github.com/android/enterprise-samples/pull/29
In my Android application, I need to display phone numbers of the Sim cards which are available in the device.
I tried with the below codes
private String getPhone() {
TelephonyManager phoneMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (ActivityCompat.checkSelfPermission(activity, wantPermission) != PackageManager.PERMISSION_GRANTED) {
return "";
}
return phoneMgr.getLine1Number();
}
and
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
List<SubscriptionInfo> subscription = SubscriptionManager.from(getApplicationContext()).getActiveSubscriptionInfoList();
for (int i = 0; i < subscription.size(); i++) {
SubscriptionInfo info = subscription.get(i);
Log.d(TAG, "number " + info.getNumber());
Log.d(TAG, "network name : " + info.getCarrierName());
Log.d(TAG, "country iso " + info.getCountryIso());
}
}
But both are returning null or empty string only.
I have added the manifest permission also.
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Could you please help me.
Thanks.
some phone companies not give this permission to get number from sim-card because i was same problem in past projects.
(in the past project i want to send OTP on simcard number user can't type his number. it was for security purpose.)
so some of phone gives you output correct and remains give you output as NULL
I tried using below piece of code but it is not giving me the number. Your information would be great help.
Code below:
val subscription =SubscriptionManager.from(context).activeSubscriptionInfoList
for (subscriptionInfo in subscription)
{
val number = subscriptionInfo.number
Log.e("Test", " Number is " + number)
}
Correct way to get IMEI Number KOTLIN
try{
val tm = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
val IMEI = tm.getImei()
if (IMEI != null)
Toast.makeText(this, "IMEI number: " + IMEI,
Toast.LENGTH_LONG).show()
}catch (ex:Exception){
Log.e("",ex.message)
}
Including asking for Permission
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_PHONE_STATE)) {
} else { ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.READ_PHONE_STATE), 2) } }
Don't forget AndroidManifest.xml
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Taken from this answer and translated to kotlin:
Getting the Phone Number, IMEI, and SIM Card ID
val tm = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
// For SIM card, use the getSimSerialNumber()
//---get the SIM card ID---
val simID = tm.simSerialNumber
if (simID != null)
Toast.makeText(this, "SIM card ID: " + simID,
Toast.LENGTH_LONG).show()
Phone number of your phone, use the getLine1Number() (some device's dont return the phone number)
//---get the phone number---
val telNumber = tm.line1Number
if (telNumber != null)
Toast.makeText(this, "Phone number: " + telNumber,
Toast.LENGTH_LONG).show()
// IMEI number of the phone, use the getDeviceId()
//---get the IMEI number---
val IMEI = tm.deviceId
if (IMEI != null)
Toast.makeText(this, "IMEI number: " + IMEI,
Toast.LENGTH_LONG).show()
Permissions needed:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Please note that some devices could not return the phone number due to its internal implementation.
Right now you can not access these Info according to docs:
getSerial()
getImei()
getDeviceId()
getMeid()
getSimSerialNumber()
getSubscriberId()
If your app targets Android 10 or higher, a SecurityException occurs.
If your app targets Android 9 (API level 28) or lower, the method returns null or placeholder data if the app has the READ_PHONE_STATE permission. Otherwise, a SecurityException occurs.
I am not able to set the default sim for calling. I am trying to alter the system settings to change the default sim every before I sent the ACTION_CALL intent but ever time I am getting the sim selection dialog
public class CallUtil {
public static void sendCallIntent(Context context, String number) {
Intent intent = new Intent(Intent.ACTION_CALL)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("tel:" + number));
setDefaultSim(context);
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
return;
}
context.startActivity(intent);
}
public static void setDefaultSim(Context context) {
try {
ContentValues val = new ContentValues();
List<Integer> sims = getInsertedSIMIds(context);
val.put("value", sims.get(0));
context.getContentResolver().update(Uri.parse("content://settings/system"), val, "name='voice_call_sim_setting'", null);
} catch (Exception e) {
}
}
public static List<Integer> getInsertedSIMIds(Context context){
List<Integer> list = new ArrayList<Integer>();
SubscriptionManager sm=(SubscriptionManager)context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
for ( SubscriptionInfo sub: sm.getActiveSubscriptionInfoList()) {
list.add(sub.getSimSlotIndex());
}
return list;
}
}
My intention is to place the call through a specific sim using Android 5.1 APIs. Please let me know if there is any alternate approach.
From API level 22 and above we can set sim selection while making a call Intent by using SubscriptionManager and TelecomManager as follows.
//To find SIM ID
String primarySimId,secondarySimId;
SubscriptionManager subscriptionManager = (SubscriptionManager) appContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
List<SubscriptionInfo> subList = subscriptionManager.getActiveSubscriptionInfoList();
int index=-1;
for (SubscriptionInfo subscriptionInfo : subList) {
index++;
if(index == 0){
primarySimId=subscriptionInfo.getIccId();
}else {
secondarySimId=subscriptionInfo.getIccId();
}
}
// TO CREATE PhoneAccountHandle FROM SIM ID
TelecomManager telecomManager =(TelecomManager) getSystemService(Context.TELECOM_SERVICE);
List<PhoneAccountHandle> list = telecomManager.getCallCapablePhoneAccounts();
PhoneAccountHandle primaryPhoneAccountHandle,secondaryPhoneAccountHandle;
for(PhoneAccountHandle phoneAccountHandle:list){
if(phoneAccountHandle.getId().contains(primarySimId)){
primaryPhoneAccountHandle=phoneAccountHandle;
}
if(phoneAccountHandle.getId().contains(secondarySimId)){
secondaryPhoneAccountHandle=phoneAccountHandle;
}
}
//To call from SIM 1
Uri uri = Uri.fromParts("tel",number, "");
Bundle extras = new Bundle(); extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,primaryPhoneAccountHandle);
telecomManager.placeCall(uri, extras);
//To call from SIM 2
Uri uri = Uri.fromParts("tel",number, "");
Bundle extras = new Bundle(); extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,secondaryPhoneAccountHandle);
telecomManager.placeCall(uri, extras);
For more details refer https://developer.android.com/reference/android/telephony/SubscriptionManager.html
Also above code will work only for API 22 and above and require READ_PHONE_STATE permissions
dual-sim is not official supports of Android SDK. I suggest you to capture the logcat and make a specific sim call with system dialer, finding out the intent format about the sim cards.
UPDATE
from api level 22, the sdk supports dual sim link but i can not find the ACTION_CALL intent format for dual-sim in SDK documents.
True-caller app has been able to add a button for selecting a specified sim to either send or receive voice and text messages.
Have tried SubscriptionManager API introduced in 5.1 but still getting no change.