:printer: :label: App development for Brother printer using Flutter :label: :printer:
What does this accomplish?
What are the supported platforms?
What languages are used?
Functionalities?
Takes text input to print out a label
Takes camera/gallery selected images to print out a label
Discover Printer
1) `mDNS` --> using multicast dns to detect printers in local networks and their models ( Fully works on Android )
2) `Wifi Port Scans` --> scanning for print protocols ports like ( Just port 9100 or IPP, LPR ).
- Detecting models using this method can be achieved through SNMP. ( InProgress )
Technique used?
Hybrid Method
of leveraging existing SDK stuff Brother has built for the respective platforms and driving them using Flutter ( Kind of like a FrontEnd ). That way we avoid rewriting the sdk in Flutter and reuse them as Native code!Method Channels
in Flutter to call into the existing Brother SDK methods in their own platformBackground:
Brother already has SDKs for IOS (ObjC) and Android (Java) that work pretty well in respective platforms. Whats next?
This is a demo project that you could leverage to start building on top of. Some of the code has been intentionally kept simple to easily understand the flow and without proper error handling.
* Download and install Flutter
- for IOS, you would need xCode to sign and run the application
- for Android, AndroidStudio helps in debugging faster
* Clone the repository, check with doctor and run
- flutter doctor -v
- flutter run
As there are not a lot of err handling done ( inprogress to make it better! ), following this should keep everything good.
```
On the Android side, I have a map that relates the printerId to the ENUM value of printer model used inside the SDK. This map can be updated with your model ENUM or all the models to make it work with any models
This currently is supported only on Android as there is a mDNS IOS issue that needs to be resolved ( ref: https://github.com/flutter/flutter/issues/42102 )
To add new printer model?
If your printer is discovered via mDNS and shows in the dropdown ( should happen! ) —> Just update the map of printers in android side with the model and things should work!. Let me know otherwise, happy to debug…
Current workaround for IOS:
Similar steps required for Label sizes
Real devices VS Emulators
printer detection
wont work. In that case hardcode the methodChannel calls with the IP Address of the printer and corresponding model number + label size. Printer must be connected to the same wireless network the device is ( real device )
Power on printer (wait for solid green light)
Download Brother Wireless Wizard here
Set up wireless using the wizard steps. If wireless setup fails using the WPS button, wait until it gives option to set up using USB
Once printer is connected to network, make sure device is on the same network and you’re good to go!
Running flutter on IOS devices ( real device )
Debugging a few known Xcode errors:
If Flutter run gives a build error with Xcode migration, complete the steps here and it should work after that
Run(Flutter IDE): flutter clean
Run (Xcode): Product — > Clean Build Folder
IOS launch failure on real device with Pod Errors
—> Method 1
- I was amazed looking at MAC having ability to detect all printer types —> dug in to the BonjourSpec. Specifically this,
_printer._tcp.local. Port 515
_ipp._tcp.local. Port 631
_pdl-datastream._tcp.local. Port 9100
- Using mDNS it is possible to resolve services within small networks that is WIFI. We could retrieve the model and ip address using the multicast_dns package in Flutter. ( This works in Android )
- As said before in IOS the mDNS method needs a little bit of work or fix to have it working.
—> Method 2
- We could scan for network ports that are open directly. So looking for 9100 returns ip address of the printer.
- To get the model we could either reverse resolve the ipaddress
- Or, use SNMP get to query for specific OID.
- As of now, the modelID discovery is in progress….
Implemented
Pros:
This allows us to avoid .bin
files + file operations + downloading or moving bin files. Instead we use the base64 encoded label data directly.cat <label_name>.bin | base64
—> add to the mapOther Logic Considered and also be better
<label_name>.bin
in assets at native code ( android/ ios) - Android part of this logic is already done but not used<label_name>.bin
in assets at dart side and share to native platform —> https://flutter.dev/docs/development/ui/assets-and-images This app is not complete so please feel free to contribute!
* Design/Methods
- https://raw.githubusercontent.com/flutter/flutter/master/.gitignore
- https://flutter.dev/docs/development/platform-integration/platform-channels
- https://stackoverflow.com/questions/59669933/how-to-turn-asset-image-into-bitmap-in-flutter-dart
- https://medium.com/john-lewis-software-engineering/adding-a-third-party-framework-inside-a-first-party-framework-in-xcode-3ba58cfd08da
- https://medium.com/47billion/creating-a-bridge-in-flutter-between-dart-and-native-code-in-java-or-objectivec-5f80fd0cd713
- https://medium.com/@pahlevikun/bridging-between-dart-and-native-code-with-flutter-channel-for-communicate-each-other-7c736929ee42
- https://blog.usejournal.com/integrating-native-third-party-sdk-in-flutter-8aab03afa9da
- https://blog.solutelabs.com/integrating-third-party-native-sdks-in-flutter-df418829dcf7
- https://flutter.dev/docs/development/platform-integration/platform-channels
- https://github.com/rahimkhalid/FlutterWithSurveryMonkey
- https://fluttertutorial.in/method-channel-in-flutter/
- https://github.com/RafaO/FlutterNativeCommunication
- https://proandroiddev.com/communication-between-flutter-and-native-modules-9b52c6a72dd2
- https://github.com/anilgsharma900/MethodChannelDemo
- https://medium.com/@Anil_Sharma/methodchannel-in-flutter-727d3823d6ac
- https://stablekernel.com/article/flutter-platform-channels-quick-start/
- https://stackoverflow.com/questions/53105715/what-is-the-substitute-for-deprecated-staticlayout
* Network
- https://pub.dev/packages/wifi#-installing-tab-
- https://pub.dev/packages/ping_discover_network#-installing-tab-
- https://blog.hyperiongray.com/multicast-dns-service-discovery/
- https://pub.dev/documentation/multicast_dns/latest/
- https://developer.apple.com/bonjour/printing-specification/bonjourprinting-1.2.1.pdf
- http://jamesslocum.com/post/77759061182
* UI
- https://stackoverflow.com/questions/58897270/adding-icon-to-left-of-dropdownbutton-expanded-in-flutter
- https://flutter.dev/docs/cookbook/forms/validation
- https://medium.com/@afegbua/flutter-thursday-08-multi-level-dependent-dropdown-d965c08d2748
- https://stackoverflow.com/questions/58363597/dropdownbutton-in-flutter-not-changing-values-to-the-selected-value
- https://github.com/invoiceninja/flutter-client/blob/master/samples/form_keys.dart
- https://hillel.dev/2018/06/12/flutter-complex-forms-with-multiple-tabs-and-relationships/
- https://stackoverflow.com/questions/56410110/flutter-dropdownbutton-show-label-when-option-is-selected
- https://api.flutter.dev/flutter/material/DropdownButtonFormField/DropdownButtonFormField.html
- https://medium.com/flutterpub/sample-form-part-2-flutter-c19e9f37ac41
- https://medium.com/@nitishk72/form-validation-in-flutter-d762fbc9212c
* Images
- https://pub.dev/packages/image_picker
- https://theswiftdev.com/picking-images-with-uiimagepickercontroller-in-swift-5/
- https://stackoverflow.com/questions/5151744/upload-picture-to-emulator-gallery
- https://stackoverflow.com/questions/59669933/how-to-turn-asset-image-into-bitmap-in-flutter-dart
- https://stackoverflow.com/questions/49835623/how-to-load-images-with-image-file
- https://dev.to/pedromassango/let-s-pick-some-images-with-flutter-575b
- https://developer.apple.com/library/archive/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/HandlingImages/Images.html
- https://gist.github.com/superpeteblaze/14885c5e2c8a5ccfbddb
- https://www.hackingwithswift.com/example-code/core-graphics/how-to-draw-a-text-string-using-core-graphics
- https://stackoverflow.com/questions/28906914/how-do-i-add-text-to-an-image-in-ios-swift
- https://teamtreehouse.com/community/how-to-rotate-images-to-the-correct-orientation-portrait-by-editing-the-exif-data-once-photo-has-been-taken
- https://stackoverflow.com/questions/34532502/resizing-portrait-bitmap-to-landscape-dimensions-in-android
- https://stackoverflow.com/questions/9015372/how-to-rotate-a-bitmap-90-degrees
- https://android--code.blogspot.com/2015/11/android-how-to-rotate-canvas.html
- https://www.skoumal.com/en/android-drawing-multiline-text-on-bitmap/
- https://www.skoumal.com/en/android-guide-draw-text-over-bitmap/
- https://medium.com/swlh/fun-with-text-to-image-in-android-c70046b76682
- https://android.okhelp.cz/create-bitmap-and-draw-text-into-bitmap-android-example/
- https://discuss.kotlinlang.org/t/using-a-bitmap-inside-a-new-android-project/14714
* Random Helpers
- https://github.com/CocoaPods/CocoaPods/issues/8377