4

I am trying to listen for any incoming SMS messages on an Android device and then showing a toast in my Flutter app whenever an SMS is received. I am connecting to Flutter through EventChannel and detecting SMS using a BroadcastReceiver. How do I send an events.success(message) whenever my broadcast receiver detects an SMS?

I tried adding the BroadcastReceiver directly inside the EventChannel but that did not work. The flutter SMS package also doesn't seem to work.

This is what my MainActivity looks like:

public class MainActivity extends FlutterActivity{
    public static final String STREAM = "com.myapp.thisapp/stream";
    public static final String TAG = "THIS IS A MESSAGE: ";


    @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);

        new EventChannel(getFlutterView(), STREAM).setStreamHandler(
                new EventChannel.StreamHandler() {

                    @Override
                    public void onListen(Object args, final 
EventChannel.EventSink events) {
                        //Send events.success() when SMS received
                        Log.w(TAG, "adding listener");
                    }

                    @Override
                    public void onCancel(Object args) {
                        Log.w(TAG, "cancelling listener");
                    }
                }
        );
  }

}

And this is the code for my BroadcastReceiver:

public class IncomingSmsBroadcastReceiver extends BroadcastReceiver {

    private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";

    @Override
    public void onReceive(final Context context, final Intent intent) {

        if (intent != null && SMS_RECEIVED.equals(intent.getAction())) {
            final SmsMessage smsMessage = extractSmsMessage(intent);
            processMessage(context, smsMessage);
        }

    }

    private SmsMessage extractSmsMessage(final Intent intent) {

        final Bundle pudsBundle = intent.getExtras();
        final Object[] pdus = (Object[]) pudsBundle.get("pdus");
        final SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[0]);

        return smsMessage;

    }

    private void processMessage(final Context context, final SmsMessage smsMessage) {

        //TODO: Send message to event channel
    }

}

Whenever the BroadCastReceiver encounters an SMS, I want the content of the message to be sent to the EventChannel which will send the message text to the Flutter front-end. How do I do this?

3 Answers 3

3

Based on your first comment Laksh22 YES it can be possible.

Create a constructor for your 'Activity' like this :

     _yourclassnameState() {
       platform.setMethodCallHandler(JavaMethodHandler);
     }

and then implement a handler for response

       Future<dynamic> JavaMethodHandler(MethodCall methodcall) async
       {
         switch(methodcall.method)
          {
           case 'SMSRecived':
            print('DataRecived is' + methodcall.arguments);
            break;
           default:
            break;
         }
       }

then in your 'BroadcastReceiver' use this code to call a flutter method :

    MethodChannel channel =new MethodChannel(view,CHANNEL);
    channel.invokeMethod("SMSRecived",args, new MethodChannel.Result() {
        @Override
        public void success(Object o) {
            System.out.println(o);
        }

        @Override
        public void error(String s, String s1, Object o) {

        }

        @Override
        public void notImplemented() {

        }
    });

Don't forget about CHANNEL. It should be the same both side.

Don't forget about manifest file.

For receiving SMS while your app is closed use 'ForegroundService'.Unfortunately Flutter dosen't support ForegroundService yet. you should implement it in Java.

Sign up to request clarification or add additional context in comments.

Comments

2

This is what you should be using in MainActivity, store the Result

        public class MainActivity extends FlutterActivity{
            public static final String STREAM = "com.myapp.thisapp/stream";
            public static final String TAG = "THIS IS A MESSAGE: ";
            public Result resultLater;


            @Override
          protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            GeneratedPluginRegistrant.registerWith(this);

            new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
                    new MethodCallHandler() {
                        @Override
                        public void onMethodCall(MethodCall call, Result result) {
                            //store the reference for later access
                            resultLater = result;
                        }
                    });

           }

         public class IncomingSmsBroadcastReceiver extends BroadcastReceiver {

         private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";

          @Override
          public void onReceive(final Context context, final Intent intent) {

            if (intent != null && SMS_RECEIVED.equals(intent.getAction())) {
                final SmsMessage smsMessage = extractSmsMessage(intent);
                processMessage(context, smsMessage);
            }

        }

          private SmsMessage extractSmsMessage(final Intent intent) {

            final Bundle pudsBundle = intent.getExtras();
            final Object[] pdus = (Object[]) pudsBundle.get("pdus");
            final SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[0]);

            return smsMessage;

         }

       }

       private void processMessage(final Context context, final SmsMessage smsMessage) {

            //here send back result, like this
            if(smsMessage.getMessageBody()!=null){
                 result.success(smsMessage.getMessageBody());
            }else{
                 result.error("Error", "Sms not found", null);
            }

         }

  }

now make the sms broadcast sub class in your main activity and declare below. and access the result when you get the sms. And from your flutter side just make channel call as usual.

Follow the reference for docs sample.

6 Comments

Is there any way for the message body to be sent to flutter automatically when SMS is received? Right now Flutter needs to invoke a method every time it wants to see an incoming SMS.
there is no way till now where flutter can directly access the sms code. but what i suggested should also work since it's just callback from native to flutter that sms is received and should be able to automatically filled up. have you tried approach. ?
How would you register the receiver in the manifest this way?
hi @DevilWarrior you do what you normally do to register your broadcast just add it in manifest file statically and give class to which it declared and have a callback mechanism to notify the main activity using some another broadcast or some rxjava observable or some event bus. and if you added it dynamically in your main activity then sub class it and take action. hope this helps.
I should've phrase my question better. I have the broadcastReceiver set correctly and I'm able to send the information to flutter via intents. I catch the event in the receiver than send the event to the main activity via intent than to Flutter via an EventChannel. The problem comes when I try to send the event when the app is closed. Any idea on how to proceed with that?
|
1

Register your broadcast receiver in EventChannel's onListen method

override fun onListen(arguments: Any?, eventSink: EventSink) {

    val receiver = IncomingSmsBroadcastReceiver()

    receiver.setListener(object : SmsReceiveListener() {

       override fun onSmsReceive(sms: String?) {
         eventSink.success(sms)
       }
    })

    val filter = IntentFilter(IncomingSmsBroadcastReceiver.SMS_RECEIVED)
    context.registerReceiver(receiver, filter)
}

A SmsReceiveListener is registered to IncomingSmsBroadcastReceiver to listen to the received message.

For more detail check the below URL:-

https://medium.com/cashify-engineering/event-channel-to-listen-to-broadcast-events-from-android-43a813672896

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.