I write a app which use SMS Manager. I use method sendTextMessage() but it isn't work. Now I am using sendMutlipartTextMessage() and it's work. But it's send multipart message when it is about 60 characters. This is normal? Everywhere I read than should be 160 characters. This is important to me because I must pay more.
The message character limit depends on the character bit-size of the alphabet you're using. For the standard GSM 7-bit alphabet, the character limit is 160. For an 8-bit alphabet, it is 140, and for a 16-bit alphabet, which sounds like your situation, it is only 70 characters. If you must send messages with special Unicode characters, like those in non-Latin alphabets, then you're stuck with the 16-bit alphabet, and its 70-character limit. If you can somehow convert the messages to the basic 7-bit alphabet, you will have the 160-character limit.
Related
In my application I am writing a number of measurements to an NFC chip. As the number of measurements varies, I cannot define an exact length of NDEF message and implementing a function that would count the length and write the payload length just before the NFC read is not practical for the application.
What I thought of doing was to set the size of the NDEF message to maximum available memory and simply write to the free space. However, whilst using an NXP NFC scanner I get an error that my memory is not NDEF formatted. Could anyone tell me what I am doing wrong?
My current understanding is that: 0x03 defines ndef format, 0xFF flags 3 byte length format, 0x373 is the available length, 0xC5 identifies ME and MB for the single chunk, then 0x00 for type length and first two payload bytes, finally - 0x03 and 0x6D defines 0x36D payload length.
The memory (start and end) after initialization can be seen below:
You should know the size of the payload at the time write the message. It's possible to code NDEF by hand, but you need to include the TNF, type, and payload for each record in the message.
I recommend using NdefRecord and NdefMessage to encode the payload and create the message. If at later date you have a different payload with a different size, create a new message and write it to the tag. When you write a message to the tag, it overwrites the previous message.
Use the Android Ndef.getMaxSize() method to determine the maximum size available. This however requires actually writing dummy data.
A more optimal way would be to just write the NDEF header, then later modify it as more data is coming in. If so, you should note that the NDEF message iself is wrapped in a simple container style format when actually on the tag. So you'll have to update the length more than once place.
See for example NFCTools
I need to send a SMS that contains a JSON in my Android app. Here is the code:
SmsManager sms = SmsManager.getDefault();
String message = "{\"phone\":\"9999-9999\"}";
sms.sendTextMessage(phoneNumber, null, message, null, null);
I tested with some phones and most part of them receive the right message:
{"phone":"9999-9999"}
But one model (LG G2 Mini) changes the '{' character when the SMS is received:
ä"phone":"9999-9999"ñ
Does anybody know why it's happening?
Any tip will be very helpful,
Thanks
There are special charsets for SMS, see this link from Wikipedia: https://en.wikipedia.org/wiki/GSM_03.38
The characters { and }, that are wrong on your phone, are in the Basic Character Set Extension. Try other are characters like €, |, ] and so on. When these characters also do not work on your phone, I suppose your problem is related to this charset extension.
Characters from the extension need to be escaped with 0x1B (escape character in SMS). This is only a conjecture, maybe there could be a problem with the escaping.
Looks like the LG G2 Min has not correctly implemented the 3GPP TS 23.038.
SMS uses different character sets. The mostly used is the GSM 7 bit default alphabet. It codes in 7 bits most of the usual characters and special characters used by US and some European languages. Some special characters (^{}\<[~]€) did not fit into this 7 bit table. The escape character switch to GSM 7 Bit default alphabet extension table that contains the above mentioned special character. These characters are codes by two 7-Bit character, ESC and the code for e.g. ‘{‘.
What you can try, if possible, is to use Unicode. You may force Unicode by using a Unicode character in your message that is not part of the 7-Bit GSM character code and its extension table.
I'm developing an Android application which sends commands to a remote equipment through SMS. The commands are all regular text messages, and some of them start with the prefix A##. To test the app I sent some "commands" to other phones using an Android 4.3 phone and also an Android 2.3 phone.
When I run the app on the Android 4.3 phone, the SMS on the receiving end shows just fine on any device, but if I use the Android 2.3 to send the commands they get received as A¿¿ on an Android 4.3 phone but arrive as normally as A## either on an Android 2.3 or an iPhone. On the target equipment (it uses a GSM modem) the message gets like A (character "A" plus two spaces - ASCII 0x20), so I suspect the sender is using a different encoding. What I find strange is the # symbol is not even an extended ASCII char, so I'm wondering why it would be encoded in some other charset than ASCII anyway.
Can anyone explain what is happening here? If the Android 2.3 device is really using another encoding, is there a way to force it to ASCII before sending the SMS?
The sending code is as follows:
#Override
public void sendCommand(String command) {
//TODO: Send SMS with 'command' as its text message
SmsManager sms=SmsManager.getDefault();
PendingIntent piSent=PendingIntent.getBroadcast(this, 0,
new Intent("SMS_SENT"), 0);
PendingIntent piDelivered=PendingIntent.getBroadcast(this, 0,
new Intent("SMS_DELIVERED"), 0);
String phone = txtPhone.getText().toString();
sms.sendTextMessage(phone, null, command, piSent, piDelivered);
}
Where the parameter command is always the concatenation of the prefix with some other text, like this:
String SmsPrefix = new String("A##");
sendCommand(SmsPrefix + "AT+DEACT");
UPDATE:
I had a hint from someone that problem might be related to the carrier, not to the Android system itself. I live in Brazil and my Android 2.3 device was using the carrier TIM, just the same as the iPhone we used. The Android 4.3 device was using the carrier Claro. What I found is that, if I get the TIM SIM card and put it on the Android 4.3 device the receiving end also shows the garbled #, so it seems the carrier TIM is messing up the SMS sent through their network. I will try the new suggestions from #PMunch below so we can possibly find a workaround, but we can be sure already it wasn't really some kind of bug corrected from Android 2.3 to 4.3.
Really seems like an encoding issue. It might be that you try to send as ASCII but the receiver tries to parse it in a different encoding. If you explicitly specify encoding on both sender and receiver end it should work.
EDIT:
This would get the character array and create a string from it all using US-ASCII encoding.
String newString = new String(oldString.getBytes("US-ASCII"), "US-ASCII"));
EDIT2:
Turns out GSM doesn't use regular US-ASCII, rather it uses it's own GSM alphabet. What seems to be happening is that the # (ASCII 0x40) is translated into the GSM alphabet directly as ¡ (Upside down exlamation mark, GSM 0x40). This won't affect regular text characters as they share the same addresses (same for the plus sign 0x2B). Then when converted back it tries to convert it frow what it assumes is GSM-alphabet to ASCII, meaning the 0x40 of the earlier # sign is now an upside down exclamation mark. This is a sign that does not exist in regular ASCII and is therefore replaced by an unknown character symbol, apparently an upside down question mark in Android 2.3 and a space in the GSM receiver. This lack of conversion from ASCII to GSM seems to have been fixed between Android 2.3 and Android 4.3.
If you try to specify to Android that this is an ASCII string by using new String ("A##","ISO-8859-1") it might do the conversion in it's own. If not you might have to do it yourself (Something like this might help). If # is the only special character you need to support then you could of course encode that single character yourself(\0\0 for ##).
EDIT3:
Edit2 included multiple actions, what did you try? To explain the whole GSM/ASCII thing:
ASCII uses it's first 32 characters as control characters. These characters were deemed unnecessary for GSM and so they were replaced with other characters. The null character, on computers used to terminate a string, is not used for text messages. They are set at 140 octets and any empty space is simply filled with filler characters. So the null character 0x00 in ASCII is used for something else, the # character. If you look at the GSM alphabet and the ASCII alphabet you will see that the 32 first characters are replaced by Greek characters and some others. If you look at the remaining characters they are mostly in the right place, the # character is one of the ones that aren't. If you for example try to type in _ you should get similar results. When you say that # comes out as A do you then mean that A## becomes A or that it becomes AAA? I also found something interesting while looking through Unicode conversion supplied by Unicode Inc.:
0x00 is NULL (when followed only by 0x00 up to the
end of (fixed byte length) message, possibly also up to
FORM FEED. But 0x00 is also the code for COMMERCIAL AT
when some other character (CARRIAGE RETURN if nothing else)
comes after the 0x00.
So if you tried to send only A## then the two last #s might be interpreted as padding characters instead of # characters. Regardless it seems like the carriers in your area does some conversion between them, have you tried to send the characters with sendDataMessage as raw data bytes? The function byte[] stringToGsm7BitPacked(String data) throws EncodeException from telephony.GsmAlphabet should help convert your string to the GSM alphabet.
I've observed this issue for years now, not knowing where it came from. I am concerned that this bug is still observable in the new versions of Android, in 2011, and I hope you can finally help me to fully understand it, if not solve it.
Let's consider the given (real) situation. Mister "A" is using a custom SMS/MMS app from Sony on his Xperia Arc (official 2.3.3). Mister B is using the android SMS/MMS stack app on his Milestone (Cyanogen 6.12, unofficial 2.2). Both of them use Android in French (if that matters).
When A sends a sms to B containing special characters like "ç", "ê", B receives a message with these characters replaced by a space. Characters like "é" are working fine though.
When B sends the sms to A, everything works fine.
When A sends this sms to himself, everything works fine.
Conclusion : this is not the mobile provider's fault since it works in one way and not the other.
So, I guessed at first that something was wrong with A's custom app. Replaced it with the apk from B's phone. Everything remained the same. I decompiled the app and I didn't find where the encoding of the sms string was done. I concluded the bug is not coming from the app, but from the way Android encodes the strings...
I ran another test :
I wrote an sms with only standard characters, something like 250 characters in 1.5 sms. Then, I append a "ç" to the sms.
On A's phone : the counter says it consumed 10 characters.
On B's phone : the counter says the sms now takes 3 sms : the string size doubled !
Conclusion :
On A's phone, the default charset includes "ç".
On B's phone, when "ç" appears, the charset changes and each character needs then twice the original space.
(Or am I missing something ?)
Questions :
Why different version of Android aren't using the same default charset ?
On Android, are these default charset depending on the rom, for example ?
Can we configure/change these charset somewhere (in the menu or directly on a rooted phone) ?
Is there another easy way to fix this ?
Any help, explanation or experience is welcome :)
You are suffering from encoding problems. From the description it looks like 'A' is sending data in one charset and not including information about what charset that is. The root cause is that to pass extended (non-ascii) characters between two systems they have to agree on an encoding to use. If you are restricted to 8 bit values then the systems agree to use the same codepages. In SMS there is a special GSM codepage for 7 or 8 bit encodings or UTF-16 can be used which uses 2 bytes to represent each character. What you see when you enter 250 characters followed by a single extended character shows you what is happening in the application. An SMS message is restricted to 140 octets. When you are using an 8 bit encoding your 250 chars fit into 2 messages (250 < 280) however once you added the "ç" the app changed to using UTF-16 encoding so suddenly all your characters are taking 2 octets and you can only fit 70 characters into a message. Now it takes 3.5 SMS messages to transfer the entire message.
On Android the decoding of the SMS message is part of the framework telephony code in SmsCbMessage.java. It works out the language code and encoding of the message body. If this is incorrect (the message was encoded with an english codepage but uses french extended chars) then you can get odd characters appearing.
You are right that this is not the mobile network at fault. I suspect it is phone A's messaging application although it is possible that Android is failing to correctly identify the encoding of a valid SMS. I wonder how it works between A and an iPhone or some other manufacturers device.
I have encountered the same problem when I had to show a few special characters in an sms unicode app. The method I used was take the string that I need to send as sms, run it in a for loop to take each character , find its ascii code , use that integer value to encode that string using a delimiter. This string can be sent as sms, which needs to be decoded using the same delimiter that is used for sending, then convert each ascii code char in it to characters (language specific), form a string by appending the converted chars. This text will be same as the one that was sent as sms.
Regards
Text SMS have a limit of 160 characters and to send more than that you have to send using multipart SMS.
Is this applicable for Data SMS too? If the size of the data SMS exceeds (160 Characters * 7 (I believe each character is encoded using 7 bits), you have to split and send it?
I tried receiving a data SMS in the emulator, (sending a UTF-8 encoded String, using getBytes(),) however I was not able to convert back the message completely, the message is filled with different characters, when I try to get back the string.
Any suggestions?
Unfortunately, sending and receiveing data SMS doesn't work well in emulator. You'll have to use real device.
From my experience, data SMS takes less than 140 bytes. I was trying to send ~140 bytes and I got exceptions.
I didn't have time to digg deeper what's the real limit of data SMS. If you find out, let me know.
data SMS have 133 byte capacity (140-7 byte for port number)