0

I am making an app which makes use of a broadcast receiver for obtaining specific sms messages that are received in the phone. The sms messages which are to be fetched by the broadcast receiver contain "!test!" in them, and are then sent to the server through an HTTP post. This procedure functions properly on certain mobile phones, while on others it does not(though sometimes it does).

The problems lies in the broadcast receiver not being activated. According to the research which I have conducted recently, this issue seems to arise when a broadcast receiver with a higher priority obtains the sms broadcast first and then aborts it, preventing it from being delivered to other phones. Some of the solutions provided where to set the priority of intent filter to 999 or 1000. However this did not eventually fix the issue.

Also I have read that from android version 4.4 and above aborting a broadcast is not allowable, though I still seem to be facing the similar issue on such android versions also.

Even though I am aware that this is intrinsically much more related with some of the faults present with the Android OS, I have for convenience provided some code snippets. I would like to know whether there might be some approaches which could somehow tackle such an issue. And if not what would be the adviseful suggestions to take into consideration ?

Registering a receiver pro grammatically within the on create method.

registerReceiver(smsreceiver, new    IntentFilter("android.provider.Telephony.SMS_RECEIVED"));

On recieve procedure:

 private BroadcastReceiver smsreceiver = new BroadcastReceiver()
{
    @Override


    public void onReceive(Context context, Intent intent)
    {
        Bundle bundle = intent.getExtras();        
        SmsMessage[] msgs = null;

        String phonenumber = " ";
        String msg = " ";

        if(null != bundle)
        {
            String info = "Text SMS from ";
            Object[] pdus = (Object[]) bundle.get("pdus");
            msgs = new SmsMessage[pdus.length];
            String info1 = "";
            for (int i=0; i<msgs.length; i++){
                msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);                
                info += msgs[i].getOriginatingAddress();  
                phonenumber = msgs[i].getOriginatingAddress();  
                info += "\n*****TEXT MESSAGE*****\n";
                info += msgs[i].getMessageBody().toString();
                //msg = msgs[i].getMessageBody().toString();

                msg += msgs[i].getMessageBody().toString();

                info1 = "";
                if (msgs[i].getServiceCenterAddress()!=null)
               // info1 = info1 + " Service Center:" + msgs[i].getServiceCenterAddress().toString();


               //  info1 = info1 + " Protocol identifier:" + msgs[i].getProtocolIdentifier();
               //  info1 = info1 + " Time stamp in milisec:" + msgs[i].getTimestampMillis();


                // info1 = info1 + "=" + msgs[i].getServiceCenterAddress().toString();

                 info1 =  msgs[i].getServiceCenterAddress().toString();

                 info1 = info1 + "=" + msgs[i].getProtocolIdentifier();
                 info1 = info1 + "=" + msgs[i].getTimestampMillis();

                 long milliSeconds = msgs[i].getTimestampMillis();
                 // milliSeconds is the time of real message it is datestam in miliseconds 



                 Calendar calendar = Calendar.getInstance();
                 // this shoule be the DateTime on moible when the message is recived 
                 //long timeNow= System.currentTimeMillis();

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

                 //calendar.getTimeInMillis().setTimeInMillis(milliSeconds);

                 //int mYear = calendar.get(Calendar.YEAR);
                 //int mMonth = calendar.get(Calendar.MONTH);
                 //int mDay = calendar.get(Calendar.DAY_OF_MONTH);

                // int mHour = calendar.get(Calendar.HOUR);
                // int mMin = calendar.get(Calendar.MINUTE);
                // int mSec = calendar.get(Calendar.SECOND);

                 //2015-09-11 23:09:10
                 // Y-  m-  d      H: i: s

                // String totalDateTime = Integer.toString(mYear) + "-" + Integer.toString(mMonth)+ "-"+ Integer.toString(mDay) + " " + Integer.toString(mHour) + ":" + Integer.toString(mMin)+ ":"+ Integer.toString(mSec);
                 String totalDateTime = ts; // this should be the time from the phone when SMS is received

                 info1 = info1 + "=" + totalDateTime;

            }

            // HERE make the new comment next line LINE COMMNET 
           //    Toast.makeText(context, info, Toast.LENGTH_SHORT).show();
            info = phonenumber + "_"+ msg;
           // msg = msg.toLowerCase();
            if (msg.contains("!test!")==true)
           // {
           //  Toast.makeText(context, "location in msg", Toast.LENGTH_SHORT).show();
           // }
           // else
            {
                // here to o http to web php to save the data
              Toast.makeText(context, info, Toast.LENGTH_SHORT).show();
              txtName = (TextView) findViewById(R.id.name);
              String phonenumberRec = txtName.getText().toString();


              String codeofsender = msg.substring(6, 11); 

              String all = phonenumberRec + "|"+msg+"|"+phonenumber+"|"+codeofsender+"|"+info1;


              ConnectivityManager cm =
                        (ConnectivityManager)getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);

                NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
                boolean isConnected = activeNetwork != null &&
                                      activeNetwork.isConnectedOrConnecting();




                //StringEntity allF = new StringEntity(all, "UTF-8");
                //

                String _data = GetDateTimeWithProcedure("In SMS before network connected ");
                WriteToLogTextFile(_data);

                if (isConnected)
                {
                    String _data1 = GetDateTimeWithProcedure("In SMS network connected ");

                    if (activeNetwork != null && activeNetwork.isConnected() && activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
                    {
                        _data1 = "WIFI " + _data1;       
                    }  

                    if (activeNetwork != null && activeNetwork.isConnected() && activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
                    {
                        _data1 = "Mobile Network " + _data1;       
                    } 

                    WriteToLogTextFile2(_data1);

                     new MyAsyncTask().execute(all);
                }


             // String res = postDataToWebServer(phonenumberRec,msg,phonenumber,codeofsender, info1);

            }

        }                         
    }
};

Defining receiver in android manfiest.xml:

 <receiver android:name=".smsreceiver">
        <intent-filter android:priority="999">           
 </intent-filter>
Ravi
  • 34,851
  • 21
  • 122
  • 183
  • Have you set the permission? – Trey Cai Dec 29 '15 at 12:23
  • @TreyCai, Yes I have. ** **, ** **. If I had not set any permissions this would not have worked at all. I have stated above that this has functioned properly on my phone and some others. – user2912203 Dec 29 '15 at 13:06
  • If you statically register the Receiver in the manifest, there's no need to register it dynamically in code, though you'd need to fix the `` entry, and the corresponding class. Also, you're correct that the `SMS_RECEIVED` broadcast can't be aborted in API>18, so I would guess that the Receiver isn't properly registered in an active component at the time of receipt in the cases that it's failing in that scenario. Apart from that, there's not much you can do in versions <=18 if another app is intercepting the broadcast, other than asking the user to disable/remove the offending app(s). – Mike M. Dec 29 '15 at 14:18
  • @MikeM. Thanks for the information. I made a registration of the receiver statistically being that I wasn't aware much then that I could add the priority dynamically. So if I were to register the receiver statistically what are the some of the fixes and changes which I would need to apply ? Also quoting what you mentioned "Receiver isn't properly registered in an active component at the time of receipt in the cases that it's failing in that scenario", if this was the case would it apply in all scenarios like in every phone ? Being that as I have mentioned it works well enough on my phone. – user2912203 Dec 29 '15 at 15:27
  • @MikeM. There are certain phones the app has been tested on, on some the broadcast receiver has worked flawlessly whilst others it's mostly a random matter. On the random ones, there are cases where only one message out of a number get's picked up by our broadcast receiver. By having the sms inbox checked, all the messages appeared to have been delivered whilst the app was running. Apparently it seems they weren't aborted by another app, if I am correct. Could the reason be memory being filled, and the Android OS has to then free up some memory space by removing unnecessary processes ? – user2912203 Dec 29 '15 at 15:36
  • [This post's](http://stackoverflow.com/questions/14452808) `SMSReceiver` class and manifest examples in the question are correct. You'll need to create a separate class for the Receiver, and you'd add your `priority` attribute to the example `` element. As for your failing tests, since I don't know how you're testing, or the specifics of how & where the Receiver is registered, I can't be certain what the problem is. However, since you're Receiver is registered dynamically at the moment, then it's most likely that it's in a component that's not actually running at the time of receipt. – Mike M. Dec 29 '15 at 15:41
  • The first step would be to get the Receiver statically registered, and see if you're missing any messages then. – Mike M. Dec 29 '15 at 15:41
  • @MikeM.The broadcast receiver is dynamically registered inside the _OnCreateMethod_ of an activity class which represents the main menu of the app. This triggers the BroadCast receiver object which was initialized in the same activity class which contains overridden _OnRecieve_ method. – user2912203 Dec 29 '15 at 16:10

1 Answers1

0

Change manifest to

<receiver
    android:name=".YourSMSReceiverClass"
    android:exported="true">
    <intent-filter android:priority="999">
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>
saeed khalafinejad
  • 1,139
  • 9
  • 22