Receiving data from a scanner [kotlin code] and se

2019-07-31 04:53发布

问题:

[Edit 4th February 2019]
I gave up Kotlin and I'm really out of my comfort zone using java, I think I-m almost there but I-m getting this error

MissingPluginException(No implementation found for method listen on channel scanner)

here's my last code, I could use some help:

java side

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.GeneratedPluginRegistrant;

public class MainActivity extends FlutterActivity implements EventChannel.StreamHandler {

  static IntentFilter filter = new IntentFilter();
  static String mAction = "++++CENSOR++++";
  static final String mKey = "++++CENSOR++++";
  static final String mEventCall = "scanner";
  private PluginRegistry.Registrar mRegistrar;
  private EventChannel.EventSink mEventSink;

  public void registerWith(Registrar registrar) {
      MainActivity plugin = new MainActivity();
      final EventChannel channel = new EventChannel(registrar.messenger(),mEventCall);
      channel.setStreamHandler(plugin);
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    filter.addCategory(Intent.CATEGORY_DEFAULT);
    filter.addAction(mAction);
    registerReceiver(myBroadcastReceiver, filter);
    GeneratedPluginRegistrant.registerWith(this);
  }

  @Override
  protected void onDestroy()
  {
    super.onDestroy();
    unregisterReceiver(myBroadcastReceiver);
  }

  private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
      String action = intent.getAction();
      if (action.equals(mAction)) {
        try {
            String data = intent.getStringExtra(mKey);
            mEventSink.success(data);
        } catch (Exception e) {
        }
      }
    }
  };

    public void onListen(Object o, EventChannel.EventSink eventSink) {
      mEventSink=eventSink;
    }

    public void onCancel(Object arguments) {
      mEventSink=null;
    }
}

flutter side

scanner.dart

import 'package:flutter/services.dart';
import 'dart:async';

class Scanner {
  static const String mEventCall = 'scanner';
  static const EventChannel _eventChannel = const EventChannel(mEventCall);
  static Stream<String> _readingStream;
  static Stream<String> get readingStream {
    if(_readingStream== null){
      _readingStream =_eventChannel.receiveBroadcastStream().map<String>((value)=> value);
    }
    return _readingStream;
  }

}

main.dart

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Scanner Beta',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {

  Stream<String> _stream = Scanner.readingStream;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("test"),
      ),
      body: Center(
        child: StreamBuilder(
          initialData: "",
          stream: _stream,
            builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
            return Text(snapshot.data);
            }
        )
      ),
    );
  }
}

[edit: 30th Jan]
I've checked the suggested link, for sure it gives me a better insight of a context I'm not yet familiar with, but I believe my problem is of a different nature:
I try to explain myself better:
1. (native app on the device) -> broadcast INTENT and ACTION
2. (my kotlin broadcast receiver) -> receive INTENT and ACTION
3. (MISSING PART) need to get the data from the intent/action to MethodChannel
4. (my kotlin MethodChannel) -> sen data to Flutter via platform invokeMethod

once again thank you in advance for any help you can give me Francesco

[original post]
I'm trying to build an app to read a scanner data (and other stuff with that) I (kind of / think I) know how to use a methodChannel to pass the data from kotlin to flutter, the scanner doesn't have a real plugin, but I can use a BroadcastReceiver + IntentFilter to listen to the 'scanner action';

my problem is to put both together, how can I make sure that whenever the Br..Receiver 'receive' something it will pass it to the method channel (WITHOUT touching the screen this is the device)

Bonus, I'm really out of my comfort zone with this task I might (probably) made some mistake, I can really use another pair of eyes

Here is my code: //////////////// KOTLIN

// get data from scanner API
import android.os.Bundle
import io.flutter.plugins.GeneratedPluginRegistrant
import android.content.BroadcastReceiver
import android.content.Context
import android.content.IntentFilter
import android.content.Intent;

//send data to flutter
import io.flutter.app.FlutterActivity
import io.flutter.plugin.common.MethodChannel;

class MainActivity:FlutterActivity() {

    private var scanData:String? = null


    private val SCANNER_ACTION = "++++censored++++"
    private val SCANNER_INTENT_DATA = "++++censored++++"
    private val FLUTTER_CHANNEL = "scanner.data"
    private val FLUTTER_METHOD = "getScannerData"

    override fun onCreate(savedInstanceState:Bundle?) {


        private const method_flutter = MethodChannel(flutterView, FLUTTER_CHANNEL)

    super.onCreate(savedInstanceState)

        //send intent to flutter
        GeneratedPluginRegistrant.registerWith(this)
       method_flutter.setMethodCallHandler{
            methodCall, result ->
            if (methodCall.method == FLUTTER_METHOD) {
                if (scanData!=null) {
                    result.success(scanData)
                } else {
                    result.error(null,null,null)
                }
            } else {
                result.notImplemented()
            }
        }

        ///scanner INTENT FILTER
        val filter = IntentFilter()
        filter.addCategory(Intent.CATEGORY_DEFAULT)
        filter.addAction(SCANNER_ACTION)
        registerReceiver(receiver, filter)
    }

     // END OF 'onCreate'
     // SCANNER RECEIVER
     private val receiver = object : BroadcastReceiver() {
         override fun onReceive(contxt: Context?, intent: Intent?) {
             if (intent?.action == SCANNER_ACTION) {
                scanData = intent.getStringExtra(SCANNER_INTENT_DATA)
             }
         }
     }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(receiver)
    }
}

////////////////DART

import 'dart:async';
import 'package:flutter/services.dart';

    class Plugin {
      static const platform =  MethodChannel('scanner.data');
      Future<String> get data async => await platform.invokeMethod('getScannerData');
      }