listen for the SMS sent in android activity using Intent ActionSENDTO
I have a problem with Android. Let me explain my feature first. I am trying to implement a referral system in the Android app where users can select the contacts and selecting they will select the submit button which should redirect them to the messaging app and they can select the send button. instead of programmatically sending messages I want the users to send the messages to contacts selected by them. after that, the message can be sent, delivered, ignored, and many more. so I want to get notified of the action of what happened if the messages are delivered then I will send an API call to the server, if not I would just pop up a error message in my current activity. i tried using broadcast receivers and added the pendingintent to the action_sendto intent but I have not received any response even using the broadcast receivers. i will include the code below please have a look at it. please find the issues in my code. also in the onactivityresult function i was getting the requestcode as REQUEST_CODE_SENT when the message is sent but the result is not ok. could you clarify this problem for me. I am new to android so i am not aware of these APIs and how to trigger them please clarify my problems public class NewReferralActivity extends AppCompatActivity implements ReferralContactsAdapter.DataChangedListener { private static final int CONTACTS_PERMISSION_REQUEST_CODE = 100; private static final int CONTACTS_PICKER_REQUEST_CODE = 101; private static final int REQUEST_CODE_READ_CONTACTS = 1; private static final int SMS_PERMISSION_REQUEST_CODE = 102; private static final String SENT_SMS_ACTION = "SMS_SENT_ACTION"; private static final String SMS_DELIVERED_ACTION = "SMS_DELIVERED"; private static final int REQUEST_CODE_SENT = 0; private static final int REQUEST_CODE_DELIVERED = 1; private static final int REQUEST_CODE_SEND_SMS = 2; final Activity context = this; private List selectedContacts = new ArrayList(); private final String referralImageURL = "https://perkz.s3.us-east-2.amazonaws.com/Perkz-Images/grocery/3_0/banner-3.PNG"; private ReferralContactsAdapter referralContactsAdapter; private ArrayList referralCustomers = new ArrayList(); private TextView noReferralText; private Button submitReferralButton; private LoginViewModel loginViewModel; private LoginRepository loginRepository; private int messageSent=0; private int messageDelivered=0; private String message = "Hi, I am using Perkz to order groceries. You can use this app to order groceries and get them delivered to your doorsteps. Please use my referral code to get a discount on your first order. My referral code is: "; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_new_referral); //Register the broadcast receivers registerReceivers(); // intialize the views variables noReferralText = findViewById(R.id.noReferrals); submitReferralButton = findViewById(R.id.submitReferral); //setting up the action listener for the submit button submitReferralButton.setOnClickListener(v -> { if(checkSMSPermission()){ requestSMSPermission(); } else{ sendReferralSMS(); } }); //setting up the action listener for the select contacts button Button selectContactsButton = findViewById(R.id.selectContacts); selectContactsButton.setOnClickListener(v -> { selectDeviceContacts(); }); } @Override protected void onResume() { super.onResume(); referralContactsAdapter.updateItems(referralCustomers); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceivers(); } private final BroadcastReceiver sentStatusReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { System.out.println(SENT_SMS_ACTION); System.out.println(intent.getAction()); switch (getResultCode()) { case RESULT_OK: messageSent++; Toast.makeText(context, "SMS sent", Toast.LENGTH_SHORT).show(); break; case SmsManager.RESULT_ERROR_GENERIC_FAILURE: Toast.makeText(context, "Generic failure", Toast.LENGTH_SHORT).show(); break; case SmsManager.RESULT_ERROR_NO_SERVICE: Toast.makeText(context, "No service", Toast.LENGTH_SHORT).show(); break; case SmsManager.RESULT_ERROR_NULL_PDU: Toast.makeText(context, "Null PDU", Toast.LENGTH_SHORT).show(); break; case SmsManager.RESULT_ERROR_RADIO_OFF:
I have a problem with Android. Let me explain my feature first. I am trying to implement a referral system in the Android app where users can select the contacts and selecting they will select the submit button which should redirect them to the messaging app and they can select the send button. instead of programmatically sending messages I want the users to send the messages to contacts selected by them. after that, the message can be sent, delivered, ignored, and many more. so I want to get notified of the action of what happened if the messages are delivered then I will send an API call to the server, if not I would just pop up a error message in my current activity. i tried using broadcast receivers and added the pendingintent to the action_sendto intent but I have not received any response even using the broadcast receivers. i will include the code below please have a look at it. please find the issues in my code. also in the onactivityresult function i was getting the requestcode as REQUEST_CODE_SENT when the message is sent but the result is not ok. could you clarify this problem for me. I am new to android so i am not aware of these APIs and how to trigger them please clarify my problems
public class NewReferralActivity extends AppCompatActivity implements ReferralContactsAdapter.DataChangedListener {
private static final int CONTACTS_PERMISSION_REQUEST_CODE = 100;
private static final int CONTACTS_PICKER_REQUEST_CODE = 101;
private static final int REQUEST_CODE_READ_CONTACTS = 1;
private static final int SMS_PERMISSION_REQUEST_CODE = 102;
private static final String SENT_SMS_ACTION = "SMS_SENT_ACTION";
private static final String SMS_DELIVERED_ACTION = "SMS_DELIVERED";
private static final int REQUEST_CODE_SENT = 0;
private static final int REQUEST_CODE_DELIVERED = 1;
private static final int REQUEST_CODE_SEND_SMS = 2;
final Activity context = this;
private List selectedContacts = new ArrayList<>();
private final String referralImageURL = "https://perkz.s3.us-east-2.amazonaws.com/Perkz-Images/grocery/3_0/banner-3.PNG";
private ReferralContactsAdapter referralContactsAdapter;
private ArrayList referralCustomers = new ArrayList<>();
private TextView noReferralText;
private Button submitReferralButton;
private LoginViewModel loginViewModel;
private LoginRepository loginRepository;
private int messageSent=0;
private int messageDelivered=0;
private String message = "Hi, I am using Perkz to order groceries. You can use this app to order groceries and get them delivered to your doorsteps. Please use my referral code to get a discount on your first order. My referral code is: ";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_referral);
//Register the broadcast receivers
registerReceivers();
// intialize the views variables
noReferralText = findViewById(R.id.noReferrals);
submitReferralButton = findViewById(R.id.submitReferral);
//setting up the action listener for the submit button
submitReferralButton.setOnClickListener(v -> {
if(checkSMSPermission()){
requestSMSPermission();
}
else{
sendReferralSMS();
}
});
//setting up the action listener for the select contacts button
Button selectContactsButton = findViewById(R.id.selectContacts);
selectContactsButton.setOnClickListener(v -> {
selectDeviceContacts();
});
}
@Override
protected void onResume() {
super.onResume();
referralContactsAdapter.updateItems(referralCustomers);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceivers();
}
private final BroadcastReceiver sentStatusReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println(SENT_SMS_ACTION);
System.out.println(intent.getAction());
switch (getResultCode()) {
case RESULT_OK:
messageSent++;
Toast.makeText(context, "SMS sent", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Toast.makeText(context, "Generic failure", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Toast.makeText(context, "No service", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
Toast.makeText(context, "Null PDU", Toast.LENGTH_SHORT).show();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Toast.makeText(context, "Radio off", Toast.LENGTH_SHORT).show();
break;
}
}
};
private final BroadcastReceiver sentDeliveredReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println(SMS_DELIVERED_ACTION);
System.out.println(intent.getAction());
switch (getResultCode()) {
case RESULT_OK:
messageDelivered++;
if(messageDelivered == selectedContacts.size()){
executeReferralAPI();
}
Toast.makeText(context, "SMS delivered", Toast.LENGTH_SHORT).show();
break;
case RESULT_CANCELED:
Toast.makeText(context, "SMS not delivered", Toast.LENGTH_SHORT).show();
break;
}
}
};
private void selectDeviceContacts() {
if (checkContactsPermission()) {
requestContactsPermission();
} else {
pickContacts();
}
}
private boolean checkContactsPermission(){
return ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED;
}
private void requestContactsPermission(){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, CONTACTS_PERMISSION_REQUEST_CODE);
}
private boolean checkSMSPermission(){
return ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED;
}
private void requestSMSPermission(){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS}, SMS_PERMISSION_REQUEST_CODE);
}
private void pickContacts(){
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, CONTACTS_PICKER_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == CONTACTS_PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
pickContacts();
}
else{
Toast.makeText(this, "Permission Denied to Read Contacts", Toast.LENGTH_SHORT).show();
}
}
else if(requestCode == SMS_PERMISSION_REQUEST_CODE){
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
sendReferralSMS();
}
else{
Toast.makeText(this, "Permission Denied to Send SMS", Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CONTACTS_PICKER_REQUEST_CODE && resultCode == RESULT_OK) {
Uri contactData = data.getData();
if (contactData != null) {
PhoneNumberResult number = readContactInfo(contactData);
if(number!=null){
try {
ObjectMapper mapper = new ObjectMapper();
Invite newContact = new Invite();
newContact.setName(number.getContactName());
newContact.setPhones(new String[]{number.getFormattedNumber()});
CustomerEntity customer = loginRepository.getCustomerEntity();
newContact.setInvitedById(customer.getCustomerId());
HTTPRequestHelper referralContactRequest = new HTTPRequestHelper("/api/invites/checkstatus");
ArrayList newContactList = new ArrayList<>();
newContactList.add(newContact);
InviteeWrapper inviteeWrapper = new InviteeWrapper();
inviteeWrapper.setInvitees(newContactList);
String jsonString = mapper.writeValueAsString(inviteeWrapper);
referralContactRequest.setBody(jsonString);
referralContactRequest.postAsync(this::handleContactData, this::handleContactErrors);
}
catch (Exception e){
handleContactErrors(e);
}
}
}
}
else if(requestCode == REQUEST_CODE_SEND_SMS){
if(resultCode == RESULT_OK){
Log.i("NewReferralActivity", "SMS not sent"+resultCode+requestCode);
Toast.makeText(this, "SMS sent", Toast.LENGTH_SHORT).show();
}
else{
Log.e("NewReferralActivity", "SMS not sent"+resultCode+requestCode);
Toast.makeText(this, "SMS not sent", Toast.LENGTH_SHORT).show();
}
}
else if(requestCode == REQUEST_CODE_SENT){
if(resultCode == RESULT_OK){
Log.i("NewReferralActivity", "SMS not sent"+resultCode+requestCode);
Toast.makeText(this, "SMS sent", Toast.LENGTH_SHORT).show();
}
else{
Log.e("NewReferralActivity", "SMS not sent"+resultCode+requestCode);
Toast.makeText(this, "SMS not sent", Toast.LENGTH_SHORT).show();
}
}
else if(requestCode == REQUEST_CODE_DELIVERED){
if(resultCode == RESULT_OK){
Log.i("NewReferralActivity", "SMS not sent"+resultCode+requestCode);
Toast.makeText(this, "SMS delivered", Toast.LENGTH_SHORT).show();
}
else{
Log.e("NewReferralActivity", "SMS not delivered"+resultCode+requestCode);
Toast.makeText(this, "SMS not delivered", Toast.LENGTH_SHORT).show();
}
}
}
private void handleContactData(String data) {
runOnUiThread(new Runnable() {
@Override
public void run() {
try{
ObjectMapper mapper = new ObjectMapper();
Wrapper wrapper = mapper.readValue(data, Wrapper.class);
ArrayList contacts = mapper.readValue(mapper.writeValueAsString(wrapper.getItems()), new TypeReference>(){});
if(contacts!=null && !contacts.isEmpty()) {
referralContactsAdapter.updateItems(contacts);
}
}
catch (Exception e) {
handleContactErrors(e);
}
}
});
}
private void handleContactErrors(Exception error) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("NewReferralActivity", "Error in fetching contact details", error);
Toast.makeText(NewReferralActivity.this, "Error in fetching contact details", Toast.LENGTH_SHORT).show();
}
});
}
private PhoneNumberResult readContactInfo(Uri contactURI){
String contactName = null;
String contactNumber = null;
Cursor cursor = getContentResolver().query(contactURI, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
int idIndex = cursor.getColumnIndex(ContactsContract.Contacts._ID);
int nameIndex = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
if(idIndex>=0 && nameIndex>=0){
String id = cursor.getString(idIndex);
contactName = cursor.getString(nameIndex);
Log.i("Selected Contacts", "a"+contactName);
cursor.close();
Cursor phoneCursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
if(phoneCursor != null && phoneCursor.moveToFirst()) {
int numberIndex = phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
if(numberIndex>=0) {
contactNumber = formatPhoneNumber(phoneCursor.getString(numberIndex));
Log.i("Selected Contacts", "a"+contactNumber);
}
phoneCursor.close();
}
return new PhoneNumberResult(contactNumber, contactName);
}
else{
cursor.close();
}
}
return null;
}
public static String formatPhoneNumber(String phoneNumber) {
// Remove all non-digit characters
String cleanedPhoneNumber = phoneNumber.replaceAll("[^\\d+]", "");
// If the phone number starts with a '+', ensure it is followed by the country code
return cleanedPhoneNumber;
}
private void sendReferralSMS() {
if (referralCustomers.isEmpty()) {
Toast.makeText(this, "No Referral Contacts to send SMS", Toast.LENGTH_SHORT).show();
return;
}
StringBuilder phoneNumbersStr = new StringBuilder();
for (Invite contact : referralCustomers) {
for (String phone : contact.getPhones()) {
phoneNumbersStr.append(phone).append(";");
}
}
// Remove the last semicolon
phoneNumbersStr.setLength(phoneNumbersStr.length() - 1);
Uri uri = Uri.parse("smsto:" + phoneNumbersStr.toString());
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
intent.putExtra("sms_body", message);
// Create PendingIntents for sent and delivered
PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT_SMS_ACTION), PendingIntent.FLAG_IMMUTABLE);
PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(SMS_DELIVERED_ACTION), PendingIntent.FLAG_IMMUTABLE);
// Attach the PendingIntents to the Intent (this is not standard and may not work on all devices)
intent.putExtra("SENT_SMS_ACTION", sentPI);
intent.putExtra("SMS_DELIVERED_ACTION", deliveredPI);
context.startActivityForResult(intent, REQUEST_CODE_SEND_SMS);
}
private void executeReferralAPI(){
Log.i("Referral", "API call to submit referral");
}
private void registerReceivers(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
registerReceiver(sentStatusReceiver, new IntentFilter(SENT_SMS_ACTION), Context.RECEIVER_NOT_EXPORTED);
registerReceiver(sentDeliveredReceiver, new IntentFilter(SMS_DELIVERED_ACTION), Context.RECEIVER_NOT_EXPORTED);
} else {
registerReceiver(sentStatusReceiver, new IntentFilter(SENT_SMS_ACTION));
registerReceiver(sentDeliveredReceiver, new IntentFilter(SMS_DELIVERED_ACTION));
}
}
private void unregisterReceivers() {
if (sentStatusReceiver != null) {
context.unregisterReceiver(sentStatusReceiver);
}
if (sentDeliveredReceiver != null) {
context.unregisterReceiver(sentDeliveredReceiver);
}
}
@Override
public void onDataChanged(int count){
if(count > 0){
noReferralText.setVisibility(TextView.GONE);
submitReferralButton.setVisibility(Button.VISIBLE);
}
else{
noReferralText.setVisibility(TextView.VISIBLE);
submitReferralButton.setVisibility(Button.GONE);
}
}
}