Dual SIM

The Hover SDK automatically supports dual SIM devices without any extra configuration. However, sometimes you may need to read the user's SIM cards, get them to choose a SIM, or something else. Hover provides a number of helper methods as well as it's own data model for SIM information. Android's APIs for dual SIM devices are poorly documented and were only introduced in version 5.1. Hover's helpers work on all supported Android versions 4.3 and up.

When you create a Hover action you specify a country and network. This is used to match the SIM cards that work with that the USSD service your action represents. When your app runs the action using the HoverParameter.Builder() intent, the correct SIM card is chosen automatically using the configuration you created. If the correct SIM card is present it will be used to dial the USSD root code regardless of which slot the SIM card is in or the user's system settings regarding which SIM to dial with. If the correct SIM card is not present an error will be returned to your app in onActivityResult() with RESULT_CANCELED. If for some reason the user has two SIM cards that work with your action inserted, they will be shown a simple dialog asking them to choose one before proceeding

Reading a user's SIM cards

You must get the READ_PHONE_STATE permission THEN call Hover.initialize() BEFORE using any SIM card methods below, otherwise the SIM information will be empty. You can do this yourself or using Hover's permission helper.

The simplest SIM card helper just lets you check if the correct SIM for your action is present: Hover.isActionSimPresent(actionID, context).

You might instead want to get a list of all the user's currently inserted SIM cards. To do so you can call Hover.getPresentSims(context) which returns a list of Hover's SimInfo objects.

Choosing an action using present SIMs

A common use case is to choose an action to run based on the user's present SIM card(s). This can be done by calling ActionHelper.getActionChoice(actionIds, actionChoiceListener, context). You must specify an ActionChoiceListener which is the following interface:

public interface ActionChoiceListener {
	void onActionChosen(String actionId);
	void onCanceled();
}

This is because if the user has a dual SIM device and more than one SIM matches your actions, then the callback will be called once they have selected the SIM from a simple dialog. Note that this dialog will actually present the user with a list of SIM choices not action names. If only one SIM matches, the callback will be called immediately. If no SIMs match an exception will be thrown. If the user cancels the dialog onCanceled will be called. The following is an example:

try {
	Hover.getActionChoice(new String[] {"aaaa1111", "bbbb2222"}, new ActionHelper.ActionChoiceListener() {
		@Override 
		public void onActionChosen(String actionID) {
			Intent i = new HoverParameters.Builder(this).request(actionID)
				.buildIntent();
			startActivityForResult(i, 0);
		}

		@Override 
		public void onCanceled() { 
			Toast.makeText(activity, "You must choose a SIM card").show();
		}
	}, activity);
} catch(HoverConfigException e) {}

The contexts in this example should be activities, since a dialog may need to be shown to the user.

The SimInfo Object

SimInfo is a Plain Old Java Object (POJO) included in the Hover SDK to simplify reading of SIM info in Android.

You do not instantiate SimInfo objects yourself, you must get them from a method (such as those above) that returns them!

The follow table lists the most useful fields and methods on SimInfo and what they mean. This and more detailed info is also available in the javadoc

Type Field Meaning
int mSlotIdx 0 indexed position of the SIM this object represents. -1 if SIM not present (was previously inserted but since removed)
int mSubscriptionId An ID assigned by Android and used to get other info about a SIM in various places
String mIccId The hardware identifier of the physical SIM card
String mImsi The international mobile subscriber identity, a unique number provisioned by the operator that distributed the SIM. The first 3 digits are always the MCC, the next 2 or 3 digits are the MNC, and the rest are unique to an individual's account. This is the best way to identify a SIM card's mobile operator. See https://en.wikipedia.org/wiki/Mobile_country_code
String mOperatorName The name of the mobile operator which provisioned the SIM. This can sometimes be incorrect, such as when a phone has been unlocked from a network.
String mCountryIso The country ISO alpha-2 of the mobile operator which provisioned the SIM. This can sometimes be incorrect, such as when a phone has been unlocked from a network.
boolean mNetworkRoaming Whether the phone is currently roaming. Can sometimes be incorrect.