2

I implemented so that my Service will run and retrieve SMS from server and send in a thread, but my problem now is that the Sent and Delivered report is not calling my PI. Below is my code, any expert can help me to pinpoint where did I do wrong?

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import android.app.Activity;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.PowerManager;
import android.telephony.SmsManager;
import android.text.format.Time;
import android.widget.Toast;

public class ServiceSMSSender extends Service 
{
    Boolean continueRun = true;
    PowerManager.WakeLock wl;
    WifiLock wifiLock;

    String SENT = "SMS_SENT";
    String DELIVERED = "SMS_DELIVERED";

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
    {          
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TAG");
        wl.acquire();

        WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL, "TAG");
        wifiLock.acquire();

        ConnectionDetector cd = new ConnectionDetector(getApplicationContext());
        if(cd.isConnectingToInternet())
        {  
            //get the center list
            WsConnection wsConn = new WsConnection();
            ObjCenter objCenters[] = wsConn.GetCenterList(getApplicationContext());

            if(objCenters != null)
            {
                ((MyGlobal) this.getApplication()).SetCenterList(objCenters);               

                Intent summaryIntent = new Intent(this, SummaryActivity.class);
                PendingIntent pIntent = PendingIntent.getActivity(this, 0, summaryIntent, Intent.FLAG_ACTIVITY_NEW_TASK);

                Notification mNotification = new Notification.Builder(this)

                .setContentTitle(getString(R.string.txtServiceSMSSender))
                .setSmallIcon(R.drawable.notification_icon)
                .setContentIntent(pIntent)
                .build();

                mNotification.flags |= Notification.FLAG_AUTO_CANCEL;

                startForeground(9999, mNotification);

                final Handler handler = new Handler()
                {
                    @Override
                    public void handleMessage(Message msg) 
                    {
                        super.handleMessage(msg);

                        ObjCenter[] objCenters = ((MyGlobal) getApplication()).GetCenterList();

                        for(int i = 0; i < objCenters.length; i++)
                        {
                            new ExecuteCenterSMSProcessing(objCenters[i]).execute();
                        }                                           

                        System.gc();
                    }
                };
                new Thread(new Runnable(){
                    public void run() {

                        do
                        {
                            try 
                            {
                                handler.sendEmptyMessage(0);

                                Thread.sleep(5000); //2 minutes                     
                            } 
                            catch (InterruptedException e)
                            {    
                                e.printStackTrace();
                            } 

                        }while(continueRun);
                    }
                }).start(); 

                return Service.START_STICKY;
            }
        }

        stopForeground(true);
        stopSelf();

        return Service.START_NOT_STICKY;           
    }

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

    @Override
    public void onDestroy() 
    {       
        continueRun = false;

        stopForeground(true);

        wl.release();
    }

    private class ExecuteCenterSMSProcessing extends AsyncTask<Void, Void, Void>
    { 
        ObjCenter objCenter;

        public ExecuteCenterSMSProcessing(ObjCenter objCenter) 
        {   
            this.objCenter = objCenter;
        }

        protected Void doInBackground(Void... params) 
        {                       
            WsMessagePool wsMessagePool = new WsMessagePool();

            ObjMessagePool[] objMessagePools = wsMessagePool.GetUnsentMessage(getApplicationContext(), objCenter.centerId);

            if(objMessagePools != null)
            {
                for(int i = 0; i < objMessagePools.length; i++)
                {                                       
                    SmsManager smsManager = SmsManager.getDefault();

                    ArrayList<PendingIntent> sentPendingIntents = new ArrayList<PendingIntent>();
                    ArrayList<PendingIntent> deliveredPendingIntents = new ArrayList<PendingIntent>();

                    Intent intentSent = new Intent(getApplicationContext(), SmsSentReceiver.class);
                    Intent intentDelivered = new Intent(getApplicationContext(), SmsDeliveredReceiver.class);

                    intentSent.putExtra("messagePoolId", objMessagePools[i].messagePoolId);
                    intentDelivered.putExtra("messagePoolId", objMessagePools[i].messagePoolId);

                    intentSent.putExtra("centerId", objCenter.centerId);
                    intentDelivered.putExtra("centerId", objCenter.centerId);

                    PendingIntent sentPI = PendingIntent.getBroadcast(getApplicationContext(), 0, intentSent, 0);
                    PendingIntent deliveredPI = PendingIntent.getBroadcast(getApplicationContext(), 0, intentDelivered, 0);

                    //check and manage Unicode
                    String message = null;
                    if (!MyGlobal.HasUnicode(objMessagePools[i].message))
                    {
                        try
                        {
                            byte[] utf16 = objMessagePools[i].message.getBytes("UTF-16");
                            message = new String(utf16, "UTF-16");
                        }
                        catch (UnsupportedEncodingException ex)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        message = objMessagePools[i].message;
                    }

                    ArrayList<String> msgArray = smsManager.divideMessage(message);

                    for (int j = 0; j < msgArray.size(); j++) 
                    {
                        sentPendingIntents.add(j, sentPI);
                        deliveredPendingIntents.add(j, deliveredPI);
                    }

                    intentSent.putExtra("noOfUnit", msgArray.size());

                    smsManager.sendMultipartTextMessage(objMessagePools[i].recipientMobileNo, null, msgArray, sentPendingIntents, deliveredPendingIntents);                 
                }
            }

            return null;
        }
    }
}

Then I created 2 classes for the receiver

public class SmsDeliveredReceiver extends BroadcastReceiver 
{
    public final int SUPER_SMS_STATUS_SUCCESS = 2002;
    public final int SUPER_SMS_STATUS_DELIVERY_FAILED = 2007;

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        int messagePoolId = intent.getIntExtra("messagePoolId", 0);
        int centerId = intent.getIntExtra("centerId", 0);

        if(messagePoolId != 0)
        {
            WsMessagePool wsMessagePool = new WsMessagePool();

            switch (getResultCode()) 
            {
                case Activity.RESULT_OK:

                    wsMessagePool.UpdateDeliveryReport(context, centerId, messagePoolId, SUPER_SMS_STATUS_SUCCESS);

                    break;

                case Activity.RESULT_CANCELED:

                    wsMessagePool.UpdateDeliveryReport(context, centerId, messagePoolId, SUPER_SMS_STATUS_DELIVERY_FAILED);

                    break;
            }
        }
    }
}

And also

public class SmsSentReceiver extends BroadcastReceiver 
{
    public final int SUPER_SMS_STATUS_SENT = 2001;
    public final int SUPER_SMS_STATUS_GENERIC_ERROR = 2003;
    public final int SUPER_SMS_STATUS_NO_SERVICE = 2004;
    public final int SUPER_SMS_STATUS_NULL_PDU = 2005;
    public final int SUPER_SMS_STATUS_RADIO_OFF = 2006;

    @Override
    public void onReceive(Context context, Intent intent) 
    {
        int messagePoolId = intent.getIntExtra("messagePoolId", 0);
        int centerId = intent.getIntExtra("centerId", 0);
        int noOfUnit = intent.getIntExtra("noOfUnit", 0);

        if(messagePoolId != 0)
        {
            WsMessagePool wsMessagePool = new WsMessagePool();

            switch (getResultCode()) 
            {
                case Activity.RESULT_OK:

                    wsMessagePool.UpdateStatus(context, centerId, messagePoolId, true, SUPER_SMS_STATUS_SENT, noOfUnit);

                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:

                    wsMessagePool.UpdateStatus(context, centerId, messagePoolId, false, SUPER_SMS_STATUS_GENERIC_ERROR, noOfUnit);

                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:

                    wsMessagePool.UpdateStatus(context, centerId, messagePoolId, false, SUPER_SMS_STATUS_NO_SERVICE, noOfUnit);

                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:

                    wsMessagePool.UpdateStatus(context, centerId, messagePoolId, false, SUPER_SMS_STATUS_NULL_PDU, noOfUnit);

                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:

                    wsMessagePool.UpdateStatus(context, centerId, messagePoolId, false, SUPER_SMS_STATUS_RADIO_OFF, noOfUnit);

                    break;
            }
        }
    }
}
TPG
  • 2,811
  • 1
  • 31
  • 52

2 Answers2

1

Found the reason, did not register the receiver. Added below line and work like a charm now.

getApplicationContext().registerReceiver(new SmsSentReceiver(), new IntentFilter(SMS_SENT));
getApplicationContext().registerReceiver(new SmsDeliveredReceiver(), new IntentFilter(SMS_DELIVERED));
TPG
  • 2,811
  • 1
  • 31
  • 52
0

Man this is a loooong code. this line:

smsManager.sendMultipartTextMessage(objMessagePools[i].recipientMobileNo, null, msgArray, sentPendingIntents, deliveredPendingIntents);

Would have sufficed.

Ok, now I will assume you have already debugged the app and placed breakpoints in your receivers that were never hit. If so, most likely you forgot to include the receivers in the manifest.

Other than this, I'd check the flags in the pending intent. Some flags cause old intents to be delivered.

Mister Smith
  • 27,417
  • 21
  • 110
  • 193