Sending Android SMS BroadcastReceiver data to Flutter through EventChannel

让人想犯罪 __ 提交于 2021-02-08 05:16:36

问题


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?


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/54088421/sending-android-sms-broadcastreceiver-data-to-flutter-through-eventchannel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!