I´m using esc_pos_bluetooth 0.2.8 library and connect the printer by bluetooth
Is ok when I send one order at a time, but when there are simultaneous orders, it print just the first and ignore the others. I try implement a print queue but I was not successful.
List printQueue = [];
insertPrintQueue(Schema item) {
printQueue.add(item);
printTicket(printQueue[0]);
}
verifyPrintQueue() {
if (printQueue.length > 0) {
printTicket(printQueue[0]);
}
}
printTicket(Schema item) async {
if (printerDevices != null) {
printerManager.selectPrinter(printerDevices[0]);
await printerManager
.printTicket(await ticket.templateTicket(item))
.then((value) => {
printQueue.removeAt(0),
if (printQueue.length > 0)
{
printTicket(printQueue[0])
}
});
} else {
print("None Printer Found");
}
I think this is happening because I'm trying to print while the printer is busy, have a way to check the status of the printer? and just order the print when the printer is not printing
insertPrintQueue(Schema item) {
printQueue.add(item);
printTicket(printQueue[0]); // Here
}
You are trying to print the first item always. So it works as expected. You can do it like this:
insertPrintQueue(Schema item) {
printQueue.add(item);
//printTicket(printQueue[0]);
for (var ticket in printQueue) {
printTicket(ticket);
}
}
Related
In my app, a user can send a file to others in a group chat. First, the user records some audio using their mic. The file is then touched up using FFMPEG. Then, the file is uploaded to Firebase Cloud Storage and if this is successful, a record is written in Firebase Realtime Database.
I'm getting the error below when the user records a long audio file and then presses submit. It almost seems as though FFMPEG hasn't finished processing the file...but I thought I used my async/await correctly to make sure that this processing is finished before moving on?
##MyAppFile## saveMyAppFileToCloudStorage Error: 'package:firebase_storage/src/reference.dart': Failed assertion: line 127 pos 12: 'file.absolute.existsSync()': is not true.
Psuedo-code:
User records audio
Audio file is processed using FFMPEG and the new processed file is created on the user's phone
User hits submit, uploading the file to Cloud Storage and, if successful, writing a record to Realtime Database
Order of Functions After User Hits Submit:
msgInput.dart -> sendMyAppFile()
msgInput.dart -> prepareMyAppFileForSending()
msgInput.dart -> runFFMPEGHighLow()
message_dao.dart -> sendMyAppFile()
message_dao.dart -> saveMyAppFileToCloudStorage() //ERROR COMES FROM THIS FUNCTION
The Code:
//msgInput.dart
Future<void> sendMyAppFile() async {
if (sendableMyAppFileExists == 1) {
final MyAppFileReadyToBeSent = await prepareMyAppFileForSending();
if (MyAppFileReadyToBeSent == '1') {
messageDao.sendMyAppFile(MyAppFile, filepath, filename);
} else {
}
}
setState(() {
sendableMyAppFileExists = 0;
});
}
Future<String> prepareMyAppFileForSending() async {
if (sendableMyAppFileExists == 1) {
if (recordedMyAppFileFilterID == '1') {
await runFFMPEGHighLow('1');
return '1';
}
if (recordedMyAppFileFilterID == '2') {
await runFFMPEGHighLow('2');
return '1';
}
}
return '0';
}
Future<void> runFFMPEGHighLow(String filterID) async {
if (filterID != '1' && filterID != '2') {
return;
}
if (sendableMyAppFileExists == 1) {
if (filterID == '1') {
await FFmpegKit.executeAsync(/*...parms...*/);
setState(() {
currentMyAppFileFilename = currentMyAppFileFilename + '1.mp3';
});
}
if (filterID == '2') {
await FFmpegKit.executeAsync(/*...parms...*/);
setState(() {
currentMyAppFileFilename = currentMyAppFileFilename + '2.mp3';
});
}
}
}
//message_dao.dart
void sendMyAppFile(ChatData MyAppFile, String filepath, String filename) {
saveMyAppFileToCloudStorage(filepath, filename).then((value) {
if (value == true) {
saveMyAppFileToRTDB(MyAppFile);
}
});
}
Future<bool> saveMyAppFileToCloudStorage(String filepath, String filename) async {
//filepath: /data/user/0/com.example.MyApp/app_flutter/MyApp/MyAppAudioFiles/MyAppFiles/2d7af6ae-6361-4be5-8209-8498dd17d77d1.mp3
//filename: 2d7af6ae-6361-4be5-8209-8498dd17d77d1.mp3
_firebaseStoragePath = MyAppFileStorageDir + filename;
File file = File(filepath);
try {
await _firebaseStorage
.ref(_firebaseStoragePath)
.putFile(file);
return true;
} catch (e) {
print('##MyAppFile## saveMyAppFileToCloudStorage Error: ' + e.toString()); //ERROR COMES FROM THIS LINE
return false;
}
return true;
}
I assume you're using the package ffmpeg_kit_flutter.
First, why it's not working: execute and executeAsync return FFmpegSession objects. The run of FFmpeg doesn't need to be finished for these methods to complete. In fact, the returned session object has methods like getState to monitor whether the run of FFmpeg has completed.
A good way to fix this: The documentation for executeAsync has a hint for what to do here.
Note that this method returns immediately and does not wait the execution to complete. You must use an FFmpegSessionCompleteCallback if you want to be notified about the result.
You can set a completion callback by passing a function to executeAsync. Here's the full function signature from the docs:
Future<FFmpegSession> executeAsync(
String command,
[FFmpegSessionCompleteCallback? completeCallback = null,
LogCallback? logCallback = null,
StatisticsCallback? statisticsCallback = null]
)
FFmpegSessionCompleteCallback is just a function that accepts an FFmpegSession and returns nothing. You can provide your own.
void someCompletionFunction() {
setState(() {
currentMyAppFileFilename = currentMyAppFileFilename + '1.mp3';
});
}
await FFmpegKit.executeAsync(/*...parms...*/, someCompletionFunction);
Future vs callback: If you prefer to use Futures and async-await instead of callbacks, you'll need to create your own Future and update it in the callback. See Dart, how to create a future to return in your own functions? for an example.
Does anyone know how to get an argument pass by MethodChannel in windows?
Here is my code to send and receive data.
I need to get data value in string type
String data = "Some data";
await platform.invokeMethod("OpenViewer", {"data":data});
channel->SetMethodCallHandler([](const flutter::MethodCall<>& call, std::unique_ptr<flutter::MethodResult<>> result)
{
// check method name called from dart
if (call.method_name().compare("OpenViewer") == 0) {
}
else {
result->NotImplemented();
}
});
you could use something like below
if (method_call.method_name().compare("launch") == 0) {
std::string url = GetUrlArgument(method_call);
if (url.empty()) {
result->Error("argument_error", "No URL provided");
return;
}
std::optional<std::string> error = LaunchUrl(url);
if (error) {
result->Error("open_error", error.value());
return;
}
result->Success(EncodableValue(true));
For more read here from url_launcher
I am new in flutter.
I am building an app to print on the ble label printer via Bluetooth.
I use flutter_blue library. I had successfully connected to the device and found the target characteristic. My problem is that when I call write() function of the characteristic printer show on display “waiting for data” and nothing is printed.
Could you please help me with the data format I need to put into the method?
I use utf8 encoded string as data.
Future<void> _print() async {
var serviceUuid = '0000ff00-0000-1000-8000-00805f9b34fb';
var characteristicsUuid = '0000ff02-0000-1000-8000-00805f9b34fb';
_services.forEach((service) {
if(service.uuid.toString().toLowerCase() == serviceUuid) {
printService = service;
for (var c in printService!.characteristics) {
if(c.uuid.toString().toLowerCase() == characteristicsUuid) {
var ZPL_TEST_LABEL = 'Hello WeChat!\r\n';
printCharacteristic = c;
writeData(printCharacteristic, ZPL_TEST_LABEL);
}
}
}});
}
Future<void> writeData(characteristic, data) async{
if (characteristic == null) return;
try {
var utf8Encoded = utf8.encode(data);
debugPrint(data.toString());
var result = await characteristic.write(utf8Encoded);
debugPrint(result.toString());
} catch (e) {
debugPrint(e.toString());
}
}
My first step is to print at least a string, could you pls help me?
So am having a scroll listener to get more data now the problem is that when the listener calls the function for more data then am having 4 if conditions but the function is running the if condition twice i don't understand the logic behind it.
MyCode:-
void _scrollListener()async{
if (!loading) {
if (scrollController.position.pixels == scrollController.position.maxScrollExtent) {
setState(() => load = true);
await clearEmptyDocs();
getMoreData();
}
}
}
getMoreData()async
{
var quicks;
var posts;
if(publicPostsDocuments.isNotEmpty)
{
print('1\n\n\n\n');
posts=await getPublicPosts();
}
if(publicQuicksDocuments.isNotEmpty)
{
print('2\n\n\n\n');
quicks=await getPublicQuicks();
}
if(publicPostsDocuments.isEmpty)
{
print('3\n\n\n\n');
posts=await getPublicDocuments();
}
if(publicQuicksDocuments.isEmpty)
{
print('4\n\n\n\n');
quicks=await getPublicDocumentsForQuicks();
}
setState(() {
load=false;
});
}
Here am having four lists and based on them am having if blocks so when lists are not empty then it should simply print 1 and 2 and then exit but it is printing 1,2,1,2 i.e. first 2 if blocks are running twice.
I cannot get the OnComplete() method to be called after all items are processed. I need to do so in order to (al the very least) hide the loading view. I'm a little new to JavaRX so I don't know where exactly is the problem. Can you help me to get the OnComplete() called when all items are processed?
The code does the following:
Show the loading view and get the list of items (just references).
Check if they are local or remote items.
If they are local, get them and add them to the list.
If they are remote, download them and add them to the list.
With the list built, draw the data on the UI.
Final processing and hiding of the loading view.
The code is the following:
private void loadDataRX(final long fromTime, final long toTime) {
mLoadingPb.setVisibility(View.VISIBLE);
iCompositeDisposable.clear();
iCompositeDisposable.add(mViewModel.getItems(fromTime, toTime)
.subscribeOn(Schedulers.io())
.flatMap(items -> {
Activity context = ItemFragment.this.getActivity();
if (context == null) {
Log.e(TAG, "Cannot present results: context is null");
return Flowable.empty();
} else {
context.runOnUiThread(() -> {
mItems.clear();
mCustomView.reset();
});
if (items != null && items.size() > 0) {
return Flowable.just(items);
} else {
Log.i(TAG, "No items.");
return Flowable.just(Collections.singletonList(new Item(-1))); // This is my current way of solving a similar problem so as to know if I don't have any items
}
}
})
.concatMapIterable(items -> items)
.concatMap(item -> {
if (item.getUid() == -1) {
return Flowable.just(item);
}
String file = item.getFileName();
boolean uploaded = item.isUploaded();
if (uploaded) { // Remote file
if (item.getUid() > 0) {
return iRetrofit.create(RestApi.class).getItem(item.getUid());
} else {
return Flowable.empty();
}
} else { // Local file
return Flowable.just(item);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(item -> {
Log.i(TAG, "Loaded items RX");
if (item instanceof Item) {
//Do stuff with the item and the files
} else if (item instanceof ResponseBody) {
//This is dirty but I didn't find another way. So here I basically extract the items and the files from the server's response. At least, it works.
} else {
Log.i(TAG, "No results for the given dates");
}
}, throwable -> {
mLoadingPb.setVisibility(View.GONE);
Log.e(TAG, "Error: " + throwable.getMessage());
}, () -> {
mLoadingPb.setVisibility(View.GONE);
Log.i(TAG, "Loading results completed"); // Can't get this to be called
})
);
}
Thanks in advance.
I guess that mViewModel.getItems returns Flowable. For flowable to complete we need to explicitly dispose it.
To resolve that you can make mViewModel.getItems to return Single<List<ItemType>>, then transform stream using .flatMapObservable { Observable.fromIterable(it) } to process each item.