-
Notifications
You must be signed in to change notification settings - Fork 336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I am getting error Unhandled Exception: MissingPluginException(No implementation found for method startScan on channel flutter_bluetooth_basic/methods) #145
Comments
@andrey-ushakov Please help to fix the issue. |
@andrey-ushakov facing same issue. please look into it. |
Hi there, can you give more context on this one? Maybe some code snippets? Basically before you scan a bluetooth, please make sure:
Remember that you will need to run on a real device instead of an emulator. |
@singgihmardianto Code:
} And it was working last week but suddenly it started throwing exception while scanning the bluetooth |
Here is my code
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false" />
<!-- New Bluetooth permissions in Android 12 https://developer.android.com/about/versions/12/features/bluetooth-permissions -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- legacy for Android 11 or lower -->
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
<!-- legacy for Android 9 or lower -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="28" />
<application
android:label="bluetooth_printer"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>
import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/material.dart' hide Image;
import 'package:flutter/services.dart';
import 'package:image/image.dart';
import 'package:intl/intl.dart';
import 'package:oktoast/oktoast.dart';
import 'package:permission_handler/permission_handler.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return OKToast(
child: MaterialApp(
title: 'Bluetooth demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Bluetooth demo'),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
MyHomePageState createState() => MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
PrinterBluetoothManager printerManager = PrinterBluetoothManager();
List<PrinterBluetooth> _devices = [];
@override
void initState() {
super.initState();
printerManager.scanResults.listen((devices) async {
// print('UI: Devices found ${devices.length}');
setState(() {
_devices = devices;
});
});
}
void _startScanDevices() async {
await Permission.bluetooth.request().then((value) {
if (!value.isGranted) {
showToast('Bluetooth Permission denied');
return;
}
});
await Permission.bluetoothScan.request().then((value) {
if (!value.isGranted) {
showToast('Bluetooth scan Permission denied');
return;
}
});
await Permission.bluetoothConnect.request().then((value) {
if (!value.isGranted) {
showToast('Bluetooth connect Permission denied');
return;
}
});
setState(() {
_devices = [];
});
printerManager.startScan(const Duration(seconds: 4));
}
void _stopScanDevices() {
printerManager.stopScan();
}
Future<List<int>> demoReceipt(
PaperSize paper, CapabilityProfile profile) async {
final Generator ticket = Generator(paper, profile);
List<int> bytes = [];
// Print image
// final ByteData data = await rootBundle.load('assets/rabbit_black.jpg');
// final Uint8List imageBytes = data.buffer.asUint8List();
// final Image? image = decodeImage(imageBytes);
// bytes += ticket.image(image);
bytes += ticket.text('GROCERYLY',
styles: const PosStyles(
align: PosAlign.center,
height: PosTextSize.size2,
width: PosTextSize.size2,
),
linesAfter: 1);
bytes += ticket.text('889 Watson Lane',
styles: const PosStyles(align: PosAlign.center));
bytes += ticket.text('New Braunfels, TX',
styles: const PosStyles(align: PosAlign.center));
bytes += ticket.text('Tel: 830-221-1234',
styles: const PosStyles(align: PosAlign.center));
bytes += ticket.text('Web: www.example.com',
styles: const PosStyles(align: PosAlign.center), linesAfter: 1);
bytes += ticket.hr();
bytes += ticket.row([
PosColumn(text: 'Qty', width: 1),
PosColumn(text: 'Item', width: 7),
PosColumn(
text: 'Price',
width: 2,
styles: const PosStyles(align: PosAlign.right)),
PosColumn(
text: 'Total',
width: 2,
styles: const PosStyles(align: PosAlign.right)),
]);
bytes += ticket.row([
PosColumn(text: '2', width: 1),
PosColumn(text: 'ONION RINGS', width: 7),
PosColumn(
text: '0.99',
width: 2,
styles: const PosStyles(align: PosAlign.right)),
PosColumn(
text: '1.98',
width: 2,
styles: const PosStyles(align: PosAlign.right)),
]);
bytes += ticket.row([
PosColumn(text: '1', width: 1),
PosColumn(text: 'PIZZA', width: 7),
PosColumn(
text: '3.45',
width: 2,
styles: const PosStyles(align: PosAlign.right)),
PosColumn(
text: '3.45',
width: 2,
styles: const PosStyles(align: PosAlign.right)),
]);
bytes += ticket.row([
PosColumn(text: '1', width: 1),
PosColumn(text: 'SPRING ROLLS', width: 7),
PosColumn(
text: '2.99',
width: 2,
styles: const PosStyles(align: PosAlign.right)),
PosColumn(
text: '2.99',
width: 2,
styles: const PosStyles(align: PosAlign.right)),
]);
bytes += ticket.row([
PosColumn(text: '3', width: 1),
PosColumn(text: 'CRUNCHY STICKS', width: 7),
PosColumn(
text: '0.85',
width: 2,
styles: const PosStyles(align: PosAlign.right)),
PosColumn(
text: '2.55',
width: 2,
styles: const PosStyles(align: PosAlign.right)),
]);
bytes += ticket.hr();
bytes += ticket.row([
PosColumn(
text: 'TOTAL',
width: 6,
styles: const PosStyles(
height: PosTextSize.size2,
width: PosTextSize.size2,
)),
PosColumn(
text: '\$10.97',
width: 6,
styles: const PosStyles(
align: PosAlign.right,
height: PosTextSize.size2,
width: PosTextSize.size2,
)),
]);
bytes += ticket.hr(ch: '=', linesAfter: 1);
bytes += ticket.row([
PosColumn(
text: 'Cash',
width: 7,
styles:
const PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
PosColumn(
text: '\$15.00',
width: 5,
styles:
const PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
]);
bytes += ticket.row([
PosColumn(
text: 'Change',
width: 7,
styles:
const PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
PosColumn(
text: '\$4.03',
width: 5,
styles:
const PosStyles(align: PosAlign.right, width: PosTextSize.size2)),
]);
bytes += ticket.feed(2);
bytes += ticket.text('Thank you!',
styles: const PosStyles(align: PosAlign.center, bold: true));
final now = DateTime.now();
final formatter = DateFormat('MM/dd/yyyy H:m');
final String timestamp = formatter.format(now);
bytes += ticket.text(timestamp,
styles: const PosStyles(align: PosAlign.center), linesAfter: 2);
// Print QR Code from image
// try {
// const String qrData = 'example.com';
// const double qrSize = 200;
// final uiImg = await QrPainter(
// data: qrData,
// version: QrVersions.auto,
// gapless: false,
// ).toImageData(qrSize);
// final dir = await getTemporaryDirectory();
// final pathName = '${dir.path}/qr_tmp.png';
// final qrFile = File(pathName);
// final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List());
// final img = decodeImage(imgFile.readAsBytesSync());
// bytes += ticket.image(img);
// } catch (e) {
// print(e);
// }
// Print QR Code using native function
// bytes += ticket.qrcode('example.com');
ticket.feed(2);
ticket.cut();
return bytes;
}
Future<List<int>> testTicket(
PaperSize paper, CapabilityProfile profile) async {
final Generator generator = Generator(paper, profile);
List<int> bytes = [];
bytes += generator.text(
'Regular: aA bB cC dD eE fF gG hH iI jJ kK lL mM nN oO pP qQ rR sS tT uU vV wW xX yY zZ');
// bytes += generator.text('Special 1: àÀ èÈ éÉ ûÛ üÜ çÇ ôÔ',
// styles: PosStyles(codeTable: PosCodeTable.westEur));
// bytes += generator.text('Special 2: blåbærgrød',
// styles: PosStyles(codeTable: PosCodeTable.westEur));
bytes += generator.text('Bold text', styles: const PosStyles(bold: true));
bytes +=
generator.text('Reverse text', styles: const PosStyles(reverse: true));
bytes += generator.text('Underlined text',
styles: const PosStyles(underline: true), linesAfter: 1);
bytes += generator.text('Align left',
styles: const PosStyles(align: PosAlign.left));
bytes += generator.text('Align center',
styles: const PosStyles(align: PosAlign.center));
bytes += generator.text('Align right',
styles: const PosStyles(align: PosAlign.right), linesAfter: 1);
bytes += generator.row([
PosColumn(
text: 'col3',
width: 3,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
PosColumn(
text: 'col6',
width: 6,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
PosColumn(
text: 'col3',
width: 3,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
]);
bytes += generator.text('Text size 200%',
styles: const PosStyles(
height: PosTextSize.size2,
width: PosTextSize.size2,
));
// Print image
final ByteData data = await rootBundle.load('assets/logo.png');
final Uint8List buf = data.buffer.asUint8List();
final Image image = decodeImage(buf)!;
bytes += generator.image(image);
// Print image using alternative commands
// bytes += generator.imageRaster(image);
// bytes += generator.imageRaster(image, imageFn: PosImageFn.graphics);
// Print barcode
final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
bytes += generator.barcode(Barcode.upcA(barData));
// Print mixed (chinese + latin) text. Only for printers supporting Kanji mode
// bytes += generator.text(
// 'hello ! 中文字 # world @ éphémère &',
// styles: PosStyles(codeTable: PosCodeTable.westEur),
// containsChinese: true,
// );
bytes += generator.feed(2);
bytes += generator.cut();
return bytes;
}
void _testPrint(PrinterBluetooth printer) async {
printerManager.selectPrinter(printer);
// TODO Don't forget to choose printer's paper
const PaperSize paper = PaperSize.mm80;
final profile = await CapabilityProfile.load();
// TEST PRINT
// final PosPrintResult res =
// await printerManager.printTicket(await testTicket(paper));
// DEMO RECEIPT
final PosPrintResult res =
await printerManager.printTicket((await demoReceipt(paper, profile)));
showToast(res.msg);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView.builder(
itemCount: _devices.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () => _testPrint(_devices[index]),
child: Column(
children: <Widget>[
Container(
height: 60,
padding: const EdgeInsets.only(left: 10),
alignment: Alignment.centerLeft,
child: Row(
children: <Widget>[
const Icon(Icons.print),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(_devices[index].name ?? ''),
Text(_devices[index].address!),
Text(
'Click to print a test receipt',
style: TextStyle(color: Colors.grey[700]),
),
],
),
)
],
),
),
const Divider(),
],
),
);
}),
floatingActionButton: StreamBuilder<bool>(
stream: printerManager.isScanningStream,
initialData: false,
builder: (c, snapshot) {
if (snapshot.data!) {
return FloatingActionButton(
onPressed: _stopScanDevices,
backgroundColor: Colors.red,
child: const Icon(Icons.stop),
);
} else {
return FloatingActionButton(
onPressed: _startScanDevices,
child: const Icon(Icons.search),
);
}
},
),
);
}
} |
@singgihmardianto Actually I am getting error while scanning the bluetooth |
@singgihmardianto It was working properly last week but suddenly it stopped working and throwing exception |
@rohit0713 all seems good.. what version are you using? I am using |
@singgihmardianto i'm also using the same version also. but having this issue. yes used flutter clean many times. |
@vishnudasRapidor what's your targetSdkVersion and compiledSdkVersion? |
@singgihmardianto flutter 3.22.1 |
@singgihmardianto could you be able to identify the issue? |
@singgihmardianto @vishnudasRapidor The issue is with the latest flutter version. It is not supporting in current flutter version. |
@rohit0713 in my project or the |
@vishnudasRapidor In your project Use flutter 3.19.5 Version then it will work perfectly. |
so I need to downgrade. But the user already using will face problems once they upgrade right? But this the issue for package itself. @singgihmardianto since user don't downgrade always, resolve it on the package will be a better approach. Please currect me if I'm wrong. |
@vishnudasRapidor @rohit0713 yeah I think so. The only different with my machine is the flutter and dart version. Mine: I think the best solution right now is to downgrade the version and waiting support for the latest flutter version. |
@singgihmardianto downgrading is not an option for us, because downgrading will cause errors from other packages. We are keeping dependencies updated for some reason. Planning to handle android part done by ourselves till new release comes. Thank you @singgihmardianto @rohit0713 for the help ❤️ |
I'm experiencing this too and second if downgrade isn't an option for us |
I'm having the same problem, and downgrading Flutter is not an option for us |
Update: Migrated to esc_pos_bluetooth_updated and I can confirm the problem is not present. Just update the imports and thats it |
Running into this problem
I tried everything here https://stackoverflow.com/questions/66236115/no-podspec-found-for-geolocator-web-in-symlinks-plugins-geolocator-web-ios This is the output of
|
So we still can't use this package with the new Flutter versions? |
I am not able to scan the bluetooth due to error
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method stopScan on channel flutter_bluetooth_basic/methods)
E/flutter ( 4507): #0 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:332:7)
E/flutter ( 4507):
E/flutter ( 4507): #1 BluetoothManager.stopScan (package:flutter_bluetooth_basic/src/bluetooth_manager.dart:122:5)
E/flutter ( 4507):
E/flutter ( 4507): #2 PrinterBluetoothManager.stopScan (package:esc_pos_bluetooth/src/printer_bluetooth_manager.dart:67:5)
E/flutter ( 4507):
E/flutter ( 4507):
I/flutter ( 4507): Error starting scan.
E/flutter ( 4507): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: MissingPluginException(No implementation found for method startScan on channel flutter_bluetooth_basic/methods)
E/flutter ( 4507): #0 BluetoothManager.scan (package:flutter_bluetooth_basic/src/bluetooth_manager.dart:85:7)
E/flutter ( 4507):
E/flutter ( 4507): #1 _nullDataHandler (dart:async/stream_impl.dart:517:1)
E/flutter ( 4507):
E/flutter ( 4507):
The text was updated successfully, but these errors were encountered: