[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');
}