About android SMS port - android

I want implement an app which receives SMS on a specific port.
Manifest Code:
<receiver android:name=".BinarySMSReceiver">
<intent-filter>
<action android:name="android.intent.action.DATA_SMS_RECEIVED"/>
<data android:port="8091"/>
<data android:scheme="sms"/>
</intent-filter>
</receiver>
And receiver class code below.
public class BinarySMSReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
if(null != bundle)
{
String info = "Binary SMS from ";
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
byte[] data = null;
for (int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
info += msgs[i].getOriginatingAddress();
info += "\n*****BINARY MESSAGE*****\n";
data = msgs[i].getUserData();
for(int index=0; index<data.length; ++index)
{
info += Character.toString((char)data[index]);
}
}
Toast.makeText(context, info, Toast.LENGTH_SHORT).show();
}
}
}
I am getting all SMS which are on this (8091) port or not. I want to receive only those messages which are port specific.

For those who are still wondering why the app is receiving data SMS directed to other ports and not just to port 8091. The problem lies in the Manifest code. I've seen many solutions that were posted and most of them are actually wrong.
The Manifest should be :
<receiver
android:name = ".SmsReceiver">
<intent-filter>
<action android:name="android.intent.action.DATA_SMS_RECEIVED" />
<data
android:scheme="sms"
android:host="*"
android:port="8095" />
</intent-filter>
</receiver>
The scheme, host and port attributes must be defined in only one "data" element of the intent-filter, not in separate "data" elements.
Also not that from this link, under "data test" section it states that
"The host and port together constitute the URI authority; if a host is not specified, the port is ignored."
So keep in mind that you need to specify the host if you want the app to receive the data SMS for only a specific port.
The "host" element is * (asterisk) is to specify that it accepts data SMS from all hosts / phone numbers
Hope this helps someone (:

I had similar problem, just add following check condition at begin of your 'onReceive' code:
String dataStr = intent.getDataString();
if (dataStr.indexOf(":8888" ) == -1) {
return;
}

Related

Unable to find SMS permission in android studio

I am unable to find android.provider.Telephony action in android studio for creating an app that can receive SMS. Almost every article including android developer says that I have to include a intent filter action android.provider.Telephony.SMS_RECEIVE in manifest file. But I figured out that this action is no more supported by android studio. Please help me
You need to give the permission to your manifest file,
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
Then you should include the intent-filter to your manifest,You should have taken a class that extends BroadcastReceiver write the name of that class as receiver name.In my case it is SMSReceivcer.
<receiver android:name=".SMSReceivcer"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
pls try this
// Add this in manifest
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<receiver android:name=".SMSReciver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
//Create new class
public class SMSReciver extends BroadcastReceiver
{
private Context mContext;
#Override
public void onReceive(Context context, Intent intent)
{
mContext = context;
Bundle myBundle = intent.getExtras();
SmsMessage[] messages = null;
String strMessage = "";
String lMessageBody = "", lMessageFrom = "";
if (myBundle != null)
{
Object[] pdus = (Object[]) myBundle.get("pdus");
messages = new SmsMessage[pdus.length];
for (int i = 0; i < messages.length; i++)
{
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
lMessageFrom = messages[i].getOriginatingAddress();
lMessageBody = messages[i].getMessageBody();
}
}
}
}

how to get receiver phone number from sms application? [duplicate]

Is it possible in android to filter the SMS from a specific number in android.And save it in a specific database.and the SMS should not be visible in the inbox...
You have yo do this in 3 step:
read SMS from Specific number you have to look in to this link then after
you have to create Database for store all info about SMS(like id, body, number, time) for that check this link
you have to Delete SMS from INBOX check this link for delete SMS.
add below permission for do all step:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
ya is it possible.
in mainfest file add following code:
<receiver android:name="com.example.Sms_BReceiver" >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
after that create a class use following code
public class Sms_BReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
SmsMessage[] messageString = null;
Object[] pdus = (Object[]) bundle.get("pdus");
messageString = new SmsMessage[pdus.length];
for (i = 0; i < messageString.length; i++) {
messageString[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
Phone_no = messageString[0].getOriginatingAddress();
Message_body = messageString[0].getMessageBody();
Time = messageString[0].getTimestampMillis();
CharSequence text = str;
Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
}
if (Phone_no.contains(here check no to filter) {
here delete message form inbox
and save in our own db
} else {
}
}
i hope this code will use full for u

Is it possible to read incoming sms and reply back only to specific or desire number

Is it possible to read incoming sms and reply back only to specific or desire number. i-e i want to make app that will run in back ground ... whenever i will send sms with my number it will automatically respond back to me with XYZ information
Yes, it's possible. You need to add a BroadcastReceiver in your app that will intercept incoming SMS messages and then send a message if it matches the number you're looking for.
Following source code from:
BroadcastReceiver + SMS_RECEIVED
http://shreymalhotra.me/blog/tutorial/receive-sms-using-android-broadcastreceiver-inside-an-activity/
In AndroidManifest.xml:
<receiver android:name=".SMSReceiver">
<intent-filter android:priority="999">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
In a new file called SMSReceiver.java:
public class SMSReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
// get SMS data, if bundle is null then there is no data so return
Bundle extras = intent.getExtras();
if (extras == null) return;
// extract SMS data from bundle
Object[] pdus = (Object[]) extras.get("pdus");
for (int i = 0; i < pdus.length; i++) {
SmsMessage SMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
String sender = SMessage.getOriginatingAddress();
String body = SMessage.getMessageBody().toString();
// if there's an SMS from this number then send
if(sender.equals("+1800555555") {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(sender, null, "sms received", null, null);
}
}
}
}

Broadcast Receiver Long Binary SMS

I have a problem when receiving a long binary SMS. The client is supposed to receive multipart binary SMS. Upon searching stackoverflow, people have mentioned that onReceive() shall be fired only once. From there you can concatenate the multiple SMS.
I am not sure if that's the same when sending binary SMS. I receive 2 SMS, and onReceive is fired twice. The SMS are separate from each other making it impossible to concatenate.
AndroidManifest:
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.INTERNET" />
<receiver
android:name="com.myapp.smsnotification.SMSReceiver"
android:enabled="true" >
<intent-filter android:priority="100" >
<action android:name="android.intent.action.DATA_SMS_RECEIVED" />
<data
android:host="localhost"
android:port="9515"
android:scheme="sms" />
</intent-filter>
</receiver>
SMSReceiver.java
in my onReceive()
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
try {
if (messages.length > -1) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
for (int i = 0; i < messages.length; i++) {
SmsMessage message = messages[i];
os.write(message.getUserData());
}
byte[] stream = os.toByteArray();
// do something with stream
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
Found out that it was not an issue with the client side but in the server side. They didn't include in the User Data Header the part to indicate that the message is a concatenated SMS.
If the protocol is followed, Android will be able to detect it and handle them accordingly, waiting for all SMS to arrive and fire the SMS broadcast receiver once containing all received SMS.

how to make sure sms sent by my app is only received by a phone with my app installed

I am writing an app that has a feature of sending and receiving SMS messages. I would like SMS messages sent by my app be only received by another phone with my app installed and not reach phone's native SMS app. The only solution I found so far is to set high priority to android:priority in Manifest file:
<receiver android:name=".SMSreceiver">
<intent-filter android:priority="100">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
and put this.abortBroadcast() statement in onReceive method to the class that extends BroadcastReceiver:
public class SMSreceiver extends BroadcastReceiver
{
private final String CODE = "myappcodeword";
#Override
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String from = "";
String str = "";
String sms = "";
if (bundle != null)
{
Object [] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i = 0; i<msgs.length; i++)
{
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
if (i == 0)
{
from = msgs[i].getOriginatingAddress();
}
str += msgs[i].getMessageBody().toString();
}
if (str.startsWith(CODE)) // SMS starts with code word therefore was sent by my app
{
sms = str.substring(CODE.length()); // extract code word from actual sms message
Intent SMSIntent = new Intent(context, SMSActivity.class);
SMSIntent.putExtra("from", from);
SMSIntent.putExtra("sms", sms);
SMSIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(SMSIntent); // start new activity using sms info
this.abortBroadcast();
}
}
}
}
Since of course I don't want to block SMS not intended for my app, I thought of starting SMS messages sent by my app by some kind of key word. My question is, is there a better solution than this? (For example, user might theoretically actually send SMS to somebody containing key word on purpose no matter how random the key word is and my app would filter it out). Also above code will not filter out the SMS sent by my app if the phone the SMS is sent to does not have my app installed. Is there a way to find out first if the phone SMS is being send to has my app installed? If the app is not installed then I would like the SMS not even show up on that phone.
you might want to look at GCM, allows you to target your application running on targeted devices based on your need.
Google Cloud Messaging for Android
No, you cannot use SMS as a carrier for the scenario you describe. Remember that SMS is a store and forward service (in that respect similar to email) and the mobile operator might be storing the message for a long time (days is possible) if the recipient is not turned on or out of coverage (at some point it will be discarded, but that is up till the operator to decide).

Categories

Resources