I would like to know how to detect what coding has been used for SENT SMS (in case I read it from "content://sms/sent"). I check all columns and I didnĀ“t find any information about it there.
Reason why I am looking for this is to know, how many messages has been sent. I believe when it is sent as: 160 GSM characters = 1 SMS ; 70 Unicode characters = 1 SMS
Columns:
_id
thread_id
address
person
date
date_sent
protocol
read
status
type
reply_path_present
subject
body
service_center
locked
error_code
seen
deletable
hidden
group_id
group_type
delivery_date
app_id
msg_id
callback_number
reserved
pri
teleservice_id
link_url
Thank you for any help in advance.
I haven't tried it yet, but I assume you must check BOM marker in a text if you want to relate to its encoding. Try to read this answer: this
the SmsMessage.calculateLength method does that pretty well !
read the message's body string from the sms content provider
throw that to calculateLength(body, true)
read the results :
result[0] = 'number of SMS's required'
result[1] = 'number of code units used'
result[2] = 'number of code units remaining until the next message'
result[4] = 'encoding type that should be used for the message'
Cheers !
Related
I want to extract the debited amount from the SMS
my sms content is
Cash withdrawal of Rs3,000.00 made on Kotak Debit Card X2694 on 08-01-2020 at #Acoount Number#.Avl bal is Rs 110.32.Not you?Visit kotak.com/fraud. Transactions on non-Kotak ATMs are chargeable beyond 5 per month(3 for Metro locations), if applicable, as per your account variant. Visit www.kotak.com for details.
As suggested by Anunay, regex would solve your issue with a single line.
Personally, I'm a newbie to regex. A naive method I could suggest is to parse the string based on the occurrence of "Rs" and ".".
Then, remove all the (,)commas and convert the String to a float.
messageString = 'Your message as a String'
startIndex = messageString.index('Rs') + 2
endIndex = messageString.index('.') + 3
debitAmount = float(messageString[startIndex: endIndex].replace(',',''))
print(debitAmount)
Sorry, for my Python implementation.
If this is a duplicate, first of all, I'm sorry I've been looking all around and I haven't found how to solve my problem (or my head is too messed up).
I think that is better if I throw my problem rather than explain it.
I have an integer value wich is int234. I convert this value to its hex string representation EA. Note that this is "EA", it is a string.
Then I use Integer.parseInt to convert it to 0xEA (which is an hex value, not hex string) and finally I need the ASCII (or character) representation of this value.
The problem is that when I decode it using Integer.toHexString I get C3AA instead of EA
This is the best explanation I've found. But still I don't know how to solve it..
I hope you can help me out! Thanks in advance!
EDIT
I'd like to transmit the int 234 in a UDP datagram that's why I use the conversions. (This UDP channel mainly sends ASCII ("234") but I want an exception to that and once in a while transmit it in ony 1byte) That's why I do all this conversions (maybe it is easier than this, but I think I'm too close the problem that I can't see it with clarity)
I can confortly do it in C but I need to do it in Java. And my head is going crazy.
So 234 toHexString becomes `hex="EA";
// HEX -> ASCII code
for(int i=0; i<hex.length()-1; i+=2 ){
String output = hex.substring(i, (i + 2));
int decimal = Integer.parseInt(output, 16);
result.append((char)decimal);
}
return result.toString();
As result I get a strange character (the one that #fadden said). Now a question: this value is 2bytes long?
I transmit this odd character and when I use str = Integer.toHexString(prevResult); I get C3AA.
Maybe I'm messing thing up, but what I want is just to transmit 0xEA(byte) and get the int 234 in the other side.
For Example, Let's say I'd like to transmit the word "COMMAND" and append the value 234. Normally I would send "COMMAND234" but now I need the command value to be only one byte long. So the hex representation of what I'd be transmitting would be:
0x67 0x79 0x77 0x77 0x65 0x78 0x68 0xEA
C O M M A N D 234
I need to send a USSD code containing a double value, that represents the balance account amount to be transferred. This value is composed by an integer number, and optionally a decimal separator and 2 more digits. My code looks as follows:
double doubleValue = 0.70;
String phoneNumber = "51234567", pincode = "1234";
String ast = Uri.encode("*");
String baseUssd = ast + "234" + ast + "1" + ast + phoneNumber + ast + pincode + ast;
StringBuilder builder = new StringBuilder();
builder.append(baseUssd);
builder.append(doubleValue); //i.e: 1.35, 0.80
builder.append(Uri.encode("#"));
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + builder.toString()));
startActivity(intent);
My phone treats the doubleValue as 135, 080, etc. ignoring the dot separator character. I hope the final code includes "dot", allowing send the decimal value. Someone solved this problem?
The Java code shown works fine of course assuming that doubleValue is a float or a double.
As suggested here the Intent is handled by OutgoingCallBroadcaster.processIntent() which processes the String given in the Intent by calling PhoneNumberUtils.convertKeypadLettersToDigits() and PhoneNumberUtils.stripSeparators().
The latter one strips everything except numbers, *, #, + and the WILD, WAIT and PAUSE symbols.
This is where your decimal separator is lost.
So either the separator should be escaped to a specific numerical value or substituted by one of the accepted symbols to actually leave your phone and reach the receiver.
Whoever is responsible for the receiving end can probably advice you on properly formatting your decimal number.
Thinking about the way the pinpad, which my bank sent me, works, you always have to enter the two digits after the decimal point and the formatting on the display deals with the position of the point.
So if i enter "1", it is interpreted as 0.01.
Similarly "1023" would be 10.23.
I think the same approach could work nicely for you.
So 1.23 is entered as "123" and 0.80 as "80"
I can't see a reference that limits the characters to 0-9#* but all the examples follow this format. However, your example starts *234, which seems to fit this rule in the specification
Case a) 1, 2 or 3 digits from the set (*, #) followed by 1X(Y), where X=any number 0-4, Y=any number
0-9, then, optionally "* followed by any number of any characters", and concluding with # SEND:
This case is reserved for HPLMN use. When a serving network receives such a message from a
visiting subscriber, it shall pass the USSD message directly to the HPLMN. If it receives it from a
home subscriber, it is up to the network to decide whether to treat it locally or to pass it to the HLR
http://www.etsi.org/deliver/etsi_ts/100600_100699/100625/07.00.00_60/ts_100625v070000p.pdf
In general, I am not sure the HPLMN (Home Public Land Mobile Network) or HLR (Home Location Register) would expect the extra characters, even though the whole character set and even other character sets are allowed in the USSD protocol.
I have been writing an application for Android that receives a response from a cgi-script (python) that access data from a MySQL DB in order to generate dynamic content. I receive the response fine. I am trying to use a python dictionary server-side so that I can respond to the android client with a JSON array. During debugging, if I don't use a dictionary, like this:
with con:
cur = con.cursor()
cur.execute("SELECT * from posts")
rows = cur.fetchall()
print "Content-type: text/html"
print
if cur:
print row[1] #this entry in the DB is a datetime field, however other fields suffer from the same problem
else:
print "Something went wrong."
In that case, I get the response on the android client in a desirable format, such as 2013-06-06 23:03:47.
On the other hand, if I create a dictionary and place the value under a key such as my column name like this:
with con:
cur = con.cursor()
cur.execute("SELECT * from posts")
rows = cur.fetchall()
print "Content-type: text/html"
print
if cur:
for row in rows:
d = {'time':row[1]}
print d
else:
print "Something went wrong."
Then the response I receive has formatting issues. I receive a response like:
{'time':datetime.datetime(2013,6,6.23.3.47)}
The same happens with numbers that I've used Decimal on. Instead of showing as just the number, as they do in a normal print, inside the dictionary (response) they show as:
Decimal('12.345678')
Could anyone with more knowledge than me shed some light on the subject?
Thanks in advance!
When you print inside of a dictionary (or any container), it shows the __repr__ ("code representation") of the object; whereas when you use print directionly, it prints the __str__ (human-readable) representation of the object.
import decimal
mynum = decimal.Decimal('12')
print mynum # 12
print [mynum] # [Decimal('12')
You can see this by adding a print repr line to your code:
if cur:
print repr(row[1]) # will be Decimal...
print row[1] # looks like a number
You can use Decimal exactly like a regular float, except that it maintains complete precision, it makes little difference to any arithmetic you might do to it.
In terms of repr vs. str. The general idea is that str is easy to understand and view, whereas repr is code-oriented and often eval(repr(obj)) == obj would hold.
I'm currently making an SMS viewing application and using the ContentResolver to obtain all SMS messages on the phone (Yes, I understand the risks). Like other applications, I want to group all messages from the same person to one thread, display the latest message from them, and order the contacts by date of the last message.
When it comes to the address values of the incoming messages, they all contain the country code (e.g. +44123456789). But when the user saves his contacts, he could ignore the country code and simply type in the local format. So all outgoing messages are stored as 0123456789.
So, the database will contain the same address in both formats, +44123456789 and 0123456789. How do you match this 2 and remove the duplicate address?
Note:
1) Messages from the same person may not have the same "thread id"
2) There may not be a "contact id"/"display name" value for the address
Actually, messages to and from the same contact are in the same thread, therefore they have the same thread_id. (Apart from multiple recipient messages, which are in their own thread).
By looking in content://sms and storing a list of obtained thread_ids you can make sure there's no duplicates. With the address value you can use the following code to obtain the Display name.
Now, I'm trying to optimise this:
private String quickCallerId(String phoneNumber){
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
ContentResolver resolver=getContentResolver();
Cursor cur = resolver.query(uri, new String[]{PhoneLookup.DISPLAY_NAME}, null, null, null);
if(cur!=null&&cur.moveToFirst()){
String value=cur.getString(cur.getColumnIndex(PhoneLookup.DISPLAY_NAME));
if(value!=null){
cur.close();
return value;
}
}
cur.close();
return "";
}
I don't have the code on me, but it's pretty easy to parse a string from right to left. You could do this and simply set an arbitrary limit on how accurate it must be to stop.
For instance (pseudo-code), given 2 strings (string1 and string2):
if first-char = '+'
len = 9
else
len = length(string1)
end
len = min(len, length(string2))
match = true
for i = len to 1
if substr( string2, i, 1) != substr( string2, i, 1)
match = false
quit
end
i--
end
You could get fancier by checking the characters immediately following the '+' sign to determine the country code, which would let you know how long that country's phone numbers are likely to be.
You would also need to check for people entering numbers as e.g. '(123) 456-7890 x1234' if that's a possibility. So it might be simpler to use some regexp variant...
Rory