Search code examples
androidsmsdual-sim

Spreadtrm Chipset. Dual Sim Application to send sms from specified sim slot. (< 22)


I am tryting to develop an android application for Spreadtrum chipset smartphones. This app needs to specify which sim card (sim1 or sim2) to send sms or execute a phone call.

I was able to find an API for Mediatek API here, which works as an addon in android studio.

I tried to use adb shell as mentioned in this post. This did not work, both the commands sent sms through sim1. Two commands:

1. service call isms 5 s16 "PhoneNumber" i32 0 i32 0 s16 "BodyText" 2. service call isms2 5 s16 "PhoneNumber" i32 0 i32 0 s16 "BodyText"

When I list the service calls, there are telephony.registry0 and telephony.registry1.

I tried to use reflection as mentioned in this post. Sms was sent from sim1 only.

Isn't there any API or addons to use for spreadtrum

NOTE: I know this is not a prolem for Lollipop and later versions of android. But I am trying to build this application for KitKat versions.

P.S. I even tried contacting the chipset company. But sadly no response.


Solution

  • You need to use reflection for this. Following code worked for me:

    public class SimUtil {
    
    public static boolean sendSMS(Context ctx, int simID, String toNum, String centerNum, String smsText, PendingIntent sentIntent, PendingIntent deliveryIntent) {
    String name;
    
    try {
        if (simID == 0) {
            name = "isms0";
        } else if (simID == 1) {
            name = "isms1";
        } else {
            throw new Exception("can not get service which for sim '" + simID + "', only 0,1 accepted as values");
        }
    
        try
        {
            Method method = Class.forName("android.os.ServiceManager").getDeclaredMethod("getService", new Class[]{String.class});
            method.setAccessible(true);
            Object param = method.invoke(null, new Object[]{name});
            if (param == null)
            {
                throw new RuntimeException("can not get service which is named '" + name + "'");
            }
            method = Class.forName("com.android.internal.telephony.ISms$Stub").getDeclaredMethod("asInterface", new Class[]{IBinder.class});
            method.setAccessible(true);
            Object stubObj = method.invoke(null, new Object[]{param});
            method = stubObj.getClass().getMethod("sendText", String.class, String.class, String.class, String.class, PendingIntent.class, PendingIntent.class);
            method.invoke(stubObj, ctx.getPackageName(), toNum, centerNum, smsText, sentIntent, deliveryIntent);
        } catch (ClassNotFoundException e)
        {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e)
        {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e)
        {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e)
        {
            throw new RuntimeException(e);
        }
    
        return true;
    } catch (ClassNotFoundException e) {
        Log.e("Exception", "ClassNotFoundException:" + e.getMessage());
    } catch (NoSuchMethodException e) {
        Log.e("Exception", "NoSuchMethodException:" + e.getMessage());
    } catch (InvocationTargetException e) {
        Log.e("Exception", "InvocationTargetException:" + e.getMessage());
    } catch (IllegalAccessException e) {
        Log.e("Exception", "IllegalAccessException:" + e.getMessage());
    } catch (Exception e) {
        Log.e("Exception", "Exception:" + e);
    }
    return false;
    }
    }
    

    For determining which isms values your sim slots carry, please view this comment.

    For more details view this post.