To store an SMS Message to the SIM Card (ICC Card) you have to create a PDU-String of the SMS Message.
The following Code creates the PDU String of the Message. You have to insert the PhoneNumber and the Message as String. Notice, that the String of the Message has a maximum length of 159 chars.
public String getPduString(String msg, String phoneNr){
String inpString = msg;
String phoneNumber = phoneNr;
String REIVER_NUMBER_LENGTH = intToHex(phoneNr.length());
if (phoneNumber.length() % 2 != 0){
phoneNumber = phoneNumber + "F";
}
String octetFirst = "";
String octetSecond = "";
String output = "";
String firstOctet = "04";
String REIVER_NUMBER_FORMAT = "91";
String REIVER_NUMBER = semiOctetToString(phoneNumber);
String PROTO_ID = "00";
String DATA_ENCODING = "00";
String VALID_PERIOD = "20806291731408";
String userDataSize = intToHex(inpString.length());
for (int i = 0; i <= inpString.length(); i++){
if (i == inpString.length()){
if (octetSecond != ""){
output = output + "" + (intToHex(binToInt(octetSecond)));
}
break;
}
String current = intToBin(getSevenBit(inpString.charAt(i)),7);
String currentOctet;
if ((i != 0)&&(i % 8 != 0)){
octetFirst = current.substring(7 - (i) % 8);
currentOctet = octetFirst + octetSecond;
output = output + "" + (intToHex(binToInt(currentOctet)));
octetSecond = current.substring(0,7 - (i) % 8);
}else{
octetSecond = current.substring(0,7 - (i) % 8);
}
}
String header = firstOctet + REIVER_NUMBER_LENGTH + REIVER_NUMBER_FORMAT + REIVER_NUMBER + PROTO_ID + DATA_ENCODING + VALID_PERIOD + userDataSize;
return header + output;
}
The function need some other functions to work:
public String intToHex(int i){
String sHex = "0123456789ABCDEF";
String h = "";
for (int j = 0; j <= 3; j++){
h = h + sHex.charAt((i >> (j * 8 + 4)) & 0x0F) + sHex.charAt((i >> (j * 8)) & 0x0F);
}
return h.substring(0,2);
}
public String semiOctetToString(String inp){
String out = "";
String temp = "";
for (int i = 0; i < inp.length(); i = i + 2){
temp = inp.substring(i, i + 2);
out = out + temp.charAt(1) + temp.charAt(0);
}
return out;
}
public String intToBin(int x, int size){
int base = 2;
BigInteger num = new BigInteger(Integer.toString(x));
String bin = num.toString(base);
for (int i = bin.length(); i < size; i++){
bin = "0" + bin;
}
return bin;
}
public int getSevenBit(char character){
char[] sevenbitdefault = {'@', '£', '$', '¥', 'è', 'é', 'ù', 'ì', 'ò', 'Ç', '\n', 'Ø', 'ø', '\r','Å', 'å','\u0394', '_', '\u03a6', '\u0393', '\u039b', '\u03a9', '\u03a0','\u03a8', '\u03a3', '\u0398', '\u039e','€', 'Æ', 'æ', 'ß', 'É', ' ', '!', '"', '#', '¤', '%', '&', '\'', '(', ')','*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7','8', '9', ':', ';', '<', '=', '>', '?', '¡', 'A', 'B', 'C', 'D', 'E','F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S','T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'Ä', 'Ö', 'Ñ', 'Ü', '§', '¿', 'a','b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o','p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'ä', 'ö', 'ñ','ü', 'à'};
for (int i = 0; i < sevenbitdefault.length; i++){
if (sevenbitdefault[i] == character){
return i;
}
}
return 0;
}
public int binToInt(String x){
int total = 0;
int power = x.length() - 1;
for (int i = 0; i < x.length(); i++){
if (x.charAt(i) == '1'){
total = (int) (total + Math.pow(2, power));
}
power = power - 1;
}
return total;
}
The result of the function 'getPduString' is a PDU-String that you can store on the SIM Card.
You can use the hidden method 'copyMessageToIcc' of 'android.telephony.SmsManager'. The problem is, that the method is hidden. You need to use it by java reflection. I wrote a new SMStoIcc:
public boolean SMStoIcc(byte[] smsc,byte[] pdu,int status) {
boolean flag = false;
try {
Class<?> c = Class.forName("android.telephony.SmsManager");
Method m = c.getMethod("copyMessageToIcc", byte[].class, byte[].class, int.class);
try {
flag = ((Boolean)m.invoke(SmsManager.getDefault(), smsc, pdu, status )).booleanValue();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
Log.e("NoSuchMethodException","NoSuchMethodException :"+ e.getMessage());
e.printStackTrace();
} catch (ClassNotFoundException ex) {
Log.e("ClassNotFoundException","ClassNotFoundException :"+ ex.getMessage());
ex.printStackTrace();
}
return flag;
}
This method store the PDU-String to the SIM-Card. It returns true, if the process was successful.
The first parameter is the smsc. It is not so important, but you need it.
The second parameter is the pdu.
The third parameter is the status. It should be 1 for "read".
You have to insert the values as a byte[]. I wrote the following function 'hexStringToByteArray' to convert the smsc and pdu to a byte array.
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
The smsc String is in my project always '07910100000000F0'.
Now you can add a SMS to the SIM-Card.
Use the functions:
String smsc = "07910100000000F0";
String nr = "1234567890";
String msg = "SMS inserting test";
String pdu_string = getPduString(msg, nr);
byte[] service_center = hexStringToByteArray(smsc);
byte[] pdu = hexStringToByteArray(pdu_string);
boolean success = SMStoIcc(service_center, pdu, 1);
// if it was successful, success is true
That is the full process to add a SMS Message to the SIM Card...
For reading SMS from SIM use:
public ArrayList<SmsMessage> getSmsList(){
ArrayList<SmsMessage> list = new ArrayList<SmsMessage>();
SmsManager newSmsManager = SmsManager.getDefault();
try {
Class<?> smsManagerClass = Class.forName("android.telephony.SmsManager");
Method localMethod = smsManagerClass.getMethod("getAllMessagesFromIcc",null);
try {
list = (ArrayList<SmsMessage>)localMethod.invoke(newSmsManager, null);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
Log.e("NoSuchMethodException","NoSuchMethodException :"+ e.getMessage());
e.printStackTrace();
} catch (ClassNotFoundException ex) {
Log.e("ClassNotFoundException","ClassNotFoundException :"+ ex.getMessage());
ex.printStackTrace();
}
return list;
}
For delete a SMS Message from SIM use:
public boolean delMessageFromIcc(int index){
boolean flag = false;
try {
Class<?> smsManagerClass = Class.forName("android.telephony.SmsManager");
Method method = smsManagerClass.getMethod("deleteMessageFromIcc", int.class);
try {
flag = ((Boolean)method.invoke(SmsManager.getDefault(), index)).booleanValue();
} catch (IllegalAccessException e) {
Toast.makeText(getApplicationContext(), e.toString() + " _1", Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (IllegalArgumentException e) {
Toast.makeText(getApplicationContext(), e.toString() + " _2", Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (InvocationTargetException e) {
Toast.makeText(getApplicationContext(), e.getCause().toString() + " _3", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
Toast.makeText(getApplicationContext(), e.toString() + " _4", Toast.LENGTH_LONG).show();
Log.e("NoSuchMethodException","NoSuchMethodException :"+ e.getMessage());
e.printStackTrace();
} catch (ClassNotFoundException ex) {
Toast.makeText(getApplicationContext(), ex.toString() + " _5", Toast.LENGTH_LONG).show();
Log.e("ClassNotFoundException","ClassNotFoundException :"+ ex.getMessage());
ex.printStackTrace();
}
return flag;
}
For update Messages on SIM-Card use:
public boolean updateMessageOnIcc(int index, int state, byte[] pdu){
boolean flag = false;
try {
Class<?> smsManagerClass = Class.forName("android.telephony.SmsManager");
Method localMethod = smsManagerClass.getMethod("updateMessageOnIcc", int.class, int.class, byte[].class);
try {
flag = ((Boolean)localMethod.invoke(SmsManager.getDefault(), index, state, pdu)).booleanValue();
} catch (IllegalAccessException e) {
Toast.makeText(getApplicationContext(), e.toString() + " _1", Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (IllegalArgumentException e) {
Toast.makeText(getApplicationContext(), e.toString() + " _2", Toast.LENGTH_LONG).show();
e.printStackTrace();
} catch (InvocationTargetException e) {
Toast.makeText(getApplicationContext(), e.getCause().toString() + " _3", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
Toast.makeText(getApplicationContext(), e.toString() + " _4", Toast.LENGTH_LONG).show();
Log.e("NoSuchMethodException","NoSuchMethodException :"+ e.getMessage());
e.printStackTrace();
} catch (ClassNotFoundException ex) {
Toast.makeText(getApplicationContext(), ex.toString() + " _5", Toast.LENGTH_LONG).show();
Log.e("ClassNotFoundException","ClassNotFoundException :"+ ex.getMessage());
ex.printStackTrace();
}
return flag;
}
I hope, i could help you.....