-1

I am currently using a service to get the delivery and sent report for the SMS. I want to know how to setup the receiver so that I can get "delivery" & "sent" reports without any foreground service. My app is set as default-app, please let me know if any more detail is required.

I have been searching for the solution for a long time but could not get any clue, any insight will be highly welcome!

Thanks!

   public class SendMySMS extends Service {

    int count = 0;
    public static final String PRIMARY_NOTIF_CHANNEL = "default";
    public static final int PRIMARY_FOREGROUND_NOTIF_SERVICE_ID = 1009;

    BroadcastReceiver sendReceiver;
    BroadcastReceiver deliveryReceiver;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        if (intent!=null) {
            String str_number = intent.getStringExtra("KEY_number");
            String str_body = intent.getStringExtra("KEY_body");
            String str_subId = intent.getStringExtra("KEY_sub_id");

            sendSMS(str_number, str_body, str_subId);
        }
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            NotificationChannel chan1 = new NotificationChannel(PRIMARY_NOTIF_CHANNEL, "Background", NotificationManager.IMPORTANCE_NONE);
            chan1.setLightColor(Color.TRANSPARENT);
            chan1.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
            notificationManager.createNotificationChannel(chan1);

            Intent intent1 = new Intent(this, MainActivity.class);
            intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);

            Notification notification = new NotificationCompat.Builder(this, PRIMARY_NOTIF_CHANNEL)
                    .setSmallIcon(R.drawable.ic_sms_notif)
                    .setContentTitle("Waiting for delivery report..")
                    .setPriority(NotificationCompat.PRIORITY_MIN)
                    .setAutoCancel(true)
                    .build();
            startForeground(PRIMARY_FOREGROUND_NOTIF_SERVICE_ID, notification);
        }
    }


    @Override
    public void onDestroy() {
        try {
            unregisterReceiver(sendReceiver);
            unregisterReceiver(deliveryReceiver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sendSMS(final String mobNo, String message, String subId) {

        sendReceiver = new SendReceiver();
        deliveryReceiver = new DeliveryReceiver();

        String smsSent = "SMS_SENT"+msgId;
        String smsDelivered = "SMS_DELIVERED"+msgId;

        Intent sentIntent = new Intent(smsSent);
        sentIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
        sentIntent.putExtra("key_msg_id", msgId);
        sentIntent.putExtra("key_number", mobNo);
        PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, sentIntent, PendingIntent.FLAG_ONE_SHOT);

        Intent deliveryIntent = new Intent(smsDelivered);
        deliveryIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
        deliveryIntent.putExtra("key_msg_id", msgId);
        deliveryIntent.putExtra("key_number", mobNo);
        PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, deliveryIntent, PendingIntent.FLAG_ONE_SHOT);

        registerReceiver(sendReceiver, new IntentFilter(smsSent));
        registerReceiver(deliveryReceiver, new IntentFilter(smsDelivered));

        SmsManager.getSmsManagerForSubscriptionId(Integer.parseInt(subId)).sendTextMessage(mobNo, null, message, sentPI, deliveredPI);

    }

    class SendReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context arg0, Intent arg1) {
            
            Bundle bundle = arg1.getExtras();
            String msgId1="";
            String number="";
            
            if (bundle!=null) {
                msgId1 = bundle.getString("key_msg_id");
                number = bundle.getString("key_number");
            }
            
            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "SMS sent", Toast.LENGTH_LONG).show();
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    Toast.makeText(getBaseContext(), "Generic failure", Toast.LENGTH_LONG).show();
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    Toast.makeText(getBaseContext(), "No service", Toast.LENGTH_LONG).show();
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_LONG).show();
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_LONG).show();
                    break;
                default:
                    Toast.makeText(getBaseContext(), "Unknown-"+getResultCode(), Toast.LENGTH_LONG).show();
            }
        }
    }

    class DeliveryReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context arg0, Intent arg1) {
            
            Bundle bundle = arg1.getExtras();
            String msgId1="";
            String number="";

            if (bundle!=null) {
                msgId1 = bundle.getString("key_msg_id");
                number = bundle.getString("key_number");
            }

            switch (getResultCode()) {
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "SMS delivered", Toast.LENGTH_LONG).show();
                    count--;
                    if (count==0){
                        stopSelf();
                    }
                    break;
                case Activity.RESULT_CANCELED:
                    Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_LONG).show();
                    count--;
                    if (count==0){
                        stopSelf();
                    }
                    break;
                default:
                    Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_LONG).show();
                    count--;
                    if (count==0){
                        stopSelf();
                    }
                    break;
            }
        }
    }
}
Ole Pannier
  • 3,208
  • 9
  • 22
  • 33
Deepa
  • 56
  • 3
  • 1
    You should be able to have your pending intent trigger broadcast receivers. If you tried it and it didn't work it's probably because your intents are implicit. If your broadcast receivers are declared in the manifest then modify your pending intents so they are explicit: `sentIntent.setClass(this, SendReceiver.class)`. – Pawel Aug 15 '21 at 10:42
  • Thanks @Pawel for the clue, luckily I have found below link also which clarified for pending intents definition and setting up the receiver class. https://stackoverflow.com/questions/12781383/differentiating-delivery-reports-of-two-separate-smss ... I have documented detail in my answer below. – Deepa Aug 18 '21 at 03:23

1 Answers1

0

I have found solution at Differentiating delivery reports of two separate SMS's ... Below is complete working code for reference.

public class SendMySMS extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        if (intent!=null) {
            String str_number = intent.getStringExtra("KEY_number");
            String str_body = intent.getStringExtra("KEY_body");
            String str_subId = intent.getStringExtra("KEY_sub_id");

            sendSMS(str_number, str_body, str_subId);
        }
        return START_STICKY;
    }

    public void sendSMS(final String mobNo, String message, String subId) {

        long tsLong = System.currentTimeMillis();
        String ts = Long.toString(tsLong);

        ContentValues values = new ContentValues();
        values.put("address", mobNo);
        values.put("body", message);
        values.put("sub_id", subId);
        values.put("date_sent", ts);
        values.put("status", "-1");
        values.put("error_code", "2");
        getApplicationContext().getContentResolver().insert(Uri.parse("content://sms/sent"), values);

        String msgId="";
        String[] reqCols = new String[] {"_id", "address", "date_sent"};
        Uri uriMsg = Uri.parse(String.valueOf(Telephony.Sms.CONTENT_URI));
        ContentResolver cr = this.getContentResolver();
        Cursor c = cr.query(uriMsg, reqCols, null, null, null);

        assert c != null;
        int totalSMS = Math.min(c.getCount(), 10);

        if (c.moveToFirst()) {
            for (int i=0; i<totalSMS; i++) {
                if (c.getString(c.getColumnIndexOrThrow("date_sent")).equals(ts) && c.getString(c.getColumnIndexOrThrow("address")).equals(mobNo)) {
                    msgId = c.getString(0);
                    break;
                }else{
                    msgId="not_found";
                }
                c.moveToNext();
            }
        }
        c.close();

        String smsSent = "SMS_SENT"+msgId;
        String smsDelivered = "SMS_DELIVERED"+msgId;
        
        Intent sentIntent = new Intent(getBaseContext(), SendReceiver.class);
        sentIntent.setAction(smsSent);
        sentIntent.putExtra("key_msg_id", msgId);
        sentIntent.putExtra("key_number", mobNo);
        PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, sentIntent, PendingIntent.FLAG_ONE_SHOT);
        
        Intent deliveryIntent = new Intent(getBaseContext(), DeliveredReceiver.class);
        deliveryIntent.setAction(smsDelivered);
        deliveryIntent.putExtra("key_msg_id", msgId);
        deliveryIntent.putExtra("key_number", mobNo);
        PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, deliveryIntent, PendingIntent.FLAG_ONE_SHOT);
        
        SmsManager.getSmsManagerForSubscriptionId(Integer.parseInt(subId)).sendTextMessage(mobNo, null, message, sentPI, deliveredPI);
    }
}

Receivers:

public class SendReceiver extends BroadcastReceiver {
    
    @Override
    public void onReceive(Context arg0, Intent arg1) {
    
        Bundle bundle = arg1.getExtras();
        String msgId1="";
        String number="";
    
        if (bundle!=null) {
            msgId1 = bundle.getString("key_msg_id");
            number = bundle.getString("key_number");
        }
    
        switch (getResultCode()) {
            case Activity.RESULT_OK://-1
                Toast.makeText(arg0, "SMS sent", Toast.LENGTH_LONG).show();
                break;
            case SmsManager.RESULT_ERROR_GENERIC_FAILURE: //1
                Toast.makeText(arg0, "Generic failure", Toast.LENGTH_LONG).show();
                break;
            case SmsManager.RESULT_ERROR_NO_SERVICE://4
                Toast.makeText(arg0, "No service", Toast.LENGTH_LONG).show();
                break;
            case SmsManager.RESULT_ERROR_NULL_PDU://3
                Toast.makeText(arg0, "Null PDU", Toast.LENGTH_LONG).show();
                break;
            case SmsManager.RESULT_ERROR_RADIO_OFF://2
                Toast.makeText(arg0, "Radio off", Toast.LENGTH_LONG).show();
                break;
            case SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED://8
            case SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED://7
                Toast.makeText(arg0, "Can't send to Short code", Toast.LENGTH_LONG).show();
                break;
            case 17:
                Toast.makeText(arg0, "No balance!", Toast.LENGTH_LONG).show();
                break;
            default:
        }
    }
}

public class DeliveredReceiver extends BroadcastReceiver {
    
    @Override
    public void onReceive(Context arg0, Intent arg1) {
    
        Bundle bundle = arg1.getExtras();
        String msgId1="";
        String number="";
    
        if (bundle!=null) {
            msgId1 = bundle.getString("key_msg_id");
            number = bundle.getString("key_number");
    
            Object pdu = Objects.requireNonNull(arg1.getExtras()).get("pdu");
            SmsMessage message = SmsMessage.createFromPdu((byte[]) pdu);
            int status = message.getStatus();
    
            if (status!=0) {
                Toast.makeText(arg0, "SMS not delivered", Toast.LENGTH_LONG).show();
                return;
            }
        }
    
        switch (getResultCode()) {
            case Activity.RESULT_OK:
                Toast.makeText(arg0, "SMS delivered", Toast.LENGTH_LONG).show();
                break;
            case Activity.RESULT_CANCELED:
                Toast.makeText(arg0, "SMS not delivered", Toast.LENGTH_LONG).show();
                break;
            default:
                Toast.makeText(arg0, "SMS not delivered (Error-100)", Toast.LENGTH_LONG).show();
                break;
        }
    }
}

Manifest:

    <receiver android:name=".SendReceiver" />
    <receiver android:name=".DeliveredReceiver" />
Deepa
  • 56
  • 3