diff --git a/README.md b/README.md index 145fcec..24ed368 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,21 @@ # dj_scaner -A new flutter plugin project. +东集PDA手持扫描设备flutter端插件 -## Getting Started - -This project is a starting point for a Flutter -[plug-in package](https://flutter.dev/developing-packages/), -a specialized package that includes platform-specific implementation code for -Android and/or iOS. - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +## 初始化 +```dart +DjScaner.init(); +``` +初始化内容:声音关闭,震动关闭,开机自启动,扫描头关闭 +##监听扫描内容 +```dart +await DjScaner.addListener((data) { + _code = data; + setState(() {}); + }); +``` +##结束监听 +```dart + DjScaner.cancel(); +``` diff --git a/android/src/main/java/com/dj/pda/scaner/dj_scaner/DjScanerPlugin.java b/android/src/main/java/com/dj/pda/scaner/dj_scaner/DjScanerPlugin.java index f52ba40..bf64a3d 100644 --- a/android/src/main/java/com/dj/pda/scaner/dj_scaner/DjScanerPlugin.java +++ b/android/src/main/java/com/dj/pda/scaner/dj_scaner/DjScanerPlugin.java @@ -1,38 +1,136 @@ package com.dj.pda.scaner.dj_scaner; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; + import androidx.annotation.NonNull; import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; -/** DjScanerPlugin */ +/** + * DjScanerPlugin + */ public class DjScanerPlugin implements FlutterPlugin, MethodCallHandler { - /// The MethodChannel that will the communication between Flutter and native Android - /// - /// This local reference serves to register the plugin with the Flutter Engine and unregister it - /// when the Flutter Engine is detached from the Activity - private MethodChannel channel; - - @Override - public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { - channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "dj_scaner"); - channel.setMethodCallHandler(this); - } - - @Override - public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { - if (call.method.equals("getPlatformVersion")) { - result.success("Android " + android.os.Build.VERSION.RELEASE); - } else { - result.notImplemented(); + /// The MethodChannel that will the communication between Flutter and native Android + /// + /// This local reference serves to register the plugin with the Flutter Engine and unregister it + /// when the Flutter Engine is detached from the Activity + private MethodChannel channel; + private EventChannel eventChannel; + private Context context; + private static final String SCANACTION = "com.android.server.scannerservice.asscaner"; + private static final String SCANCHANNEL = "com.dj.pda.scaner/scandata"; + + @Override + public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { + channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "dj_scaner"); + channel.setMethodCallHandler(this); + context = flutterPluginBinding.getApplicationContext(); + eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), SCANCHANNEL); + eventChannel.setStreamHandler(new EventChannel.StreamHandler() { + private BroadcastReceiver createScanReceiver(final EventChannel.EventSink events) { + return new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals(SCANACTION)) { + String code = intent.getStringExtra("scannerdata"); + System.out.println(code); + events.success(code); + } + } + }; + } + + ; + private BroadcastReceiver scanReceiver; + + @Override + public void onListen(Object arguments, EventChannel.EventSink events) { + System.out.println("注册广播"); + scanReceiver = createScanReceiver(events); + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(SCANACTION); + intentFilter.setPriority(Integer.MAX_VALUE); + context.registerReceiver(scanReceiver, intentFilter); + } + + @Override + public void onCancel(Object arguments) { + System.out.println("注销广播"); + context.unregisterReceiver(scanReceiver); + } + }); + } + + @Override + public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { + if (call.method.equals("soundPlay")) { + boolean arg=(boolean) call.argument("onOpen"); + System.out.println("声音 "+(arg?"开启":"关闭")); + Intent intent = new Intent("com.android.scanner.service_settings"); + intent.putExtra("sound_play",arg ); + context.sendBroadcast(intent); + result.success(true); + } else if ( + call.method.equals("viberate") + ) { + boolean arg=(boolean) call.argument("onOpen"); + System.out.println("震动"+(arg?"开启":"关闭")); + Intent intent = new Intent("com.android.scanner.service_settings"); + intent.putExtra("viberate", arg); + context.sendBroadcast(intent); + result.success(true); + } else if ( + call.method.equals("scanContinue") + ) { + boolean arg=(boolean) call.argument("onOpen"); + System.out.println("连续扫描"+(arg?"开启":"关闭")); + Intent intent = new Intent("com.android.scanner.service_settings"); + intent.putExtra("scan_continue", arg); + context.sendBroadcast(intent); + result.success(true); + } else if ( + call.method.equals("bootStart") + ) { + boolean arg=(boolean) call.argument("onOpen"); + System.out.println("开机自启动"+(arg?"开启":"关闭")); + Intent intent = new Intent("com.android.scanner.service_settings"); + intent.putExtra("boot_start", arg); + context.sendBroadcast(intent); + result.success(true); + } else if ( + call.method.equals("scanEnabled") + ) { + boolean arg=(boolean) call.argument("onOpen"); + System.out.println("扫描开关:"); + System.out.println(arg); + Intent intent = new Intent("com.android.scanner.ENABLED"); + intent.putExtra("enabled",arg); + context.sendBroadcast(intent); + result.success(true); + } else if ( + call.method.equals("broadcastName") + ) { + System.out.println("设置广播名称:"); + System.out.println((String) call.argument("name")); + Intent intent = new Intent("com.android.scanner.service_settings"); + intent.putExtra("action_barcode_broadcast", (String) call.argument("name")); + context.sendBroadcast(intent); + result.success(true); + } else { + result.notImplemented(); + } } - } - @Override - public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { - channel.setMethodCallHandler(null); - } + @Override + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { + channel.setMethodCallHandler(null); + } } diff --git a/example/lib/main.dart b/example/lib/main.dart index e53bd7b..f08d622 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,8 +1,8 @@ -import 'package:flutter/material.dart'; import 'dart:async'; -import 'package:flutter/services.dart'; import 'package:dj_scaner/dj_scaner.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; void main() { runApp(const MyApp()); @@ -16,34 +16,29 @@ class MyApp extends StatefulWidget { } class _MyAppState extends State { - String _platformVersion = 'Unknown'; + String _code = ''; + bool _init = false; @override void initState() { super.initState(); - initPlatformState(); } - // Platform messages are asynchronous, so we initialize in an async method. Future initPlatformState() async { - String platformVersion; - // Platform messages may fail, so we use a try/catch PlatformException. - // We also handle the message potentially returning null. try { - platformVersion = - await DjScaner.platformVersion ?? 'Unknown platform version'; + await DjScaner.init(); + _init = true; } on PlatformException { - platformVersion = 'Failed to get platform version.'; + print('init false'); } - - // If the widget was removed from the tree while the asynchronous platform - // message was in flight, we want to discard the reply rather than calling - // setState to update our non-existent appearance. if (!mounted) return; + setState(() {}); + } - setState(() { - _platformVersion = platformVersion; - }); + @override + void dispose() { + DjScaner.cancel(); + super.dispose(); } @override @@ -54,7 +49,42 @@ class _MyAppState extends State { title: const Text('Plugin example app'), ), body: Center( - child: Text('Running on: $_platformVersion\n'), + child: Column( + children: [ + TextButton( + onPressed: () async { + await initPlatformState(); + }, + child: const Text('初始化'), + ), + const SizedBox( + height: 10, + ), + TextButton( + onPressed: () async { + await DjScaner.addListener((data) { + _code = data; + setState(() {}); + }); + }, + child: const Text('开始扫描'), + ), + const SizedBox( + height: 10, + ), + TextButton( + onPressed: () async { + DjScaner.cancel(); + }, + child: const Text('结束扫描'), + ), + Text(_code), + const SizedBox( + height: 10, + ), + Text(_init.toString()), + ], + ), ), ), ); diff --git a/lib/dj_scaner.dart b/lib/dj_scaner.dart index 5b21ba8..09b3655 100644 --- a/lib/dj_scaner.dart +++ b/lib/dj_scaner.dart @@ -1,13 +1,92 @@ - import 'dart:async'; import 'package:flutter/services.dart'; class DjScaner { + static const String scanActionName = + "com.android.server.scannerservice.asscaner"; static const MethodChannel _channel = MethodChannel('dj_scaner'); + static const EventChannel _eventChannel = + EventChannel('com.dj.pda.scaner/scandata'); + static StreamSubscription? _streamSubscription; + + static Future addListener( + void Function(dynamic data)? onData) async { + await scanEnabled(true); + if (_streamSubscription == null) { + return _eventChannel.receiveBroadcastStream().listen(onData); + } else { + return _streamSubscription!; + } + } + + static void cancel() { + if (_streamSubscription != null) { + _streamSubscription!.cancel(); + _streamSubscription = null; + } + scanEnabled(false); + } + + static Future init() async { + print('初始化'); + + ///默认关闭声音 + await soundPlay(false); + + ///默认关闭震动 + await viberate(false); + + ///默认开机自启动 + await bootStart(true); + + ///设置广播名称 + await broadcastName(scanActionName); + + ///默认关闭扫描 + await scanEnabled(false); + print('初始化完成'); + } + + ///声音开关 + static Future soundPlay(bool onOpen) async { + await _channel.invokeMethod('soundPlay', { + 'onOpen': onOpen, + }); + } + + ///震动开关 + static Future viberate(bool onOpen) async { + await _channel.invokeMethod('viberate', { + 'onOpen': onOpen, + }); + } + + ///连续扫描开关 + static Future scanContinue(bool onOpen) async { + await _channel.invokeMethod('scanContinue', { + 'onOpen': onOpen, + }); + } + + ///开机自启动 + static Future bootStart(bool onOpen) async { + await _channel.invokeMethod('bootStart', { + 'onOpen': onOpen, + }); + } + + ///启动/禁用扫描头 + static Future scanEnabled(bool onOpen) async { + await _channel.invokeMethod('scanEnabled', { + 'onOpen': onOpen, + }); + } - static Future get platformVersion async { - final String? version = await _channel.invokeMethod('getPlatformVersion'); - return version; + ///设置广播名称 + static Future broadcastName(String name) async { + await _channel.invokeMethod('broadcastName', { + 'name': name, + }); } } diff --git a/test/dj_scaner_test.dart b/test/dj_scaner_test.dart index f65ce49..e07aac9 100644 --- a/test/dj_scaner_test.dart +++ b/test/dj_scaner_test.dart @@ -1,6 +1,5 @@ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:dj_scaner/dj_scaner.dart'; void main() { const MethodChannel channel = MethodChannel('dj_scaner'); @@ -17,7 +16,5 @@ void main() { channel.setMockMethodCallHandler(null); }); - test('getPlatformVersion', () async { - expect(await DjScaner.platformVersion, '42'); - }); + test('getPlatformVersion', () async {}); }