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
Iam using Google Retriver API for automatic sms verification, now everthings works fine.
Iam receiving sms message from Broadcast receiver class.
This is my sms message..
<#> Waahan: Your verification code is:1453 jtN03jdhD6p
I want to extract only the otp from the message..
SMSBroadcastReceiver.java
public class SMSBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) {
Bundle extras = intent.getExtras();
Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS);
switch(status.getStatusCode())
{
case CommonStatusCodes.SUCCESS:
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
break;
case CommonStatusCodes.TIMEOUT:
break;
}
}
}
}
I have searched, but every one is using telephony.. iam using retrievel API..
Thanks in advance..
case CommonStatusCodes.SUCCESS:
String message = (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE);
String OTP = message.substring(message.lastIndexOf(":") + 1);
possible using SubString(Start,End) Function
I am trying to insert SMS from a backup but when I ran the code nothing happens no errors or anything and no sms in sms application or inbox.
Also tried add date,read status etc. but didn't work
Have READ and WRITE sms permissions.
minSDK: 23
Here is the code:
public void addSms(String number , String body){
ContentValues values = new ContentValues();
values.put("address", number);
values.put("body", body);
getContentResolver().insert(Uri.parse("content://sms/inbox"),values);
}
and calling addSms from:
for (int i = 0; i < smssJson2.length(); i++) {
try {
JSONObject obj = smssJson2.getJSONObject(i);
String body = obj.getString("message");
String number = obj.getString("number");
addSms(number,body);
} catch (Exception e) {
e.getLocalizedMessage();
}
}
checking inbox with(this code is working):
Uri uriSMSURI = Uri.parse("content://sms/inbox");
Cursor cur = getContentResolver().query(uriSMSURI, null, null, null, null);
while (cur != null && cur.moveToNext()) {
String address = cur.getString(cur.getColumnIndex("address"));
String body = cur.getString(cur.getColumnIndexOrThrow("body"));
JSONObject obj = new JSONObject();
try {
obj.put("number",address);
obj.put("message",body);
Log.d("SMS",obj.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
cur.close();
Solved it!
if app's android version 4.4(KitKat) or higher you have to make your app default messaging app for add sms to SmsProvider or send or receive sms and mms.
and for a backup/restore app you should follow these steps:
1- Change your app as default messaging app.
2- Insert smsses
3- Change default messaging app with previously one.
Resource and for more information HERE!
Yup its only possible once the application is marked as default SMS app, which also need to implement all the default handler classes as mentioned in the artice.
I am new to android i would like to know how to disable receiving notification after application is uninstalled, whether any event or something to detect that app is uninstalled ???
i have tried this but not working for me
if(intent.getAction().equals("android.intent.action.PACKAGE_REMOVED")) {
Intent i = new Intent(context,BootReceiver.class);
Identifier = i.getStringExtra("Recognition_flag");
serverUrl = Constants.urlAll + "uninstall.php";
LongOperation serverRequest = new LongOperation();
// serverRequest.execute(serverUrl, user, pass,
// deviceIMEI);
serverRequest.execute(serverUrl, user);
GCMRegistrar.setRegisteredOnServer(context, true);
Log.e(" BroadcastReceiver ", "onReceive called " + " PACKAGE_REMOVED ");
Toast.makeText(context, " onReceive !!!! PACKAGE_REMOVED", Toast.LENGTH_LONG).show();
}
// when package installed
else if (intent.getAction().equals("android.intent.action.PACKAGE_ADDED")) {
Log.e(" BroadcastReceiver ", "onReceive called " + "PACKAGE_ADDED");
Toast.makeText(context, " onReceive !!!!." + "PACKAGE_ADDED", Toast.LENGTH_LONG).show();
}
You cannot detect app uninstalls on Android in any easy way. The broadcast
android.intent.action.PACKAGE_REMOVED is sent to all the app present in the mobile but yours once the app is removed.
Sure there are ways my company has tracked when the app is uninstalled but thats something very tricky and deep.
I am trying to use GCM for android. After some steps that are provided by developer.google i got the registration id in toast, Now i want to store it in database. How to change here to store it in database. What steps i need to change for this updation???
code
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// checking for type intent filter
if (intent.getAction().equals(config.REGISTRATION_COMPLETE)) {
// gcm successfully registered
// now subscribe to `global` topic to receive app wide notifications
String token = intent.getStringExtra("token");
Toast.makeText(getApplicationContext(), "GCM registration token: " + token, Toast.LENGTH_LONG).show();
} else if (intent.getAction().equals(config.SENT_TOKEN_TO_SERVER)) {
// gcm registration id is stored in our server's MySQL
Toast.makeText(getApplicationContext(), "GCM registration token is stored in server!", Toast.LENGTH_LONG).show();
} else if (intent.getAction().equals(config.PUSH_NOTIFICATION)) {
// new push notification is received
Toast.makeText(getApplicationContext(), "Push notification is received!", Toast.LENGTH_LONG).show();
}
}
};
You can store the GCM token in SharedPreferences itself.
Here is small piece of code that you can add after receiving the token:
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor e = sharedPreferences.edit();
e.putString("GCMTOKEN", token);
e.commit();
And to get the token you can use this,
String token = sharedPreferences.getString("GCMTOKEN", null);
I would recommend you to keep the token as a key-value pair in SharedPreference. You will be able to retrieve and save/update your registration ID with ease using it instead of creating a record in mySQL.
There is an implementation in the top answer in this question. Do take a look.
How to get RegistrationID using GCM in android
You can follow this sample for how to deal with push token registration and refreshing token as well which is an important part
https://github.com/ChamariaUmang/MoEngageDemo
So I'm building a signup procedure that needs the user to verify their phone number by receiving a code by sms. I'm using Parse as the backend system and I'm using Twilio service which comes included in Parse to take care of the sms function. I have been successful in sending the verification code to user's number.
This is my parse cloud code:
var client = require('twilio')('ACb3....', '2b3....');
//Send an SMS text message
Parse.Cloud.define("sendVerificationCode", function(request, response) {
var verificationCode = Math.floor(Math.random()*999999);
client.sendSms({
From: "+61437877758",
To: request.params.phoneNumber,
Body: "Your verification code is " + verificationCode + "."
}, function(err, responseData) {
if (err) {
response.error(err);
} else {
response.success("Success");
}
});
});
This is the code from the app:
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("phoneNumber", userNumber);
ParseCloud.callFunctionInBackground("sendVerificationCode", params, new FunctionCallback<String>() {
public void done(String result, ParseException e) {
if (e == null) {
Log.d("Parse", result);
Intent i = new Intent(SignupActivity.this, PhoneVerificationActivity.class);
startActivity(i);
} else {
Toast.makeText(SignupActivity.this, "there was a problem with connection", Toast.LENGTH_LONG).show();
}
}
});
Now I would like to know how can I send that verification code back to my android app from Parse Cloud after success, so tat I can check the verification code against the code user puts in the EditText
if (err) {
response.error(err);
} else {
*//So the code for sending the verification code back goes here:*
response.success("Success");
}
Do I need to use Json and Rest API?, how can I call and grab this verification code from the app?.
I would really appreciate your help. Thanks.
One way would be to return it in response.success...
response.success({ status: "success", verificationCode: ... });
Another way, a better way, is to not trust the client with this. Store a record of it on an object on the server... When the user enters the validation code, call back into another function to check if it is valid. An example of this type of system can be seen in this old out-dated GitHub login example: https://github.com/ParsePlatform/CloudCodeOAuthGitHubTutorial/blob/master/cloud/main.js#L116