Repository: kakzaki/blue_thermal_printer Branch: master Commit: d183d1d74111 Files: 81 Total size: 134.5 KB Directory structure: gitextract_weax0zck/ ├── .github/ │ └── workflows/ │ └── stale.yml ├── .gitignore ├── .gradle/ │ ├── 5.1.1/ │ │ └── gc.properties │ ├── buildOutputCleanup/ │ │ └── cache.properties │ └── vcs-1/ │ └── gc.properties ├── .idea/ │ ├── .gitignore │ ├── caches/ │ │ ├── build_file_checksums.ser │ │ └── gradle_models.ser │ ├── codeStyles/ │ │ └── Project.xml │ ├── encodings.xml │ ├── libraries/ │ │ ├── Dart_SDK.xml │ │ ├── Flutter_Plugins.xml │ │ └── Flutter_for_Android.xml │ ├── misc.xml │ ├── modules.xml │ ├── runConfigurations/ │ │ └── example_lib_main_dart.xml │ └── vcs.xml ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── android/ │ ├── .gitignore │ ├── build.gradle │ ├── gradle.properties │ ├── settings.gradle │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ └── java/ │ └── id/ │ └── kakzaki/ │ └── blue_thermal_printer/ │ ├── BlueThermalPrinterPlugin.java │ ├── PrinterCommands.java │ └── Utils.java ├── blue_thermal_printer.iml ├── example/ │ ├── .flutter-plugins-dependencies │ ├── .gitignore │ ├── .metadata │ ├── README.md │ ├── android/ │ │ ├── app/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ ├── debug/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── java/ │ │ │ │ │ └── id/ │ │ │ │ │ └── kakzaki/ │ │ │ │ │ └── blue_thermal_printer_example/ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── res/ │ │ │ │ ├── drawable/ │ │ │ │ │ └── launch_background.xml │ │ │ │ └── values/ │ │ │ │ └── styles.xml │ │ │ └── profile/ │ │ │ └── AndroidManifest.xml │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ └── settings.gradle │ ├── ios/ │ │ ├── Flutter/ │ │ │ ├── AppFrameworkInfo.plist │ │ │ ├── Debug.xcconfig │ │ │ ├── Release.xcconfig │ │ │ └── flutter_export_environment.sh │ │ ├── Podfile │ │ ├── Runner/ │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets/ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── LaunchImage.imageset/ │ │ │ │ ├── Contents.json │ │ │ │ └── README.md │ │ │ ├── Base.lproj/ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ └── Main.storyboard │ │ │ ├── Info.plist │ │ │ └── Runner-Bridging-Header.h │ │ ├── Runner.xcodeproj/ │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace/ │ │ │ │ └── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── xcschemes/ │ │ │ └── Runner.xcscheme │ │ └── Runner.xcworkspace/ │ │ └── contents.xcworkspacedata │ ├── lib/ │ │ ├── main.dart │ │ ├── printerenum.dart │ │ └── testprint.dart │ ├── pubspec.yaml │ └── test/ │ └── widget_test.dart ├── gradle.properties ├── ios/ │ ├── .gitignore │ ├── Assets/ │ │ └── .gitkeep │ ├── Classes/ │ │ ├── BlueThermalPrinterPlugin.h │ │ ├── BlueThermalPrinterPlugin.m │ │ └── SwiftBlueThermalPrinterPlugin.swift │ └── blue_thermal_printer.podspec ├── lib/ │ └── blue_thermal_printer.dart ├── local.properties ├── macos/ │ ├── Classes/ │ │ ├── BlueThermalPrinterPlugin.h │ │ └── BlueThermalPrinterPlugin.m │ └── blue_thermal_printer.podspec ├── pubspec.yaml └── test/ └── blue_thermal_printer_test.dart ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/stale.yml ================================================ # This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time. # # You can adjust the behavior by modifying this file. # For more information, see: # https://github.com/actions/stale name: Mark stale issues and pull requests on: schedule: - cron: '30 20 * * *' jobs: stale: runs-on: ubuntu-latest permissions: issues: write pull-requests: write steps: - uses: actions/stale@v5 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.' stale-pr-message: 'Stale pull request message' stale-issue-label: 'no-issue-activity' stale-pr-label: 'no-pr-activity' ================================================ FILE: .gitignore ================================================ .DS_Store .dart_tool/ .packages .pub/ build/ ================================================ FILE: .gradle/5.1.1/gc.properties ================================================ ================================================ FILE: .gradle/buildOutputCleanup/cache.properties ================================================ #Thu May 09 15:59:56 ICT 2019 gradle.version=5.1.1 ================================================ FILE: .gradle/vcs-1/gc.properties ================================================ ================================================ FILE: .idea/.gitignore ================================================ # Default ignored files /workspace.xml ================================================ FILE: .idea/codeStyles/Project.xml ================================================
xmlns:android ^$
xmlns:.* ^$ BY_NAME
.*:id http://schemas.android.com/apk/res/android
.*:name http://schemas.android.com/apk/res/android
name ^$
style ^$
.* ^$ BY_NAME
.* http://schemas.android.com/apk/res/android ANDROID_ATTRIBUTE_ORDER
.* .* BY_NAME
================================================ FILE: .idea/encodings.xml ================================================ ================================================ FILE: .idea/libraries/Dart_SDK.xml ================================================ ================================================ FILE: .idea/libraries/Flutter_Plugins.xml ================================================ ================================================ FILE: .idea/libraries/Flutter_for_Android.xml ================================================ ================================================ FILE: .idea/misc.xml ================================================ ================================================ FILE: .idea/modules.xml ================================================ ================================================ FILE: .idea/runConfigurations/example_lib_main_dart.xml ================================================ ================================================ FILE: .idea/vcs.xml ================================================ ================================================ FILE: .metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b channel: stable project_type: plugin ================================================ FILE: CHANGELOG.md ================================================ ## 1.2.3 * demonstrate using enum for readability * drawer pin by erica * fix bug on ios ## 1.2.2 * upgrading gradle ## 1.2.1 * fix android 12 permission ## 1.2.0 * fix web build issue ## 1.1.9 * fix bluetooth listener not working, add additional bluetooth state info, add get connected device function * Issue #123 fix - app will now automatically disconnect if device is turned off thanks to knight-dev ## 1.1.8 * Fix bug on ios build ## 1.1.7 * dartdoc comments and Dart formatter ## 1.1.6 * Add print3Column method * Add print4Column method * Support format string ## 1.1.5 * Migrate to Android embedding v2 ## 1.1.4 * Fix Error Null-Safety ## 1.1.3 * Fix Cast Error on getBondedDevices ## 1.1.2 * Migrate to null-safety ## 1.1.1 * Support different charset in print methods, thanks to danilof ## 1.1.0 * Add print image bytes method, thanks to mvanvu ## 1.0.9 * Avoiding activity null pointer, thanks to wmattei ## 1.0.8 * fix crash with "Methods marked with @UiThread must be executed on the main thread, thanks to ricardochen ## 1.0.7 * change documentation ## 1.0.6 * add size to printleftright ## 1.0.5 * fix bug ## 1.0.4 * fix bug ## 1.0.3 * Add print left + right ## 1.0.2 * Add Endline in QRCODE ## 1.0.1 * Add Doc. ## 1.0.0 * initial release. ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2022 Zaki Mubarok (kakzaki.dev) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # blue_thermal_printer [![pub package](https://img.shields.io/pub/v/blue_thermal_printer.svg)](https://pub.dev/packages/blue_thermal_printer) [![pub package](https://img.shields.io/twitter/follow/kakzaki_id.svg?colorA=1da1f2&colorB=&label=Follow%20on%20Twitter)](https://twitter.com/kakzaki_id) A new Flutter plugin for connecting to thermal printer via bluetooth (Android Only), this plugin is still under development Note: Migrate your project to AndroidX ## Platform Support | Android | iOS | MacOS | Web | Linux | Windows | | :-----: | :-: | :---: | :-: | :---: | :-----: | | ✔️ | ️X | ️X | ️X | ️X | ️X | ## Getting Started 1. Depend on it Add this to your package's pubspec.yaml file: dependencies: blue_thermal_printer: ^any 2. Install it You can install packages from the command line: with Flutter: $ flutter packages get Alternatively, your editor might support flutter packages get. Check the docs for your editor to learn more. 3. Import it Now in your Dart code, you can use: import 'package:blue_thermal_printer/blue_thermal_printer.dart'; EXAMPLE: For detail demonstration please look at [example](https://github.com/kakzaki/blue_thermal_printer/tree/master/example) folder Note: make sure to upgrade your project to compileSdkVersion 31 or above If you like my content, please consider buying me a coffee. Thank you for your support! Buy Me A Coffee [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/Z8Z6656JW) bagi yang dari Indonesia bisa lewat saweria berikut https://saweria.co/kakzaki ================================================ FILE: android/.gitignore ================================================ *.iml .gradle /local.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build /captures ================================================ FILE: android/build.gradle ================================================ group 'id.kakzaki.blue_thermal_printer' buildscript { repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:3.5.4' } } rootProject.allprojects { repositories { google() mavenCentral() } } apply plugin: 'com.android.library' android { compileSdkVersion 31 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } defaultConfig { minSdkVersion 18 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } lintOptions { disable 'InvalidPackage' } } dependencies { implementation 'androidx.appcompat:appcompat:1.4.2' implementation 'com.google.zxing:core:3.3.3' implementation 'com.android.support:multidex:1.0.3' implementation 'com.journeyapps:zxing-android-embedded:3.6.0@aar' } ================================================ FILE: android/gradle.properties ================================================ org.gradle.jvmargs=-Xmx1536M ================================================ FILE: android/settings.gradle ================================================ rootProject.name = 'blue_thermal_printer' ================================================ FILE: android/src/main/AndroidManifest.xml ================================================ ================================================ FILE: android/src/main/java/id/kakzaki/blue_thermal_printer/BlueThermalPrinterPlugin.java ================================================ package id.kakzaki.blue_thermal_printer; import android.Manifest; import android.app.Activity; import android.app.Application; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothSocket; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Build; import android.util.Log; import android.os.AsyncTask; import android.os.Handler; import android.os.Looper; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.EventChannel.StreamHandler; import io.flutter.plugin.common.EventChannel.EventSink; 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; import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener; import com.google.zxing.BarcodeFormat; import com.google.zxing.MultiFormatWriter; import com.google.zxing.common.BitMatrix; import com.journeyapps.barcodescanner.BarcodeEncoder; public class BlueThermalPrinterPlugin implements FlutterPlugin, ActivityAware,MethodCallHandler, RequestPermissionsResultListener { private static final String TAG = "BThermalPrinterPlugin"; private static final String NAMESPACE = "blue_thermal_printer"; private static final int REQUEST_COARSE_LOCATION_PERMISSIONS = 1451; private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); private static ConnectedThread THREAD = null; private BluetoothAdapter mBluetoothAdapter; private Result pendingResult; private EventSink readSink; private EventSink statusSink; private FlutterPluginBinding pluginBinding; private ActivityPluginBinding activityBinding; private final Object initializationLock = new Object(); private Context context; private MethodChannel channel; private EventChannel stateChannel; private BluetoothManager mBluetoothManager; private Activity activity; public BlueThermalPrinterPlugin() { } @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { pluginBinding = binding; } @Override public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { pluginBinding = null; } @Override public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { activityBinding = binding; setup( pluginBinding.getBinaryMessenger(), (Application) pluginBinding.getApplicationContext(), activityBinding.getActivity(), activityBinding); } @Override public void onDetachedFromActivityForConfigChanges() { onDetachedFromActivity(); } @Override public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { onAttachedToActivity(binding); } @Override public void onDetachedFromActivity() { detach(); } private void setup( final BinaryMessenger messenger, final Application application, final Activity activity, final ActivityPluginBinding activityBinding) { synchronized (initializationLock) { Log.i(TAG, "setup"); this.activity = activity; this.context = application; channel = new MethodChannel(messenger, NAMESPACE + "/methods"); channel.setMethodCallHandler(this); stateChannel = new EventChannel(messenger, NAMESPACE + "/state"); stateChannel.setStreamHandler(stateStreamHandler); EventChannel readChannel = new EventChannel(messenger, NAMESPACE + "/read"); readChannel.setStreamHandler(readResultsHandler); mBluetoothManager = (BluetoothManager) application.getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = mBluetoothManager.getAdapter(); activityBinding.addRequestPermissionsResultListener(this); } } private void detach() { Log.i(TAG, "detach"); context = null; activityBinding.removeRequestPermissionsResultListener(this); activityBinding = null; channel.setMethodCallHandler(null); channel = null; stateChannel.setStreamHandler(null); stateChannel = null; mBluetoothAdapter = null; mBluetoothManager = null; } // MethodChannel.Result wrapper that responds on the platform thread. private static class MethodResultWrapper implements Result { private final Result methodResult; private final Handler handler; MethodResultWrapper(Result result) { methodResult = result; handler = new Handler(Looper.getMainLooper()); } @Override public void success(final Object result) { handler.post(() -> methodResult.success(result)); } @Override public void error(@NonNull final String errorCode, final String errorMessage, final Object errorDetails) { handler.post(() -> methodResult.error(errorCode, errorMessage, errorDetails)); } @Override public void notImplemented() { handler.post(methodResult::notImplemented); } } @Override public void onMethodCall(@NonNull MethodCall call, @NonNull Result rawResult) { Result result = new MethodResultWrapper(rawResult); if (mBluetoothAdapter == null && !"isAvailable".equals(call.method)) { result.error("bluetooth_unavailable", "the device does not have bluetooth", null); return; } final Map arguments = call.arguments(); switch (call.method) { case "state": state(result); break; case "isAvailable": result.success(mBluetoothAdapter != null); break; case "isOn": try { result.success(mBluetoothAdapter.isEnabled()); } catch (Exception ex) { result.error("Error", ex.getMessage(), exceptionToString(ex)); } break; case "isConnected": result.success(THREAD != null); break; case "isDeviceConnected": if (arguments.containsKey("address")) { String address = (String) arguments.get("address"); isDeviceConnected(result, address); } else { result.error("invalid_argument", "argument 'address' not found", null); } break; case "openSettings": ContextCompat.startActivity(context, new Intent(android.provider.Settings.ACTION_BLUETOOTH_SETTINGS), null); result.success(true); break; case "getBondedDevices": try { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(activity,new String[]{ Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.ACCESS_FINE_LOCATION, }, 1); pendingResult = result; break; } } else { if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED||ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION }, REQUEST_COARSE_LOCATION_PERMISSIONS); pendingResult = result; break; } } getBondedDevices(result); } catch (Exception ex) { result.error("Error", ex.getMessage(), exceptionToString(ex)); } break; case "connect": if (arguments.containsKey("address")) { String address = (String) arguments.get("address"); connect(result, address); } else { result.error("invalid_argument", "argument 'address' not found", null); } break; case "disconnect": disconnect(result); break; case "write": if (arguments.containsKey("message")) { String message = (String) arguments.get("message"); write(result, message); } else { result.error("invalid_argument", "argument 'message' not found", null); } break; case "writeBytes": if (arguments.containsKey("message")) { byte[] message = (byte[]) arguments.get("message"); writeBytes(result, message); } else { result.error("invalid_argument", "argument 'message' not found", null); } break; case "printCustom": if (arguments.containsKey("message")) { String message = (String) arguments.get("message"); int size = (int) arguments.get("size"); int align = (int) arguments.get("align"); String charset = (String) arguments.get("charset"); printCustom(result, message, size, align, charset); } else { result.error("invalid_argument", "argument 'message' not found", null); } break; case "printNewLine": printNewLine(result); break; case "paperCut": paperCut(result); break; case "drawerPin2": drawerPin2(result); break; case "drawerPin5": drawerPin5(result); break; case "printImage": if (arguments.containsKey("pathImage")) { String pathImage = (String) arguments.get("pathImage"); printImage(result, pathImage); } else { result.error("invalid_argument", "argument 'pathImage' not found", null); } break; case "printImageBytes": if (arguments.containsKey("bytes")) { byte[] bytes = (byte[]) arguments.get("bytes"); printImageBytes(result, bytes); } else { result.error("invalid_argument", "argument 'bytes' not found", null); } break; case "printQRcode": if (arguments.containsKey("textToQR")) { String textToQR = (String) arguments.get("textToQR"); int width = (int) arguments.get("width"); int height = (int) arguments.get("height"); int align = (int) arguments.get("align"); printQRcode(result, textToQR, width, height, align); } else { result.error("invalid_argument", "argument 'textToQR' not found", null); } break; case "printLeftRight": if (arguments.containsKey("string1")) { String string1 = (String) arguments.get("string1"); String string2 = (String) arguments.get("string2"); int size = (int) arguments.get("size"); String charset = (String) arguments.get("charset"); String format = (String) arguments.get("format"); printLeftRight(result, string1, string2, size, charset,format); } else { result.error("invalid_argument", "argument 'message' not found", null); } break; case "print3Column": if (arguments.containsKey("string1")) { String string1 = (String) arguments.get("string1"); String string2 = (String) arguments.get("string2"); String string3 = (String) arguments.get("string3"); int size = (int) arguments.get("size"); String charset = (String) arguments.get("charset"); String format = (String) arguments.get("format"); print3Column(result, string1, string2,string3, size, charset,format); } else { result.error("invalid_argument", "argument 'message' not found", null); } break; case "print4Column": if (arguments.containsKey("string1")) { String string1 = (String) arguments.get("string1"); String string2 = (String) arguments.get("string2"); String string3 = (String) arguments.get("string3"); String string4 = (String) arguments.get("string4"); int size = (int) arguments.get("size"); String charset = (String) arguments.get("charset"); String format = (String) arguments.get("format"); print4Column(result, string1, string2,string3,string4, size, charset,format); } else { result.error("invalid_argument", "argument 'message' not found", null); } break; default: result.notImplemented(); break; } } /** * @param requestCode requestCode * @param permissions permissions * @param grantResults grantResults * @return boolean */ @Override public boolean onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == REQUEST_COARSE_LOCATION_PERMISSIONS) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { getBondedDevices(pendingResult); } else { pendingResult.error("no_permissions", "this plugin requires location permissions for scanning", null); pendingResult = null; } return true; } return false; } private void state(Result result) { try { switch (mBluetoothAdapter.getState()) { case BluetoothAdapter.STATE_OFF: result.success(BluetoothAdapter.STATE_OFF); break; case BluetoothAdapter.STATE_ON: result.success(BluetoothAdapter.STATE_ON); break; case BluetoothAdapter.STATE_TURNING_OFF: result.success(BluetoothAdapter.STATE_TURNING_OFF); break; case BluetoothAdapter.STATE_TURNING_ON: result.success(BluetoothAdapter.STATE_TURNING_ON); break; default: result.success(0); break; } } catch (SecurityException e) { result.error("invalid_argument", "Argument 'address' not found", null); } } /** * @param result result */ private void getBondedDevices(Result result) { List> list = new ArrayList<>(); for (BluetoothDevice device : mBluetoothAdapter.getBondedDevices()) { Map ret = new HashMap<>(); ret.put("address", device.getAddress()); ret.put("name", device.getName()); ret.put("type", device.getType()); list.add(ret); } result.success(list); } /** * @param result result * @param address address */ private void isDeviceConnected(Result result, String address) { AsyncTask.execute(() -> { try { BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); if (device == null) { result.error("connect_error", "device not found", null); return; } if (THREAD != null && device.ACTION_ACL_CONNECTED.equals(new Intent(BluetoothDevice.ACTION_ACL_CONNECTED).getAction())) { result.success(true); }else{ result.success(false); } } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("connect_error", ex.getMessage(), exceptionToString(ex)); } }); } private String exceptionToString(Exception ex) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); ex.printStackTrace(pw); return sw.toString(); } /** * @param result result * @param address address */ private void connect(Result result, String address) { if (THREAD != null) { result.error("connect_error", "already connected", null); return; } AsyncTask.execute(() -> { try { BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); if (device == null) { result.error("connect_error", "device not found", null); return; } BluetoothSocket socket = device.createRfcommSocketToServiceRecord(MY_UUID); if (socket == null) { result.error("connect_error", "socket connection not established", null); return; } // Cancel bt discovery, even though we didn't start it mBluetoothAdapter.cancelDiscovery(); try { socket.connect(); THREAD = new ConnectedThread(socket); THREAD.start(); result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("connect_error", ex.getMessage(), exceptionToString(ex)); } } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("connect_error", ex.getMessage(), exceptionToString(ex)); } }); } /** * @param result result */ private void disconnect(Result result) { if (THREAD == null) { result.error("disconnection_error", "not connected", null); return; } AsyncTask.execute(() -> { try { THREAD.cancel(); THREAD = null; result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("disconnection_error", ex.getMessage(), exceptionToString(ex)); } }); } /** * @param result result * @param message message */ private void write(Result result, String message) { if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { THREAD.write(message.getBytes()); result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private void writeBytes(Result result, byte[] message) { if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { THREAD.write(message); result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private void printCustom(Result result, String message, int size, int align, String charset) { // Print config "mode" byte[] cc = new byte[] { 0x1B, 0x21, 0x03 }; // 0- normal size text // byte[] cc1 = new byte[]{0x1B,0x21,0x00}; // 0- normal size text byte[] bb = new byte[] { 0x1B, 0x21, 0x08 }; // 1- only bold text byte[] bb2 = new byte[] { 0x1B, 0x21, 0x20 }; // 2- bold with medium text byte[] bb3 = new byte[] { 0x1B, 0x21, 0x10 }; // 3- bold with large text byte[] bb4 = new byte[] { 0x1B, 0x21, 0x30 }; // 4- strong text byte[] bb5 = new byte[] { 0x1B, 0x21, 0x50 }; // 5- extra strong text if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { switch (size) { case 0: THREAD.write(cc); break; case 1: THREAD.write(bb); break; case 2: THREAD.write(bb2); break; case 3: THREAD.write(bb3); break; case 4: THREAD.write(bb4); break; case 5: THREAD.write(bb5); } switch (align) { case 0: // left align THREAD.write(PrinterCommands.ESC_ALIGN_LEFT); break; case 1: // center align THREAD.write(PrinterCommands.ESC_ALIGN_CENTER); break; case 2: // right align THREAD.write(PrinterCommands.ESC_ALIGN_RIGHT); break; } if(charset != null) { THREAD.write(message.getBytes(charset)); } else { THREAD.write(message.getBytes()); } THREAD.write(PrinterCommands.FEED_LINE); result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private void printLeftRight(Result result, String msg1, String msg2, int size ,String charset,String format) { byte[] cc = new byte[] { 0x1B, 0x21, 0x03 }; // 0- normal size text // byte[] cc1 = new byte[]{0x1B,0x21,0x00}; // 0- normal size text byte[] bb = new byte[] { 0x1B, 0x21, 0x08 }; // 1- only bold text byte[] bb2 = new byte[] { 0x1B, 0x21, 0x20 }; // 2- bold with medium text byte[] bb3 = new byte[] { 0x1B, 0x21, 0x10 }; // 3- bold with large text byte[] bb4 = new byte[] { 0x1B, 0x21, 0x30 }; // 4- strong text if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { switch (size) { case 0: THREAD.write(cc); break; case 1: THREAD.write(bb); break; case 2: THREAD.write(bb2); break; case 3: THREAD.write(bb3); break; case 4: THREAD.write(bb4); break; } THREAD.write(PrinterCommands.ESC_ALIGN_CENTER); String line = String.format("%-15s %15s %n", msg1, msg2); if(format != null) { line = String.format(format, msg1, msg2); } if(charset != null) { THREAD.write(line.getBytes(charset)); } else { THREAD.write(line.getBytes()); } result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private void print3Column(Result result, String msg1, String msg2, String msg3, int size ,String charset, String format) { byte[] cc = new byte[] { 0x1B, 0x21, 0x03 }; // 0- normal size text // byte[] cc1 = new byte[]{0x1B,0x21,0x00}; // 0- normal size text byte[] bb = new byte[] { 0x1B, 0x21, 0x08 }; // 1- only bold text byte[] bb2 = new byte[] { 0x1B, 0x21, 0x20 }; // 2- bold with medium text byte[] bb3 = new byte[] { 0x1B, 0x21, 0x10 }; // 3- bold with large text byte[] bb4 = new byte[] { 0x1B, 0x21, 0x30 }; // 4- strong text if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { switch (size) { case 0: THREAD.write(cc); break; case 1: THREAD.write(bb); break; case 2: THREAD.write(bb2); break; case 3: THREAD.write(bb3); break; case 4: THREAD.write(bb4); break; } THREAD.write(PrinterCommands.ESC_ALIGN_CENTER); String line = String.format("%-10s %10s %10s %n", msg1, msg2 , msg3); if(format != null) { line = String.format(format, msg1, msg2, msg3); } if(charset != null) { THREAD.write(line.getBytes(charset)); } else { THREAD.write(line.getBytes()); } result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private void print4Column(Result result, String msg1, String msg2,String msg3,String msg4, int size, String charset, String format) { byte[] cc = new byte[] { 0x1B, 0x21, 0x03 }; // 0- normal size text // byte[] cc1 = new byte[]{0x1B,0x21,0x00}; // 0- normal size text byte[] bb = new byte[] { 0x1B, 0x21, 0x08 }; // 1- only bold text byte[] bb2 = new byte[] { 0x1B, 0x21, 0x20 }; // 2- bold with medium text byte[] bb3 = new byte[] { 0x1B, 0x21, 0x10 }; // 3- bold with large text byte[] bb4 = new byte[] { 0x1B, 0x21, 0x30 }; // 4- strong text if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { switch (size) { case 0: THREAD.write(cc); break; case 1: THREAD.write(bb); break; case 2: THREAD.write(bb2); break; case 3: THREAD.write(bb3); break; case 4: THREAD.write(bb4); break; } THREAD.write(PrinterCommands.ESC_ALIGN_CENTER); String line = String.format("%-8s %7s %7s %7s %n", msg1, msg2,msg3,msg4); if(format != null) { line = String.format(format, msg1, msg2,msg3,msg4); } if(charset != null) { THREAD.write(line.getBytes(charset)); } else { THREAD.write(line.getBytes()); } result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private void printNewLine(Result result) { if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { THREAD.write(PrinterCommands.FEED_LINE); result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private void paperCut(Result result) { if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { THREAD.write(PrinterCommands.FEED_PAPER_AND_CUT); result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private void drawerPin2(Result result) { if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { THREAD.write(PrinterCommands.ESC_DRAWER_PIN2); result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private void drawerPin5(Result result) { if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { THREAD.write(PrinterCommands.ESC_DRAWER_PIN5); result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private void printImage(Result result, String pathImage) { if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { Bitmap bmp = BitmapFactory.decodeFile(pathImage); if (bmp != null) { byte[] command = Utils.decodeBitmap(bmp); THREAD.write(PrinterCommands.ESC_ALIGN_CENTER); THREAD.write(command); } else { Log.e("Print Photo error", "the file isn't exists"); } result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private void printImageBytes(Result result, byte[] bytes) { if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); if (bmp != null) { byte[] command = Utils.decodeBitmap(bmp); THREAD.write(PrinterCommands.ESC_ALIGN_CENTER); THREAD.write(command); } else { Log.e("Print Photo error", "the file isn't exists"); } result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private void printQRcode(Result result, String textToQR, int width, int height, int align) { MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); if (THREAD == null) { result.error("write_error", "not connected", null); return; } try { switch (align) { case 0: // left align THREAD.write(PrinterCommands.ESC_ALIGN_LEFT); break; case 1: // center align THREAD.write(PrinterCommands.ESC_ALIGN_CENTER); break; case 2: // right align THREAD.write(PrinterCommands.ESC_ALIGN_RIGHT); break; } BitMatrix bitMatrix = multiFormatWriter.encode(textToQR, BarcodeFormat.QR_CODE, width, height); BarcodeEncoder barcodeEncoder = new BarcodeEncoder(); Bitmap bmp = barcodeEncoder.createBitmap(bitMatrix); if (bmp != null) { byte[] command = Utils.decodeBitmap(bmp); THREAD.write(command); } else { Log.e("Print Photo error", "the file isn't exists"); } result.success(true); } catch (Exception ex) { Log.e(TAG, ex.getMessage(), ex); result.error("write_error", ex.getMessage(), exceptionToString(ex)); } } private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket; private final InputStream inputStream; private final OutputStream outputStream; ConnectedThread(BluetoothSocket socket) { mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; try { tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch (IOException e) { e.printStackTrace(); } inputStream = tmpIn; outputStream = tmpOut; } public void run() { byte[] buffer = new byte[1024]; int bytes; while (true) { try { bytes = inputStream.read(buffer); readSink.success(new String(buffer, 0, bytes)); } catch (NullPointerException e) { break; } catch (IOException e) { break; } } } public void write(byte[] bytes) { try { outputStream.write(bytes); } catch (IOException e) { e.printStackTrace(); } } public void cancel() { try { outputStream.flush(); outputStream.close(); inputStream.close(); mmSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } private final StreamHandler stateStreamHandler = new StreamHandler() { private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); Log.d(TAG, action); if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { THREAD = null; statusSink.success(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1)); } else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) { statusSink.success(1); } else if (BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) { THREAD = null; statusSink.success(2); } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) { THREAD = null; statusSink.success(0); } } }; @Override public void onListen(Object o, EventSink eventSink) { statusSink = eventSink; context.registerReceiver(mReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); context.registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED)); context.registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED)); context.registerReceiver(mReceiver, new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED)); } @Override public void onCancel(Object o) { statusSink = null; context.unregisterReceiver(mReceiver); } }; private final StreamHandler readResultsHandler = new StreamHandler() { @Override public void onListen(Object o, EventSink eventSink) { readSink = eventSink; } @Override public void onCancel(Object o) { readSink = null; } }; } ================================================ FILE: android/src/main/java/id/kakzaki/blue_thermal_printer/PrinterCommands.java ================================================ package id.kakzaki.blue_thermal_printer; /** * Created by https://goo.gl/UAfmBd on 2/6/2017. */ public class PrinterCommands { public static final byte HT = 0x9; public static final byte LF = 0x0A; public static final byte CR = 0x0D; public static final byte ESC = 0x1B; public static final byte DLE = 0x10; public static final byte GS = 0x1D; public static final byte FS = 0x1C; public static final byte STX = 0x02; public static final byte US = 0x1F; public static final byte CAN = 0x18; public static final byte CLR = 0x0C; public static final byte EOT = 0x04; public static final byte[] INIT = {27, 64}; public static byte[] FEED_LINE = {10}; public static byte[] SELECT_FONT_A = {20, 33, 0}; public static byte[] SET_BAR_CODE_HEIGHT = {29, 104, 100}; public static byte[] PRINT_BAR_CODE_1 = {29, 107, 2}; public static byte[] SEND_NULL_BYTE = {0x00}; public static byte[] SELECT_PRINT_SHEET = {0x1B, 0x63, 0x30, 0x02}; public static byte[] FEED_PAPER_AND_CUT = {0x1D, 0x56, 66, 0x00}; public static byte[] SELECT_CYRILLIC_CHARACTER_CODE_TABLE = {0x1B, 0x74, 0x11}; public static byte[] SELECT_BIT_IMAGE_MODE = {0x1B, 0x2A, 33, -128, 0}; public static byte[] SET_LINE_SPACING_24 = {0x1B, 0x33, 24}; public static byte[] SET_LINE_SPACING_30 = {0x1B, 0x33, 30}; public static byte[] TRANSMIT_DLE_PRINTER_STATUS = {0x10, 0x04, 0x01}; public static byte[] TRANSMIT_DLE_OFFLINE_PRINTER_STATUS = {0x10, 0x04, 0x02}; public static byte[] TRANSMIT_DLE_ERROR_STATUS = {0x10, 0x04, 0x03}; public static byte[] TRANSMIT_DLE_ROLL_PAPER_SENSOR_STATUS = {0x10, 0x04, 0x04}; public static final byte[] ESC_FONT_COLOR_DEFAULT = new byte[] { 0x1B, 'r',0x00 }; public static final byte[] FS_FONT_ALIGN = new byte[] { 0x1C, 0x21, 1, 0x1B, 0x21, 1 }; public static final byte[] ESC_ALIGN_LEFT = new byte[] { 0x1b, 'a', 0x00 }; public static final byte[] ESC_ALIGN_RIGHT = new byte[] { 0x1b, 'a', 0x02 }; public static final byte[] ESC_ALIGN_CENTER = new byte[] { 0x1b, 'a', 0x01 }; public static final byte[] ESC_CANCEL_BOLD = new byte[] { 0x1B, 0x45, 0 }; /*********************************************/ public static final byte[] ESC_HORIZONTAL_CENTERS = new byte[] { 0x1B, 0x44, 20, 28, 00}; public static final byte[] ESC_CANCLE_HORIZONTAL_CENTERS = new byte[] { 0x1B, 0x44, 00 }; /*********************************************/ /*********** Open Cash Drawer ****************/ public static final byte[] ESC_DRAWER_PIN2 = new byte[] { 0x1B, 'p', 0x30 }; public static final byte[] ESC_DRAWER_PIN5 = new byte[] { 0x1B, 'p', 0x31 }; /*********************************************/ public static final byte[] ESC_ENTER = new byte[] { 0x1B, 0x4A, 0x40 }; public static final byte[] PRINTE_TEST = new byte[] { 0x1D, 0x28, 0x41 }; } ================================================ FILE: android/src/main/java/id/kakzaki/blue_thermal_printer/Utils.java ================================================ package id.kakzaki.blue_thermal_printer; import android.graphics.Bitmap; import android.util.Log; import java.util.ArrayList; import java.util.List; public class Utils { // UNICODE 0x23 = # public static final byte[] UNICODE_TEXT = new byte[] {0x23, 0x23, 0x23, 0x23, 0x23, 0x23,0x23, 0x23, 0x23,0x23, 0x23, 0x23,0x23, 0x23, 0x23, 0x23, 0x23, 0x23,0x23, 0x23, 0x23,0x23, 0x23, 0x23,0x23, 0x23, 0x23, 0x23, 0x23, 0x23}; private static String hexStr = "0123456789ABCDEF"; private static String[] binaryArray = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; public static byte[] decodeBitmap(Bitmap bmp){ int bmpWidth = bmp.getWidth(); int bmpHeight = bmp.getHeight(); List list = new ArrayList(); //binaryString list StringBuffer sb; int bitLen = bmpWidth / 8; int zeroCount = bmpWidth % 8; String zeroStr = ""; if (zeroCount > 0) { bitLen = bmpWidth / 8 + 1; for (int i = 0; i < (8 - zeroCount); i++) { zeroStr = zeroStr + "0"; } } for (int i = 0; i < bmpHeight; i++) { sb = new StringBuffer(); for (int j = 0; j < bmpWidth; j++) { int color = bmp.getPixel(j, i); int r = (color >> 16) & 0xff; int g = (color >> 8) & 0xff; int b = color & 0xff; // if color close to white,bit='0', else bit='1' if (r > 160 && g > 160 && b > 160) sb.append("0"); else sb.append("1"); } if (zeroCount > 0) { sb.append(zeroStr); } list.add(sb.toString()); } List bmpHexList = binaryListToHexStringList(list); String commandHexString = "1D763000"; String widthHexString = Integer .toHexString(bmpWidth % 8 == 0 ? bmpWidth / 8 : (bmpWidth / 8 + 1)); if (widthHexString.length() > 10) { Log.e("decodeBitmap error", " width is too large"); return null; } else if (widthHexString.length() == 1) { widthHexString = "0" + widthHexString; } widthHexString = widthHexString + "00"; String heightHexString = Integer.toHexString(bmpHeight); if (heightHexString.length() > 10) { Log.e("decodeBitmap error", " height is too large"); return null; } else if (heightHexString.length() == 1) { heightHexString = "0" + heightHexString; } heightHexString = heightHexString + "00"; List commandList = new ArrayList(); commandList.add(commandHexString+widthHexString+heightHexString); commandList.addAll(bmpHexList); return hexList2Byte(commandList); } public static List binaryListToHexStringList(List list) { List hexList = new ArrayList(); for (String binaryStr : list) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < binaryStr.length(); i += 8) { String str = binaryStr.substring(i, i + 8); String hexString = myBinaryStrToHexString(str); sb.append(hexString); } hexList.add(sb.toString()); } return hexList; } public static String myBinaryStrToHexString(String binaryStr) { String hex = ""; String f4 = binaryStr.substring(0, 4); String b4 = binaryStr.substring(4, 8); for (int i = 0; i < binaryArray.length; i++) { if (f4.equals(binaryArray[i])) hex += hexStr.substring(i, i + 1); } for (int i = 0; i < binaryArray.length; i++) { if (b4.equals(binaryArray[i])) hex += hexStr.substring(i, i + 1); } return hex; } public static byte[] hexList2Byte(List list) { List commandList = new ArrayList(); for (String hexStr : list) { commandList.add(hexStringToBytes(hexStr)); } byte[] bytes = sysCopy(commandList); return bytes; } public static byte[] hexStringToBytes(String hexString) { if (hexString == null || hexString.equals("")) { return null; } hexString = hexString.toUpperCase(); int length = hexString.length() / 2; char[] hexChars = hexString.toCharArray(); byte[] d = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } return d; } public static byte[] sysCopy(List srcArrays) { int len = 0; for (byte[] srcArray : srcArrays) { len += srcArray.length; } byte[] destArray = new byte[len]; int destLen = 0; for (byte[] srcArray : srcArrays) { System.arraycopy(srcArray, 0, destArray, destLen, srcArray.length); destLen += srcArray.length; } return destArray; } private static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } } ================================================ FILE: blue_thermal_printer.iml ================================================ ================================================ FILE: example/.flutter-plugins-dependencies ================================================ {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"blue_thermal_printer","path":"E:\\\\MYPLUGIN\\\\blue_thermal_printer\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_ios","path":"E:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_ios-2.0.10\\\\","native_build":true,"dependencies":[]}],"android":[{"name":"blue_thermal_printer","path":"E:\\\\MYPLUGIN\\\\blue_thermal_printer\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"E:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_android-2.0.16\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"blue_thermal_printer","path":"E:\\\\MYPLUGIN\\\\blue_thermal_printer\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_macos","path":"E:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_macos-2.0.6\\\\","native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"E:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_linux-2.1.7\\\\","native_build":false,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"E:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\path_provider_windows-2.1.0\\\\","native_build":false,"dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"blue_thermal_printer","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_ios","path_provider_linux","path_provider_macos","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_ios","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2022-07-19 16:38:12.856554","version":"3.0.5"} ================================================ FILE: example/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # Visual Studio Code related .vscode/ # Flutter/Dart/Pub related **/doc/api/ .dart_tool/ .flutter-plugins .packages .pub-cache/ .pub/ /build/ # Android related **/android/**/gradle-wrapper.jar **/android/.gradle **/android/captures/ **/android/gradlew **/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java # iOS/XCode related **/ios/**/*.mode1v3 **/ios/**/*.mode2v3 **/ios/**/*.moved-aside **/ios/**/*.pbxuser **/ios/**/*.perspectivev3 **/ios/**/*sync/ **/ios/**/.sconsign.dblite **/ios/**/.tags* **/ios/**/.vagrant/ **/ios/**/DerivedData/ **/ios/**/Icon? **/ios/**/Pods/ **/ios/**/.symlinks/ **/ios/**/profile **/ios/**/xcuserdata **/ios/.generated/ **/ios/Flutter/App.framework **/ios/Flutter/Flutter.framework **/ios/Flutter/Generated.xcconfig **/ios/Flutter/app.flx **/ios/Flutter/app.zip **/ios/Flutter/flutter_assets/ **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !**/ios/**/default.mode1v3 !**/ios/**/default.mode2v3 !**/ios/**/default.pbxuser !**/ios/**/default.perspectivev3 !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages ================================================ FILE: example/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b channel: stable project_type: app ================================================ FILE: example/README.md ================================================ # blue_thermal_printer_example Demonstrates how to use the blue_thermal_printer plugin. ================================================ FILE: example/android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion 31 lintOptions { disable 'InvalidPackage' } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "id.kakzaki.blue_thermal_printer_example" minSdkVersion 18 targetSdkVersion 31 multiDexEnabled true versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } } // buildToolsVersion '29.0.2' compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } flutter { source '../..' } dependencies { testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test:runner:1.5.0-alpha04' implementation 'com.android.support:multidex:1.0.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0-alpha07' } ================================================ FILE: example/android/app/src/debug/AndroidManifest.xml ================================================ ================================================ FILE: example/android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: example/android/app/src/main/java/id/kakzaki/blue_thermal_printer_example/MainActivity.java ================================================ package id.kakzaki.blue_thermal_printer_example; import io.flutter.embedding.android.FlutterActivity; public class MainActivity extends FlutterActivity { } ================================================ FILE: example/android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: example/android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: example/android/app/src/profile/AndroidManifest.xml ================================================ ================================================ FILE: example/android/build.gradle ================================================ buildscript { repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:7.2.0' } } allprojects { repositories { google() mavenCentral() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { project.evaluationDependsOn(':app') } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: example/android/gradle/wrapper/gradle-wrapper.properties ================================================ #Fri Aug 30 12:26:22 BRT 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip ================================================ FILE: example/android/gradle.properties ================================================ android.enableJetifier=true android.useAndroidX=true org.gradle.jvmargs=-Xmx1536M ================================================ FILE: example/android/settings.gradle ================================================ include ':app' def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() def plugins = new Properties() def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') if (pluginsFile.exists()) { pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } } plugins.each { name, path -> def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() include ":$name" project(":$name").projectDir = pluginDirectory } ================================================ FILE: example/ios/Flutter/AppFrameworkInfo.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable App CFBundleIdentifier io.flutter.flutter.app CFBundleInfoDictionaryVersion 6.0 CFBundleName App CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 MinimumOSVersion 8.0 ================================================ FILE: example/ios/Flutter/Debug.xcconfig ================================================ #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" ================================================ FILE: example/ios/Flutter/Release.xcconfig ================================================ #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" ================================================ FILE: example/ios/Flutter/flutter_export_environment.sh ================================================ #!/bin/sh # This is a generated file; do not edit or check into version control. export "FLUTTER_ROOT=E:\flutter" export "FLUTTER_APPLICATION_PATH=E:\MYPLUGIN\blue_thermal_printer\example" export "COCOAPODS_PARALLEL_CODE_SIGN=true" export "FLUTTER_TARGET=lib\main.dart" export "FLUTTER_BUILD_DIR=build" export "FLUTTER_BUILD_NAME=1.0.0" export "FLUTTER_BUILD_NUMBER=1" export "DART_OBFUSCATION=false" export "TRACK_WIDGET_CREATION=false" export "TREE_SHAKE_ICONS=false" export "PACKAGE_CONFIG=.dart_tool/package_config.json" ================================================ FILE: example/ios/Podfile ================================================ # Uncomment this line to define a global platform for your project # platform :ios, '9.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' project 'Runner', { 'Debug' => :debug, 'Profile' => :release, 'Release' => :release, } def parse_KV_file(file, separator='=') file_abs_path = File.expand_path(file) if !File.exists? file_abs_path return []; end generated_key_values = {} skip_line_start_symbols = ["#", "/"] File.foreach(file_abs_path) do |line| next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } plugin = line.split(pattern=separator) if plugin.length == 2 podname = plugin[0].strip() path = plugin[1].strip() podpath = File.expand_path("#{path}", file_abs_path) generated_key_values[podname] = podpath else puts "Invalid plugin specification: #{line}" end end generated_key_values end target 'Runner' do use_frameworks! use_modular_headers! # Flutter Pod copied_flutter_dir = File.join(__dir__, 'Flutter') copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') unless File.exist?(generated_xcode_build_settings_path) raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" end generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; unless File.exist?(copied_framework_path) FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) end unless File.exist?(copied_podspec_path) FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) end end # Keep pod path relative so it can be checked into Podfile.lock. pod 'Flutter', :path => 'Flutter' # Plugin Pods # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock # referring to absolute paths on developers' machines. system('rm -rf .symlinks') system('mkdir -p .symlinks/plugins') plugin_pods = parse_KV_file('../.flutter-plugins') plugin_pods.each do |name, path| symlink = File.join('.symlinks', 'plugins', name) File.symlink(path, symlink) pod name, :path => File.join(symlink, 'ios') end end post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['ENABLE_BITCODE'] = 'NO' end end end ================================================ FILE: example/ios/Runner/AppDelegate.swift ================================================ import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } ================================================ FILE: example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "size" : "20x20", "idiom" : "iphone", "filename" : "Icon-App-20x20@2x.png", "scale" : "2x" }, { "size" : "20x20", "idiom" : "iphone", "filename" : "Icon-App-20x20@3x.png", "scale" : "3x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-App-29x29@1x.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-App-29x29@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "iphone", "filename" : "Icon-App-29x29@3x.png", "scale" : "3x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-App-40x40@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "iphone", "filename" : "Icon-App-40x40@3x.png", "scale" : "3x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-App-60x60@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "Icon-App-60x60@3x.png", "scale" : "3x" }, { "size" : "20x20", "idiom" : "ipad", "filename" : "Icon-App-20x20@1x.png", "scale" : "1x" }, { "size" : "20x20", "idiom" : "ipad", "filename" : "Icon-App-20x20@2x.png", "scale" : "2x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "Icon-App-29x29@1x.png", "scale" : "1x" }, { "size" : "29x29", "idiom" : "ipad", "filename" : "Icon-App-29x29@2x.png", "scale" : "2x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "Icon-App-40x40@1x.png", "scale" : "1x" }, { "size" : "40x40", "idiom" : "ipad", "filename" : "Icon-App-40x40@2x.png", "scale" : "2x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "Icon-App-76x76@1x.png", "scale" : "1x" }, { "size" : "76x76", "idiom" : "ipad", "filename" : "Icon-App-76x76@2x.png", "scale" : "2x" }, { "size" : "83.5x83.5", "idiom" : "ipad", "filename" : "Icon-App-83.5x83.5@2x.png", "scale" : "2x" }, { "size" : "1024x1024", "idiom" : "ios-marketing", "filename" : "Icon-App-1024x1024@1x.png", "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # Launch Screen Assets You can customize the launch screen with your own desired assets by replacing the image files in this directory. You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. ================================================ FILE: example/ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: example/ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: example/ios/Runner/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName blue_thermal_printer_example CFBundlePackageType APPL CFBundleShortVersionString $(FLUTTER_BUILD_NAME) CFBundleSignature ???? CFBundleVersion $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIViewControllerBasedStatusBarAppearance ================================================ FILE: example/ios/Runner/Runner-Bridging-Header.h ================================================ #import "GeneratedPluginRegistrant.h" ================================================ FILE: example/ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ 9705A1C41CF9048500538489 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( 3B80C3931E831B6300D905FE /* App.framework */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEBA1CF902C7004384FC /* Flutter.framework */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 9740EEB31CF90195004384FC /* Generated.xcconfig */, ); name = Flutter; sourceTree = ""; }; 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, ); sourceTree = ""; }; 97C146EF1CF9000F007C117D /* Products */ = { isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, ); name = Products; sourceTree = ""; }; 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C147021CF9000F007C117D /* Info.plist */, 97C146F11CF9000F007C117D /* Supporting Files */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, ); path = Runner; sourceTree = ""; }; 97C146F11CF9000F007C117D /* Supporting Files */ = { isa = PBXGroup; children = ( ); name = "Supporting Files"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 97C146ED1CF9000F007C117D /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, ); buildRules = ( ); dependencies = ( ); name = Runner; productName = Runner; productReference = 97C146EE1CF9000F007C117D /* Runner.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0910; ORGANIZATIONNAME = "The Chromium Authors"; TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; LastSwiftMigration = 0910; }; }; }; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 97C146E51CF9000F007C117D; productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 97C146EC1CF9000F007C117D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Thin Binary"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Run Script"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 97C146EA1CF9000F007C117D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 97C146FA1CF9000F007C117D /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 97C146FB1CF9000F007C117D /* Base */, ); name = Main.storyboard; sourceTree = ""; }; 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 97C147001CF9000F007C117D /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 249021D3217E4FDB00AE95B9 /* Profile */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Profile; }; 249021D4217E4FDB00AE95B9 /* Profile */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = S8QB4VV633; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = id.kakzaki.blueThermalPrinterExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 4.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Profile; }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; 97C147061CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = id.kakzaki.blueThermalPrinterExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = On; SWIFT_VERSION = 4.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; }; 97C147071CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Flutter", ); PRODUCT_BUNDLE_IDENTIFIER = id.kakzaki.blueThermalPrinterExample; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_SWIFT3_OBJC_INFERENCE = On; SWIFT_VERSION = 4.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( 97C147031CF9000F007C117D /* Debug */, 97C147041CF9000F007C117D /* Release */, 249021D3217E4FDB00AE95B9 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( 97C147061CF9000F007C117D /* Debug */, 97C147071CF9000F007C117D /* Release */, 249021D4217E4FDB00AE95B9 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } ================================================ FILE: example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: example/ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: example/lib/main.dart ================================================ import 'package:blue_thermal_printer_example/testprint.dart'; import 'package:flutter/material.dart'; import 'dart:async'; import 'package:blue_thermal_printer/blue_thermal_printer.dart'; import 'package:flutter/services.dart'; void main() => runApp(new MyApp()); class MyApp extends StatefulWidget { @override _MyAppState createState() => new _MyAppState(); } class _MyAppState extends State { BlueThermalPrinter bluetooth = BlueThermalPrinter.instance; List _devices = []; BluetoothDevice? _device; bool _connected = false; TestPrint testPrint = TestPrint(); @override void initState() { super.initState(); initPlatformState(); } Future initPlatformState() async { // TODO here add a permission request using permission_handler // if permission is not granted, kzaki's thermal print plugin will ask for location permission // which will invariably crash the app even if user agrees so we'd better ask it upfront // var statusLocation = Permission.location; // if (await statusLocation.isGranted != true) { // await Permission.location.request(); // } // if (await statusLocation.isGranted) { // ... // } else { // showDialogSayingThatThisPermissionIsRequired()); // } bool? isConnected = await bluetooth.isConnected; List devices = []; try { devices = await bluetooth.getBondedDevices(); } on PlatformException {} bluetooth.onStateChanged().listen((state) { switch (state) { case BlueThermalPrinter.CONNECTED: setState(() { _connected = true; print("bluetooth device state: connected"); }); break; case BlueThermalPrinter.DISCONNECTED: setState(() { _connected = false; print("bluetooth device state: disconnected"); }); break; case BlueThermalPrinter.DISCONNECT_REQUESTED: setState(() { _connected = false; print("bluetooth device state: disconnect requested"); }); break; case BlueThermalPrinter.STATE_TURNING_OFF: setState(() { _connected = false; print("bluetooth device state: bluetooth turning off"); }); break; case BlueThermalPrinter.STATE_OFF: setState(() { _connected = false; print("bluetooth device state: bluetooth off"); }); break; case BlueThermalPrinter.STATE_ON: setState(() { _connected = false; print("bluetooth device state: bluetooth on"); }); break; case BlueThermalPrinter.STATE_TURNING_ON: setState(() { _connected = false; print("bluetooth device state: bluetooth turning on"); }); break; case BlueThermalPrinter.ERROR: setState(() { _connected = false; print("bluetooth device state: error"); }); break; default: print(state); break; } }); if (!mounted) return; setState(() { _devices = devices; }); if (isConnected == true) { setState(() { _connected = true; }); } } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Blue Thermal Printer'), ), body: Padding( padding: const EdgeInsets.all(8.0), child: ListView( children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.start, children: [ const SizedBox(width: 10), const Text( 'Device:', style: TextStyle( fontWeight: FontWeight.bold, ), ), const SizedBox(width: 30), Expanded( child: DropdownButton( items: _getDeviceItems(), onChanged: (BluetoothDevice? value) => setState(() => _device = value), value: _device, ), ), ], ), const SizedBox(height: 10), Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.end, children: [ ElevatedButton( style: ElevatedButton.styleFrom(primary: Colors.brown), onPressed: () { initPlatformState(); }, child: const Text( 'Refresh', style: TextStyle(color: Colors.white), ), ), const SizedBox(width: 20), ElevatedButton( style: ElevatedButton.styleFrom( primary: _connected ? Colors.red : Colors.green), onPressed: _connected ? _disconnect : _connect, child: Text( _connected ? 'Disconnect' : 'Connect', style: TextStyle(color: Colors.white), ), ), ], ), Padding( padding: const EdgeInsets.only(left: 10.0, right: 10.0, top: 50), child: ElevatedButton( style: ElevatedButton.styleFrom(primary: Colors.brown), onPressed: () { testPrint.sample(); }, child: const Text('PRINT TEST', style: TextStyle(color: Colors.white)), ), ), ], ), ), ), ); } List> _getDeviceItems() { List> items = []; if (_devices.isEmpty) { items.add(DropdownMenuItem( child: Text('NONE'), )); } else { _devices.forEach((device) { items.add(DropdownMenuItem( child: Text(device.name ?? ""), value: device, )); }); } return items; } void _connect() { if (_device != null) { bluetooth.isConnected.then((isConnected) { if (isConnected == false) { bluetooth.connect(_device!).catchError((error) { setState(() => _connected = false); }); setState(() => _connected = true); } }); } else { show('No device selected.'); } } void _disconnect() { bluetooth.disconnect(); setState(() => _connected = false); } Future show( String message, { Duration duration: const Duration(seconds: 3), }) async { await new Future.delayed(new Duration(milliseconds: 100)); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( message, style: const TextStyle(color: Colors.white), ), duration: duration, ), ); } } ================================================ FILE: example/lib/printerenum.dart ================================================ enum Size { medium, //normal size text bold, //only bold text boldMedium, //bold with medium boldLarge, //bold with large extraLarge //extra large } enum Align { left, //ESC_ALIGN_LEFT center, //ESC_ALIGN_CENTER right, //ESC_ALIGN_RIGHT } extension PrintSize on Size { int get val { switch (this) { case Size.medium: return 0; case Size.bold: return 1; case Size.boldMedium: return 2; case Size.boldLarge: return 3; case Size.extraLarge: return 4; default: return 0; } } } extension PrintAlign on Align { int get val { switch (this) { case Align.left: return 0; case Align.center: return 1; case Align.right: return 2; default: return 0; } } } ================================================ FILE: example/lib/testprint.dart ================================================ import 'dart:typed_data'; import 'package:blue_thermal_printer_example/printerenum.dart'; import 'package:flutter/services.dart'; import 'package:path_provider/path_provider.dart'; import 'package:blue_thermal_printer/blue_thermal_printer.dart'; import 'dart:io'; import 'package:http/http.dart' as http; ///Test printing class TestPrint { BlueThermalPrinter bluetooth = BlueThermalPrinter.instance; sample() async { //image max 300px X 300px ///image from File path String filename = 'yourlogo.png'; ByteData bytesData = await rootBundle.load("assets/images/yourlogo.png"); String dir = (await getApplicationDocumentsDirectory()).path; File file = await File('$dir/$filename').writeAsBytes(bytesData.buffer .asUint8List(bytesData.offsetInBytes, bytesData.lengthInBytes)); ///image from Asset ByteData bytesAsset = await rootBundle.load("assets/images/yourlogo.png"); Uint8List imageBytesFromAsset = bytesAsset.buffer .asUint8List(bytesAsset.offsetInBytes, bytesAsset.lengthInBytes); ///image from Network var response = await http.get(Uri.parse( "https://raw.githubusercontent.com/kakzaki/blue_thermal_printer/master/example/assets/images/yourlogo.png")); Uint8List bytesNetwork = response.bodyBytes; Uint8List imageBytesFromNetwork = bytesNetwork.buffer .asUint8List(bytesNetwork.offsetInBytes, bytesNetwork.lengthInBytes); bluetooth.isConnected.then((isConnected) { if (isConnected == true) { bluetooth.printNewLine(); bluetooth.printCustom("HEADER", Size.boldMedium.val, Align.center.val); bluetooth.printNewLine(); bluetooth.printImage(file.path); //path of your image/logo bluetooth.printNewLine(); bluetooth.printImageBytes(imageBytesFromAsset); //image from Asset bluetooth.printNewLine(); bluetooth.printImageBytes(imageBytesFromNetwork); //image from Network bluetooth.printNewLine(); bluetooth.printLeftRight("LEFT", "RIGHT", Size.medium.val); bluetooth.printLeftRight("LEFT", "RIGHT", Size.bold.val); bluetooth.printLeftRight("LEFT", "RIGHT", Size.bold.val, format: "%-15s %15s %n"); //15 is number off character from left or right bluetooth.printNewLine(); bluetooth.printLeftRight("LEFT", "RIGHT", Size.boldMedium.val); bluetooth.printLeftRight("LEFT", "RIGHT", Size.boldLarge.val); bluetooth.printLeftRight("LEFT", "RIGHT", Size.extraLarge.val); bluetooth.printNewLine(); bluetooth.print3Column("Col1", "Col2", "Col3", Size.bold.val); bluetooth.print3Column("Col1", "Col2", "Col3", Size.bold.val, format: "%-10s %10s %10s %n"); //10 is number off character from left center and right bluetooth.printNewLine(); bluetooth.print4Column("Col1", "Col2", "Col3", "Col4", Size.bold.val); bluetooth.print4Column("Col1", "Col2", "Col3", "Col4", Size.bold.val, format: "%-8s %7s %7s %7s %n"); bluetooth.printNewLine(); bluetooth.printCustom("čĆžŽšŠ-H-ščđ", Size.bold.val, Align.center.val, charset: "windows-1250"); bluetooth.printLeftRight("Številka:", "18000001", Size.bold.val, charset: "windows-1250"); bluetooth.printCustom("Body left", Size.bold.val, Align.left.val); bluetooth.printCustom("Body right", Size.medium.val, Align.right.val); bluetooth.printNewLine(); bluetooth.printCustom("Thank You", Size.bold.val, Align.center.val); bluetooth.printNewLine(); bluetooth.printQRcode( "Insert Your Own Text to Generate", 200, 200, Align.center.val); bluetooth.printNewLine(); bluetooth.printNewLine(); bluetooth .paperCut(); //some printer not supported (sometime making image not centered) //bluetooth.drawerPin2(); // or you can use bluetooth.drawerPin5(); } }); } // sample(String pathImage) async { // //SIZE // // 0- normal size text // // 1- only bold text // // 2- bold with medium text // // 3- bold with large text // //ALIGN // // 0- ESC_ALIGN_LEFT // // 1- ESC_ALIGN_CENTER // // 2- ESC_ALIGN_RIGHT // // // var response = await http.get("IMAGE_URL"); // // Uint8List bytes = response.bodyBytes; // bluetooth.isConnected.then((isConnected) { // if (isConnected == true) { // bluetooth.printNewLine(); // bluetooth.printCustom("HEADER", 3, 1); // bluetooth.printNewLine(); // bluetooth.printImage(pathImage); //path of your image/logo // bluetooth.printNewLine(); // // bluetooth.printImageBytes(bytes.buffer.asUint8List(bytes.offsetInBytes, bytes.lengthInBytes)); // bluetooth.printLeftRight("LEFT", "RIGHT", 0); // bluetooth.printLeftRight("LEFT", "RIGHT", 1); // bluetooth.printLeftRight("LEFT", "RIGHT", 1, format: "%-15s %15s %n"); // bluetooth.printNewLine(); // bluetooth.printLeftRight("LEFT", "RIGHT", 2); // bluetooth.printLeftRight("LEFT", "RIGHT", 3); // bluetooth.printLeftRight("LEFT", "RIGHT", 4); // bluetooth.printNewLine(); // bluetooth.print3Column("Col1", "Col2", "Col3", 1); // bluetooth.print3Column("Col1", "Col2", "Col3", 1, // format: "%-10s %10s %10s %n"); // bluetooth.printNewLine(); // bluetooth.print4Column("Col1", "Col2", "Col3", "Col4", 1); // bluetooth.print4Column("Col1", "Col2", "Col3", "Col4", 1, // format: "%-8s %7s %7s %7s %n"); // bluetooth.printNewLine(); // String testString = " čĆžŽšŠ-H-ščđ"; // bluetooth.printCustom(testString, 1, 1, charset: "windows-1250"); // bluetooth.printLeftRight("Številka:", "18000001", 1, // charset: "windows-1250"); // bluetooth.printCustom("Body left", 1, 0); // bluetooth.printCustom("Body right", 0, 2); // bluetooth.printNewLine(); // bluetooth.printCustom("Thank You", 2, 1); // bluetooth.printNewLine(); // bluetooth.printQRcode("Insert Your Own Text to Generate", 200, 200, 1); // bluetooth.printNewLine(); // bluetooth.printNewLine(); // bluetooth.paperCut(); // } // }); // } } ================================================ FILE: example/pubspec.yaml ================================================ name: blue_thermal_printer_example description: Demonstrates how to use the blue_thermal_printer plugin. publish_to: https://pub.dev/packages/blue_thermal_printer environment: sdk: ">=2.12.0 <3.0.0" dependencies: flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. path_provider: ^2.0.11 http: ^0.13.1 dev_dependencies: flutter_test: sdk: flutter blue_thermal_printer: path: ../ # For information on the generic Dart part of this file, see the # following page: https://www.dartlang.org/tools/pub/pubspec # The following section is specific to Flutter. flutter: # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true # To add assets to your application, add an assets section, like this: assets: - assets/images/yourlogo.png # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. # For details regarding adding assets from package dependencies, see # https://flutter.dev/assets-and-images/#from-packages # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages ================================================ FILE: example/test/widget_test.dart ================================================ import 'package:blue_thermal_printer_example/main.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { testWidgets('Verify Platform version', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(MyApp()); }); } ================================================ FILE: gradle.properties ================================================ android.enableJetifier=true android.useAndroidX=true ================================================ FILE: ios/.gitignore ================================================ .idea/ .vagrant/ .sconsign.dblite .svn/ .DS_Store *.swp profile DerivedData/ build/ GeneratedPluginRegistrant.h GeneratedPluginRegistrant.m .generated/ *.pbxuser *.mode1v3 *.mode2v3 *.perspectivev3 !default.pbxuser !default.mode1v3 !default.mode2v3 !default.perspectivev3 xcuserdata *.moved-aside *.pyc *sync/ Icon? .tags* /Flutter/Generated.xcconfig ================================================ FILE: ios/Assets/.gitkeep ================================================ ================================================ FILE: ios/Classes/BlueThermalPrinterPlugin.h ================================================ #import @interface BlueThermalPrinterPlugin : NSObject @end ================================================ FILE: ios/Classes/BlueThermalPrinterPlugin.m ================================================ #import "BlueThermalPrinterPlugin.h" #import @implementation BlueThermalPrinterPlugin + (void)registerWithRegistrar:(NSObject*)registrar { [SwiftBlueThermalPrinterPlugin registerWithRegistrar:registrar]; } @end ================================================ FILE: ios/Classes/SwiftBlueThermalPrinterPlugin.swift ================================================ import Flutter import UIKit public class SwiftBlueThermalPrinterPlugin: NSObject, FlutterPlugin { public static func register(with registrar: FlutterPluginRegistrar) { let channel = FlutterMethodChannel(name: "blue_thermal_printer", binaryMessenger: registrar.messenger()) let instance = SwiftBlueThermalPrinterPlugin() registrar.addMethodCallDelegate(instance, channel: channel) } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { result("iOS " + UIDevice.current.systemVersion) } } ================================================ FILE: ios/blue_thermal_printer.podspec ================================================ # # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html # Pod::Spec.new do |s| s.name = 'blue_thermal_printer' s.version = '0.0.1' s.summary = 'A new Flutter plugin for connecting to thermal printer via bluetooth' s.description = <<-DESC A new Flutter plugin for connecting to thermal printer vie bluetooth DESC s.homepage = 'http://kakzaki.my.id' s.license = { :file => '../LICENSE' } s.author = { 'Zaki Mubarok' => 'kakzaki@gmail.com' } s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' s.ios.deployment_target = '8.0' end ================================================ FILE: lib/blue_thermal_printer.dart ================================================ import 'dart:async'; import 'dart:typed_data'; import 'package:flutter/services.dart'; class BlueThermalPrinter { static const int STATE_OFF = 10; static const int STATE_TURNING_ON = 11; static const int STATE_ON = 12; static const int STATE_TURNING_OFF = 13; static const int STATE_BLE_TURNING_ON = 14; static const int STATE_BLE_ON = 15; static const int STATE_BLE_TURNING_OFF = 16; static const int ERROR = -1; static const int CONNECTED = 1; static const int DISCONNECTED = 0; static const int DISCONNECT_REQUESTED = 2; static const String namespace = 'blue_thermal_printer'; static const MethodChannel _channel = const MethodChannel('$namespace/methods'); static const EventChannel _readChannel = const EventChannel('$namespace/read'); static const EventChannel _stateChannel = const EventChannel('$namespace/state'); final StreamController _methodStreamController = new StreamController.broadcast(); //Stream get _methodStream => _methodStreamController.stream; BlueThermalPrinter._() { _channel.setMethodCallHandler((MethodCall call) async { _methodStreamController.add(call); }); } static BlueThermalPrinter _instance = new BlueThermalPrinter._(); static BlueThermalPrinter get instance => _instance; ///onStateChanged() Stream onStateChanged() async* { yield await _channel.invokeMethod('state').then((buffer) => buffer); yield* _stateChannel.receiveBroadcastStream().map((buffer) => buffer); } ///onRead() Stream onRead() => _readChannel.receiveBroadcastStream().map((buffer) => buffer.toString()); Future get isAvailable async => await _channel.invokeMethod('isAvailable'); Future get isOn async => await _channel.invokeMethod('isOn'); Future get isConnected async => await _channel.invokeMethod('isConnected'); Future get openSettings async => await _channel.invokeMethod('openSettings'); ///getBondedDevices() Future> getBondedDevices() async { final List list = await (_channel.invokeMethod('getBondedDevices')); return list.map((map) => BluetoothDevice.fromMap(map)).toList(); } ///isDeviceConnected(BluetoothDevice device) Future isDeviceConnected(BluetoothDevice device) => _channel.invokeMethod('isDeviceConnected', device.toMap()); ///connect(BluetoothDevice device) Future connect(BluetoothDevice device) => _channel.invokeMethod('connect', device.toMap()); ///disconnect() Future disconnect() => _channel.invokeMethod('disconnect'); ///write(String message) Future write(String message) => _channel.invokeMethod('write', {'message': message}); ///writeBytes(Uint8List message) Future writeBytes(Uint8List message) => _channel.invokeMethod('writeBytes', {'message': message}); ///printCustom(String message, int size, int align,{String? charset}) Future printCustom(String message, int size, int align, {String? charset}) => _channel.invokeMethod('printCustom', { 'message': message, 'size': size, 'align': align, 'charset': charset }); ///printNewLine() Future printNewLine() => _channel.invokeMethod('printNewLine'); ///paperCut() Future paperCut() => _channel.invokeMethod('paperCut'); ///drawerPin5() Future drawerPin2() => _channel.invokeMethod('drawerPin2'); ///drawerPin5() Future drawerPin5() => _channel.invokeMethod('drawerPin5'); ///printImage(String pathImage) Future printImage(String pathImage) => _channel.invokeMethod('printImage', {'pathImage': pathImage}); ///printImageBytes(Uint8List bytes) Future printImageBytes(Uint8List bytes) => _channel.invokeMethod('printImageBytes', {'bytes': bytes}); ///printQRcode(String textToQR, int width, int height, int align) Future printQRcode( String textToQR, int width, int height, int align) => _channel.invokeMethod('printQRcode', { 'textToQR': textToQR, 'width': width, 'height': height, 'align': align }); ///printLeftRight(String string1, String string2, int size,{String? charset, String? format}) Future printLeftRight(String string1, String string2, int size, {String? charset, String? format}) => _channel.invokeMethod('printLeftRight', { 'string1': string1, 'string2': string2, 'size': size, 'charset': charset, 'format': format }); ///print3Column(String string1, String string2, String string3, int size,{String? charset, String? format}) Future print3Column( String string1, String string2, String string3, int size, {String? charset, String? format}) => _channel.invokeMethod('print3Column', { 'string1': string1, 'string2': string2, 'string3': string3, 'size': size, 'charset': charset, 'format': format }); ///print4Column(String string1, String string2, String string3,String string4, int size,{String? charset, String? format}) Future print4Column(String string1, String string2, String string3, String string4, int size, {String? charset, String? format}) => _channel.invokeMethod('print4Column', { 'string1': string1, 'string2': string2, 'string3': string3, 'string4': string4, 'size': size, 'charset': charset, 'format': format }); } class BluetoothDevice { final String? name; final String? address; final int type = 0; bool connected = false; BluetoothDevice(this.name, this.address); BluetoothDevice.fromMap(Map map) : name = map['name'], address = map['address']; Map toMap() => { 'name': this.name, 'address': this.address, 'type': this.type, 'connected': this.connected, }; operator ==(Object other) { return other is BluetoothDevice && other.address == this.address; } @override int get hashCode => address.hashCode; } ================================================ FILE: local.properties ================================================ ## This file must *NOT* be checked into Version Control Systems, # as it contains information specific to your local configuration. # # Location of the SDK. This is only used by Gradle. # For customization when using a Version Control System, please read the # header note. #Fri Mar 19 16:23:49 ICT 2021 sdk.dir=E\:\\Users\\ZAKI\\AppData\\Local\\Android\\sdk ================================================ FILE: macos/Classes/BlueThermalPrinterPlugin.h ================================================ #import @interface BlueThermalPrinterPlugin : NSObject @end ================================================ FILE: macos/Classes/BlueThermalPrinterPlugin.m ================================================ #import "BlueThermalPrinterPlugin.h" static NSString *const CHANNEL_NAME = @"plugins.kzaki.com/blue_thermal_printer"; @implementation BlueThermalPrinterPlugin + (void)registerWithRegistrar:(NSObject*)registrar { FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:CHANNEL_NAME binaryMessenger:[registrar messenger]]; BlueThermalPrinterPlugin* instance = [[BlueThermalPrinterPlugin alloc] init]; [registrar addMethodCallDelegate:instance channel:channel]; } @end ================================================ FILE: macos/blue_thermal_printer.podspec ================================================ # # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. # Run `pod lib lint flutter_blue.podspec' to validate before publishing. # Pod::Spec.new do |s| s.name = 'blue_thermal_printer' s.version = '0.0.1' s.summary = 'A new Flutter plugin for connecting to thermal printer via bluetooth' s.description = <<-DESC A new Flutter plugin for connecting to thermal printer vie bluetooth DESC s.homepage = 'http://kakzaki.my.id' s.license = { :file => '../LICENSE' } s.author = { 'Zaki Mubarok' => 'kakzaki@gmail.com' } s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'FlutterMacOS' s.platform = :osx, '10.11' s.framework = 'CoreBluetooth' end ================================================ FILE: pubspec.yaml ================================================ name: blue_thermal_printer description: A Flutter plugin for connecting to thermal printer via bluetooth version: 1.2.3 homepage: https://kakzaki.dev repository: https://github.com/kakzaki/blue_thermal_printer issue_tracker: https://github.com/kakzaki/blue_thermal_printer/issues documentation: https://github.com/kakzaki/blue_thermal_printer/blob/master/README.md environment: sdk: '>=2.12.0 <3.0.0' flutter: ">=1.10.0" dependencies: flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter # For information on the generic Dart part of this file, see the # following page: https://www.dartlang.org/tools/pub/pubspec # The following section is specific to Flutter. flutter: # This section identifies this Flutter project as a plugin project. # The androidPackage and pluginClass identifiers should not ordinarily # be modified. They are used by the tooling to maintain consistency when # adding or updating assets for this project. plugin: platforms: android: package: id.kakzaki.blue_thermal_printer pluginClass: BlueThermalPrinterPlugin ios: pluginClass: BlueThermalPrinterPlugin macos: pluginClass: BlueThermalPrinterPlugin # To add assets to your plugin package, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg # # For details regarding assets in packages, see # https://flutter.dev/assets-and-images/#from-packages # # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. # To add custom fonts to your plugin package, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts in packages, see # https://flutter.dev/custom-fonts/#from-packages ================================================ FILE: test/blue_thermal_printer_test.dart ================================================ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { const MethodChannel channel = MethodChannel('blue_thermal_printer'); setUp(() { channel.setMockMethodCallHandler((MethodCall methodCall) async { return '42'; }); }); tearDown(() { channel.setMockMethodCallHandler(null); }); test('getPlatformVersion', () async { //expect(await BlueThermalPrinter.platformVersion, '42'); }); }