Flutter

Print from a Flutter app with url_launcher and share_plus.

Launch a rollcast://print link with url_launcher. Share PDFs and images with share_plus.

YAML
# pubspec.yaml
dependencies:
  url_launcher: ^6.3.0
  share_plus: ^11.0.0

Android 11+ visibility

canLaunchUrl only sees RollCast if your app declares the scheme. Add this to android/app/src/main/AndroidManifest.xml, inside <manifest>:

XML
<queries>
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="rollcast" />
    </intent>
</queries>

Print text

Dart
import 'dart:convert';
import 'dart:typed_data';
import 'package:url_launcher/url_launcher.dart';

const rollcastStore = 'market://details?id=com.rollcast.app';

Future<void> _send(String type, List<int> bytes, {String? printerId}) async {
  final data = base64Url.encode(bytes);
  var link = 'rollcast://print?type=$type&data=$data';
  if (printerId != null) {
    link += '&printer=${Uri.encodeQueryComponent(printerId)}';
  }
  final uri = Uri.parse(link);
  if (await canLaunchUrl(uri)) {
    await launchUrl(uri, mode: LaunchMode.externalApplication);
  } else {
    await launchUrl(Uri.parse(rollcastStore), mode: LaunchMode.externalApplication);
  }
}

Future<void> printText(String text, {String? printerId}) =>
    _send('text', utf8.encode(text), printerId: printerId);

Future<void> printRaw(Uint8List bytes, {String? printerId}) =>
    _send('raw', bytes, printerId: printerId);

Tip

base64Url output may end with '=' padding. RollCast accepts it with or without padding.

Raw ESC/POS bytes

Dart
Future<void> printReceipt() {
  final bytes = Uint8List.fromList([
    0x1B, 0x40,             // ESC @    reset
    0x1B, 0x45, 0x01,       // ESC E 1  bold on
    ...ascii.encode('MY SHOP\n'),
    0x1B, 0x45, 0x00,       // ESC E 0  bold off
    ...ascii.encode('TOTAL           40.00\n'),
    0x1B, 0x64, 0x03,       // ESC d 3  feed 3 lines
    0x1D, 0x56, 0x01,       // GS V 1   cut
  ]);
  return printRaw(bytes);
}

Share a PDF

Dart
import 'package:share_plus/share_plus.dart';

Future<void> sharePdf(String path) async {
  await SharePlus.instance.share(
    ShareParams(files: [XFile(path, mimeType: 'application/pdf')]),
  );
  // share_plus < 11: await Share.shareXFiles([XFile(path, mimeType: 'application/pdf')]);
}

The user picks RollCast in the share sheet. The file prints on the default printer.