I have an auto reply sms Android application I built and I don't want the auto reply (sent sms) to show in the default messaging app. I have searched and searched and couldn't find an answer. Is there a way to bypass writing the sent sms into the default messaging app?
Here my BroadcastReciever I am using to get the data and send out the message
public class SmsReceiver extends BroadcastReceiver {
ParseUser user = ParseUser.getCurrentUser();
// Auto reply message composed of the current reply and url from that business
String msg = user.getString("myCurrentReply") + " " + user.getString("couponUrlChosen");
List smsFromList = user.getList("smsFrom");
String userName = (String) user.get("username");
#Override
public void onReceive(final Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Object messages[] = (Object[]) bundle.get("pdus");
SmsMessage smsMessage[] = new SmsMessage[messages.length];
for (int n = 0; n < messages.length; n++) {
smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
}
final String pno = smsMessage[0].getOriginatingAddress();
user.put("lastSmsFrom", pno);
user.saveInBackground();
// show first message
Toast toast = Toast.makeText(context, "Received SMS: " + smsMessage[0].getMessageBody(), Toast.LENGTH_LONG);
toast.show();
// Check Phone Number from SMS Received against Array in User Row
ParseQuery<ParseObject> query = ParseQuery.getQuery("_User");
Log.d("Username: ", userName);
query.whereEqualTo("username", userName);
query.whereContainedIn("lastSmsFrom", smsFromList);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> smsList, ParseException e) {
if (e == null) {
Log.d("Errors", "none");
if (smsList.size() == 0) {
// Send SMS
sendSms(pno, msg);
// Add Phone number to smsFrom in currentUsers Row
user.addUnique("smsFrom", pno);
// Save Phone Number in Array
user.saveInBackground();
Log.d("List size: ", " " + smsList.size());
}
} else {
Log.d("Error Message: ",
e.getMessage());
}
Log.d("Already sent to this number today. ", " " + smsList.size());
}
});
}
private void sendSms(String phonenumber, String message) {
SmsManager manager = SmsManager.getDefault();
manager.sendTextMessage(phonenumber, null, message, null, null);
}
}
Prior to KitKat, SMS sent using SmsManager require the app sending the message to insert it into the Provider, so it would just be a matter of omitting that.
Starting with KitKat, any app that is not the default SMS app and uses SmsManager to send messages will have the messages automatically written to the Provider for it by the system. There's no way to prevent this, and, furthermore, the app won't be able to delete those messages, either, as it won't have write access to the Provider.*
The app that is the default SMS app is responsible for writing its outgoing messages, so it would be able to omit that step. The system does no automatic writes for the default SMS app.
* There is a security hole in 4.4 only, by which a non-default app can gain write access to the Provider. It is detailed in my answer here, but it will not work in versions after KitKat.
Related
I have created an android application that listens for incoming sms. The issue i am encountering is that it also reads previous sms. The goal of the app was to grab sms from a specific originating address and store it in a database.
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Log.i(TAG, "Intent Received: "+intent.getAction());
if (intent.getAction()==SMS_RECEIVED){
Bundle dataBundle = intent.getExtras();
if(dataBundle != null){
//creating PDU protocol Data unit object which is a protocol for transferring message
Object[] mypdu = (Object[])dataBundle.get("pdus");
final SmsMessage[] message = new SmsMessage[mypdu.length];
for(int i =0; i< mypdu.length; i++){
//for build version >= API
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
String format = dataBundle.getString("format");
//From PDU we get all object and smsMessage using following line of code
message[i] = SmsMessage.createFromPdu((byte[])mypdu[i],format);
}else{
message[i] = SmsMessage.createFromPdu((byte[]) mypdu[i]);
}
msg += message[i].getMessageBody().toString().replace("null","");
originatingAddress = message[i].getOriginatingAddress();
}
msg = msg.replace("null","");
if(originatingAddress.trim().equals("MPESA")) {
Toast.makeText(context.getApplicationContext(), "message: " + msg, Toast.LENGTH_SHORT).show();
}
}
}
// throw new UnsupportedOperationException("Not yet implemented");
}
}
Please try with below way
(1)The Simple way you can achieve to store the unique of record on every SMS is timestamp is only unique in this case whenever you get SMS store timestamp of every Sms as a Unique or primary key as you want in database, like system.currentTimeMillisecond to get time of current SMS and store as LONG type Column in your database,
(2) you can also check with unique time on every SMS get but it is complex to check with every existing records
Hope this process will help in your way with prevent of duplicate record store in database
I am creating an SMS manager for KitKat and later version. I have implemented all the receivers as directed in the official doc by android.
I have to receive the SMS SMS_DELIVER broadcast receiver and read it and then have to write to the SMS provider.
till now I am able to read the SMS received. I have set my app as the default SMS app in the device. I am also parsing the SMS and can see it in the log.
problem
I am unable to write the SMS to the SMS provider.
here is the broadcast receiver:
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdusObj = (Object[]) bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[pdusObj.length];
for (int i = 0; i < messages.length; i++) {
String format = bundle.getString("format");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdusObj[i], format);
} else {
messages[i] = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
}
}
for (SmsMessage msg : messages) {
Log.i("log", "display msg body : " + msg.getDisplayMessageBody() + "originating address : " + msg.getDisplayOriginatingAddress() + " get message body : " + msg.getMessageBody());
//here I have to write the message to the sms provider.
}
}
}
}
does anyone have any suggestions? please help me.
Update
i have tried android-kitkat-api-19-how-to-write-messages-in-sms-content-provider-without so question but i am unable to get around it. That solution is for writing to the sent SMS without doing anything like sending the SMS. but I want to write the received SMS here.
Thanks to Mike M. for the help. i got help from this answer - sms-doesnt-save-on-kitkat-4-4-already-set-as-default-messaging-app from SO and this post - kitkat-sms-mms-supports .
here is what i have done :
to write the sms into the sms provider of android system i used content provider. and passed value to it. code snippet is :
ContentValues values = new ContentValues();
values.put(Telephony.Sms.ADDRESS, msg.getDisplayOriginatingAddress());
values.put(Telephony.Sms.BODY, msg.getMessageBody());
context.getApplicationContext().getContentResolver().insert(Telephony.Sms.Sent.CONTENT_URI, values);
this code will save the received sms into the system sms provider and even after your ap is uninstalled other sms app can read it. keep in mind that you need to be the default sms app to do this operation. and you have to provide WRITE_SMS permission in manifest. i have targeted kitkat and versions after it. for previous versions you have to some part of code differently.
the whole SmsReceiver class after completion is :
public class SmsReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdusObj = (Object[]) bundle.get("pdus");
SmsMessage[] messages = new SmsMessage[pdusObj.length];
for (int i = 0; i < messages.length; i++) {
String format = bundle.getString("format");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdusObj[i], format);
} else {
messages[i] = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
}
}
for (SmsMessage msg : messages) {
Log.i("log", "display msg body : " + msg.getDisplayMessageBody() + "originating address : " + msg.getDisplayOriginatingAddress() + " get message body : " + msg.getMessageBody());
ContentValues values = new ContentValues();
values.put(Telephony.Sms.ADDRESS, msg.getDisplayOriginatingAddress());
values.put(Telephony.Sms.BODY, msg.getMessageBody());
context.getApplicationContext().getContentResolver().insert(Telephony.Sms.Sent.CONTENT_URI, values);
}
}
}
}
I had the same problem. You have to register a SMSBroadcaseReceiver, MMSBroadcastReceiver, a QuickreplyService in order to be be able to be set as default SMS receiver.
This helped me:
https://www.androidauthority.com/how-to-create-an-sms-app-part-2-724264/
I try to send message using SmsManager in android i use this code in my application it work fine only some of the device it is not working.
i just make one class for send message
public class Sms {
public static final String TAG = "Sms";
public void sendSms(String number, String message) {
Log.i(TAG, "Sending " + message + " to " + number);
if (message.length() > 159) {
message = message.substring(0, 159);
}
SmsManager.getDefault().sendTextMessage(number, null, message, null,null);
}
}
this class is for send message
i am send using below code
buddys = db.getAllContacts();
for (int i = 0; i < buddys.size(); i++) {
Sms sms = new Sms();
sms.sendSms(buddys.get(i).getPhoneNumber(), msg_);
Toast.makeText(context.getApplicationContext(), ""+msg_+" to "+buddys.get(i).getPhoneNumber(), Toast.LENGTH_SHORT).show();
}
numbers are come from database there are maximum 4 number. it is working fine in gionee , sony , and micromax , and Moto g But not working in samsung device and zenfone . i put the toast for test it also toast the message in all the devices but the problem is only not send the message. i reused the size of message to 160 i think that was the problem but again same problem is occurs please help me.
I am creating an application for android OS, which allows user to send encrypted SMS to other users. But my application has only interface for sending an SMS, not for showing it. When application receives an SMS, I wan't to decrypt it and then somehow to show the decrypted SMS through the bult-in SMS Application. Is there a way to accomplish that? For now my receiver just shows the SMS using Toast.
Here is Receiver's code (It is not full but you will get the idea):
public class SMSReceiver extends BroadcastReceiver{
private static final byte HANDSHAKE_ID = (byte) 120;
private static final byte ENCRYPTED_ID = (byte) 125;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Bundle pudsBundle = intent.getExtras();
Object[] pdus = (Object[]) pudsBundle.get("pdus");
SmsMessage messages = SmsMessage.createFromPdu((byte[]) pdus[0]);
Log.i("Message: ", messages.getMessageBody());
String msgBody = messages.getDisplayMessageBody();
byte[] msgBytes = msgBody.getBytes();
if ( msgBytes[0] == HANDSHAKE_ID ) {
//Obtain secret key from message
//TO-DO
Toast.makeText(context, "Received a secret key from: " + messages.getOriginatingAddress(), Toast.LENGTH_LONG).show();
} else if ( msgBytes[0] == ENCRYPTED_ID ) {
//Obtain encrypted message
//TO-DO
Toast.makeText(context, plainText, Toast.LENGTH_LONG).show();
}
}
Also if it is possible I want to prevent other Apps to see(receive) the message if first byte of the message is one of following constants: HANDSHAKE_ID or ENCRYPTED_ID and visible after decryption? But the main problem that I wan't to solve is how to show plaintext with Android's Built-In SMS Application. Thanks!
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can we delete an SMS in Android before it reaches the inbox?
I've already gotten receive SMS code running successfully. What I cannot determine is a way (or if it's possible) to process messages sent from specific phone numbers within my app without them being made visible to the user. All other SMS's sent from other phone number would be handled by the normal Android SMS processing. I.e., SMS's from selected numbers should not be visible to the phone user and the rest should. Any suggestions?
Here's the SMSReceiver code (taken straight from Wei-Meng Lee's book):
public class SMSReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//get the received SMS message
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = "";
if (bundle != null) {
// retrieve the SMS message
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]);
str += "SMS from " + msgs[i].getOriginatingAddress();
str += "\nMessage Text:\n";
str += msgs[i].getMessageBody().toString();
str += "\nLength="+msgs[i].getMessageBody().toString().length()+"\n";
} // [END FOR]
// display the new SMS message
Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
// send a broadcast intent to update the SMS received in the activity
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("SMS_RECEIVED_ACTION");
broadcastIntent.putExtra("sms", str);
context.sendBroadcast(broadcastIntent);
} // [END IF]
} // [END onReceive]
} // [END SMSReceiver]
well if you put an if before you start concatenating str, you can check the originating address, and compare it to your blacklist of addresses, if its on the list, then simply use the continue to skip the concatenations