2

Is there any method to get signal strength on both sim cards. I search a lot but I couldn't find any solution. Maybe is there any method to register receiver on second sim card ? I'm working on Android 5.0 and I know that on this version Android officially does not support dual sim solutions. I found only this which nearly fits to me: Check whether the phone is dual SIM Android dual SIM signal strength

Second link presents some way but I cannot use it because method TelephonyManager.listenGemini is not available

Any help ?

Community
  • 1
  • 1
Jacob Sokol
  • 87
  • 1
  • 9

2 Answers2

6

Please note: the following is specific to some Android 5.0 devices. It uses hidden interface in Android 5.0, and will not work in earlier AND later versions. In particular, the subscription id changed from long to int when the API is exposed in API 22 (for which you should use the official API anyway).

For Android 5.0 on HTC M8, you may try the following to get the signal strength of both sim cards:

Overriding PhoneStateListener and its protected internal variable long mSubId. Since the protected variable is hidden you will need to use reflection.

public class MultiSimListener extends PhoneStateListener {

    private Field subIdField;
    private long subId = -1;

    public MultiSimListener (long subId) {
        super();            
        try {
            // Get the protected field mSubId of PhoneStateListener and set it 
            subIdField = this.getClass().getSuperclass().getDeclaredField("mSubId");
            subscriptionField.setAccessible(true);
            subscriptionField.set(this, subId);
            this.subId = subId; 
        } catch (NoSuchFieldException e) {

        } catch (IllegalAccessException e) {

        } catch (IllegalArgumentException e) {

        }
    }

    @Override
    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
        // Handle the event here, subId indicates the subscription id if > 0
    }

}

You also need to get the list of active subscription IDs from the SubscriptionManager for instantiating the class. Again SubscriptionManager is hidden in 5.0.

final Class<?> tmClassSM = Class.forName("android.telephony.SubscriptionManager");
// Static method to return list of active subids
Method methodGetSubIdList = tmClassSM.getDeclaredMethod("getActiveSubIdList");
long[] subIdList = (long[])methodGetSubIdList.invoke(null);

Then you can iterate through the subIdList to create instances of MultiSimListener. e.g.

MultiSimListener listener[subIdList[i]] = new MultiSimListener(subIdList[i]);

You can then call TelephonyManager.listen as usual, for each of the listeners.

You will need to add error and Android version / device check to the code, as it works only on specific devices / version.

headuck
  • 2,763
  • 16
  • 19
  • It works beautiful! onCellLocationChanged work to. How to get network operator for both SIMs? – theWalker Jan 30 '16 at 19:38
  • You can get the `SubscriptionInfo` using `getActiveSubscriptionInfo()` of `SubscriptionManager`, and then you can call `getCarrierName()` or `getMnc()` on the `SubscriptionInfo` instance. For 5.0 just use reflection, and note that `subId` is `long` instead of `int`. – headuck Jan 30 '16 at 19:57
  • Please rewrite it as answer in my question http://stackoverflow.com/questions/35101020/android-dual-sim-laccidcsqoperator-reporting – theWalker Jan 30 '16 at 20:17
  • But how to get SubscriptionManager in 5.0? – theWalker Jan 30 '16 at 20:24
  • NoSuchMethodException for getActiveSubscriptionInfo (5.0.2) – theWalker Jan 30 '16 at 22:08
  • Solution is simply for 5.0! Youre code + listen(msl[i], PhoneStateListener.LISTEN_SERVICE_STATE) (and LISTEN_SIGNAL_STRENGTHS & LISTEN_CELL_LOCATION) and onServiceStateChanged() reports operators for both SIMs without using SubscriptionManager – theWalker Jan 31 '16 at 08:20
  • This worked for me on 24 when I changed the subId type to "int" – PJeremyMalouf Feb 13 '18 at 04:59
  • Does not work on Android 11 (30). Info receiver is for whatever SIM the OS chooses. – 3c71 Oct 20 '20 at 12:46
  • Tested Android 10 (MIUI 11), not working either, setting mSubId has not effect whatsoever. – 3c71 Oct 20 '20 at 13:02
0

On Android 7 (N), one should do as follows to create a TelephonyManager associated with a particular subscription id:

TelephonyManager telephonyManager = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager = telephonyManager.createForSubscriptionId( subId );

On Android 5.1 (L MR1 / 22) up-to 6 (M / 23), one can do this in PhoneStateListner constructor:

try
{
    Field f = PhoneStateListener.class.getDeclaredField("mSubId");
    f.setAccessible(true);
    f.set(this, id);
}
catch (Exception e) { }

Either method requires READ_PHONE_STATE permission.

3c71
  • 4,313
  • 31
  • 43