Mini E-Paper | Ep1. Uploading Emoji to E-Paper from Flutter App(iOS & Android)

This commit is contained in:
Eric
2021-09-12 22:11:12 -07:00
parent 6ca8c510be
commit ce83662ede
23 changed files with 3207 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release

View File

@@ -0,0 +1,10 @@
# 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: 4cc385b4b84ac2f816d939a49ea1f328c4e0b48e
channel: stable
project_type: app

View File

@@ -0,0 +1,5 @@
# Mini E-Paper | Ep1. Uploading Emoji to E-Paper from Flutter App(iOS & Android)
https://youtu.be/-RhEiKldfDc
# My Channel
www.that-project.com

View File

@@ -0,0 +1,29 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,6 @@
import 'package:flutter/material.dart';
// Colors
const kMainBG = Color(0xff191720);
const kTextFieldFill = Color(0xff1E1C24);
const kCardBG = Color(0xffffffff);

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
const kHeadline = TextStyle(
color: Colors.white,
fontSize: 34,
fontWeight: FontWeight.bold,
);
const kBodyText = TextStyle(
color: Colors.grey,
fontSize: 15,
);
const kButtonText = TextStyle(
color: Colors.black87,
fontSize: 16,
fontWeight: FontWeight.bold,
);
const kBodyText2 =
TextStyle(fontSize: 28, fontWeight: FontWeight.w500, color: Colors.white);
const kSubtitleText = TextStyle(
color: Colors.grey,
fontSize: 12,
);

View File

@@ -0,0 +1,848 @@
const emojiArray = [
"😄",
"😆",
"😊",
"😃",
"😏",
"😍",
"😘",
"😚",
"😳",
"😌",
"😆",
"😁",
"😉",
"😜",
"😝",
"😀",
"😗",
"😙",
"😛",
"😴",
"😟",
"😦",
"😧",
"😮",
"😬",
"😕",
"😯",
"😑",
"😒",
"😅",
"😓",
"😥",
"😩",
"😔",
"😞",
"😖",
"😨",
"😰",
"😣",
"😢",
"😭",
"😂",
"😲",
"😱",
"😫",
"😠",
"😡",
"😤",
"😪",
"😋",
"😷",
"😎",
"😵",
"👿",
"😈",
"😐",
"😶",
"😇",
"👽",
"💛",
"💙",
"💜",
"💚",
"💔",
"💓",
"💗",
"💕",
"💞",
"💘",
"💖",
"",
"",
"🌟",
"💫",
"💥",
"💢",
"",
"",
"",
"",
"💤",
"💨",
"💦",
"🎶",
"🎵",
"🔥",
"💩",
"👍",
"👎",
"👌",
"👊",
"",
"✌️",
"👋",
"",
"👐",
"☝️",
"👇",
"👈",
"👉",
"🙌",
"🙏",
"👆",
"👏",
"💪",
"🤘",
"🖕",
"🚶",
"🏃",
"👫",
"👪",
"👬",
"👭",
"💃",
"👯",
"🙆",
"🙅",
"💁",
"🙋",
"👰",
"🙇",
"💏",
"💑",
"💆",
"💇",
"💅",
"👦",
"👧",
"👩",
"👨",
"👶",
"👵",
"👴",
"👲",
"👳",
"👷",
"👮",
"👼",
"👸",
"😺",
"😸",
"😻",
"😽",
"😼",
"🙀",
"😿",
"😹",
"😾",
"👹",
"👺",
"🙈",
"🙉",
"🙊",
"💂",
"💀",
"🐾",
"👄",
"💋",
"💧",
"👂",
"👀",
"👃",
"👅",
"💌",
"👤",
"👥",
"💬",
"💭",
"☀️",
"☁️",
"❄️",
"",
"",
"🌀",
"🌁",
"🌊",
"🐱",
"🐶",
"🐭",
"🐹",
"🐰",
"🐺",
"🐸",
"🐯",
"🐨",
"🐻",
"🐷",
"🐽",
"🐮",
"🐗",
"🐵",
"🐒",
"🐴",
"🐎",
"🐫",
"🐑",
"🐘",
"🐼",
"🐍",
"🐦",
"🐤",
"🐥",
"🐣",
"🐔",
"🐧",
"🐢",
"🐛",
"🐝",
"🐜",
"🐞",
"🐌",
"🐙",
"🐠",
"🐟",
"🐳",
"🐋",
"🐬",
"🐄",
"🐏",
"🐀",
"🐃",
"🐅",
"🐇",
"🐉",
"🐐",
"🐓",
"🐕",
"🐖",
"🐁",
"🐂",
"🐲",
"🐡",
"🐊",
"🐪",
"🐆",
"🐈",
"🐩",
"🐾",
"💐",
"🌸",
"🌷",
"🍀",
"🌹",
"🌻",
"🌺",
"🍁",
"🍃",
"🍂",
"🌿",
"🍄",
"🌵",
"🌴",
"🌲",
"🌳",
"🌰",
"🌱",
"🌼",
"🌾",
"🐚",
"🌐",
"🌞",
"🌝",
"🌚",
"🌑",
"🌒",
"🌓",
"🌔",
"🌕",
"🌖",
"🌗",
"🌘",
"🌜",
"🌛",
"🌔",
"🌍",
"🌎",
"🌏",
"🌋",
"🌌",
"",
"🎍",
"💝",
"🎎",
"🎒",
"🎓",
"🎏",
"🎆",
"🎇",
"🎐",
"🎑",
"🎃",
"👻",
"🎅",
"🎄",
"🎁",
"🔔",
"🔕",
"🎋",
"🎉",
"🎊",
"🎈",
"🔮",
"💿",
"📀",
"💾",
"📷",
"📹",
"🎥",
"💻",
"📺",
"📱",
"☎️",
"☎️",
"📞",
"📟",
"📠",
"💽",
"📼",
"🔉",
"🔈",
"🔇",
"📢",
"📣",
"",
"",
"",
"",
"📻",
"📡",
"",
"🔍",
"🔎",
"🔓",
"🔒",
"🔏",
"🔐",
"🔑",
"💡",
"🔦",
"🔆",
"🔅",
"🔌",
"🔋",
"📲",
"✉️",
"📫",
"📮",
"🛀",
"🛁",
"🚿",
"🚽",
"🔧",
"🔩",
"🔨",
"💺",
"💰",
"💴",
"💵",
"💷",
"💶",
"💳",
"💸",
"📧",
"📥",
"📤",
"✉️",
"📨",
"📯",
"📪",
"📬",
"📭",
"📦",
"🚪",
"🚬",
"💣",
"🔫",
"🔪",
"💊",
"💉",
"📄",
"📃",
"📑",
"📊",
"📈",
"📉",
"📜",
"📋",
"📆",
"📅",
"📇",
"📁",
"📂",
"✂️",
"📌",
"📎",
"✒️",
"✏️",
"📏",
"📐",
"📕",
"📗",
"📘",
"📙",
"📓",
"📔",
"📒",
"📚",
"🔖",
"📛",
"🔬",
"🔭",
"📰",
"🏈",
"🏀",
"",
"",
"🎾",
"🎱",
"🏉",
"🎳",
"",
"🚵",
"🚴",
"🏇",
"🏂",
"🏊",
"🏄",
"🎿",
"♠️",
"♥️",
"♣️",
"♦️",
"💎",
"💍",
"🏆",
"🎼",
"🎹",
"🎻",
"👾",
"🎮",
"🃏",
"🎴",
"🎲",
"🎯",
"🀄",
"🎬",
"📝",
"📝",
"📖",
"🎨",
"🎤",
"🎧",
"🎺",
"🎷",
"🎸",
"👞",
"👡",
"👠",
"💄",
"👢",
"👕",
"👕",
"👔",
"👚",
"👗",
"🎽",
"👖",
"👘",
"👙",
"🎀",
"🎩",
"👑",
"👒",
"👞",
"🌂",
"💼",
"👜",
"👝",
"👛",
"👓",
"🎣",
"",
"🍵",
"🍶",
"🍼",
"🍺",
"🍻",
"🍸",
"🍹",
"🍷",
"🍴",
"🍕",
"🍔",
"🍟",
"🍗",
"🍖",
"🍝",
"🍛",
"🍤",
"🍱",
"🍣",
"🍥",
"🍙",
"🍘",
"🍚",
"🍜",
"🍲",
"🍢",
"🍡",
"🥚",
"🍞",
"🍩",
"🍮",
"🍦",
"🍨",
"🍧",
"🎂",
"🍰",
"🍪",
"🍫",
"🍬",
"🍭",
"🍯",
"🍎",
"🍏",
"🍊",
"🍋",
"🍒",
"🍇",
"🍉",
"🍓",
"🍑",
"🍈",
"🍌",
"🍐",
"🍍",
"🍠",
"🍆",
"🍅",
"🌽",
"🏠",
"🏡",
"🏫",
"🏢",
"🏣",
"🏥",
"🏦",
"🏪",
"🏩",
"🏨",
"💒",
"",
"🏬",
"🏤",
"🌇",
"🌆",
"🏯",
"🏰",
"",
"🏭",
"🗼",
"🗾",
"🗻",
"🌄",
"🌅",
"🌠",
"🗽",
"🌉",
"🎠",
"🌈",
"🎡",
"",
"🎢",
"🚢",
"🚤",
"",
"",
"🚣",
"",
"🚀",
"✈️",
"🚁",
"🚂",
"🚊",
"🚞",
"🚲",
"🚡",
"🚟",
"🚠",
"🚜",
"🚙",
"🚘",
"🚗",
"🚗",
"🚕",
"🚖",
"🚛",
"🚌",
"🚍",
"🚨",
"🚓",
"🚔",
"🚒",
"🚑",
"🚐",
"🚚",
"🚋",
"🚉",
"🚆",
"🚅",
"🚄",
"🚈",
"🚝",
"🚃",
"🚎",
"🎫",
"",
"🚦",
"🚥",
"⚠️",
"🚧",
"🔰",
"🏧",
"🎰",
"🚏",
"💈",
"♨️",
"🏁",
"🎌",
"🏮",
"🗿",
"🎪",
"🎭",
"📍",
"🚩",
"🇯🇵",
"🇰🇷",
"🇨🇳",
"🇺🇸",
"🇫🇷",
"🇪🇸",
"🇮🇹",
"🇷🇺",
"🇬🇧",
"🇩🇪",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"🔟",
"🔢",
"0",
"#️⃣",
"🔣",
"◀️",
"⬇️",
"▶️",
"⬅️",
"🔠",
"🔡",
"🔤",
"↙️",
"↘️",
"➡️",
"⬆️",
"↖️",
"↗️",
"",
"",
"🔽",
"⤵️",
"⤴️",
"↩️",
"↪️",
"↔️",
"↕️",
"🔼",
"🔃",
"🔄",
"",
"",
"",
"🆗",
"🔀",
"🔁",
"🔂",
"🆕",
"🔝",
"🆙",
"🆒",
"🆓",
"🆖",
"🎦",
"🈁",
"📶",
"🈹",
"🈴",
"🈺",
"🈯",
"🈷️",
"🈶",
"🈵",
"🈚",
"🈸",
"🈳",
"🈲",
"🈂️",
"🚻",
"🚹",
"🚺",
"🚼",
"🚭",
"🅿️",
"",
"🚇",
"🛄",
"🉑",
"🚾",
"🚰",
"🚮",
"㊙️",
"㊗️",
"Ⓜ️",
"🛂",
"🛅",
"🛃",
"🉐",
"🆑",
"🆘",
"🆔",
"🚫",
"🔞",
"📵",
"🚯",
"🚱",
"🚳",
"🚷",
"🚸",
"",
"✳️",
"❇️",
"✴️",
"💟",
"🆚",
"📳",
"📴",
"💹",
"💱",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"🔯",
"",
"🅰️",
"🅱️",
"🆎",
"🅾️",
"💠",
"♻️",
"🔚",
"🔙",
"🔛",
"🔜",
"🕐",
"🕜",
"🕙",
"🕥",
"🕚",
"🕦",
"🕛",
"🕧",
"🕑",
"🕝",
"🕒",
"🕞",
"🕓",
"🕟",
"🕔",
"🕠",
"🕕",
"🕡",
"🕖",
"🕢",
"🕗",
"🕣",
"🕘",
"🕤",
"💲",
"©️",
"®️",
"™️",
"",
"",
"‼️",
"⁉️",
"",
"✖️",
"",
"",
"",
"💮",
"💯",
"✔️",
"☑️",
"🔘",
"🔗",
"",
"〰️",
"〽️",
"🔱",
"▪️",
"▫️",
"",
"",
"◼️",
"◻️",
"",
"",
"",
"🔲",
"🔳",
"",
"",
"🔴",
"🔵",
"🔷",
"🔶",
"🔹",
"🔸",
"🔺",
"🔻"
];

View File

@@ -0,0 +1,36 @@
/////////////////////////////////////////////////////////////////
/*
Mini E-Paper | Ep1. Uploading Emoji to E-Paper from Flutter App(iOS & Android)
Video Tutorial: https://youtu.be/-RhEiKldfDc
Created by Eric N. (ThatProject)
*/
/////////////////////////////////////////////////////////////////
import 'package:epaper_emoji_ble/route/router.dart' as router;
import 'package:epaper_emoji_ble/route/routing_constants.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'const/custom_colors.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Emoji -> E-Paper App',
theme: ThemeData(
textTheme: GoogleFonts.poppinsTextTheme(Theme.of(context).textTheme),
scaffoldBackgroundColor: kMainBG,
primarySwatch: Colors.amber,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
onGenerateRoute: router.generateRoute,
initialRoute: SplashScreenRoute,
);
}
}

View File

@@ -0,0 +1,35 @@
import 'dart:typed_data';
import 'package:epaper_emoji_ble/route/routing_constants.dart';
import 'package:epaper_emoji_ble/screens/ble_list_screen.dart';
import 'package:epaper_emoji_ble/screens/emji_converter_screen.dart';
import 'package:epaper_emoji_ble/screens/emoji_screen.dart';
import 'package:epaper_emoji_ble/screens/splash_screen.dart';
import 'package:epaper_emoji_ble/screens/undefined_screen.dart';
import 'package:flutter/material.dart';
Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case SplashScreenRoute:
return MaterialPageRoute(builder: (context) => const SplashScreen());
case EmojiScreenRoute:
return MaterialPageRoute(builder: (context) => const EmojiScreen());
case EmojiConverterScreenRoute:
return MaterialPageRoute(
builder: (context) => EmojiConverterScreen(
selectedEmoji: settings.arguments as String));
case BLEScreenRoute:
return MaterialPageRoute(
builder: (context) =>
BleListScreen(headedBitmap: settings.arguments as Uint8List));
default:
return MaterialPageRoute(
builder: (context) => UndefinedView(
name: settings.name!,
));
}
}

View File

@@ -0,0 +1,4 @@
const String SplashScreenRoute = '/';
const String EmojiScreenRoute = '/Emoji';
const String EmojiConverterScreenRoute = '/EmojiConverter';
const String BLEScreenRoute = '/BLEList';

View File

@@ -0,0 +1,235 @@
import 'dart:typed_data';
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:epaper_emoji_ble/const/custom_styles.dart';
import 'package:epaper_emoji_ble/widgets/ble_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:quiver/iterables.dart';
import 'package:sn_progress_dialog/progress_dialog.dart';
import 'package:wakelock/wakelock.dart';
class BleListScreen extends StatelessWidget {
final Uint8List headedBitmap;
const BleListScreen({Key? key, required this.headedBitmap}) : super(key: key);
@override
Widget build(BuildContext context) {
return StreamBuilder<BluetoothState>(
stream: FlutterBlue.instance.state,
initialData: BluetoothState.unknown,
builder: (c, snapshot) {
final state = snapshot.data;
if (state == BluetoothState.on) {
return FindDevicesScreen(
headedBitmap: headedBitmap,
);
}
return BluetoothOffScreen(state: state);
});
}
}
class BluetoothOffScreen extends StatelessWidget {
const BluetoothOffScreen({Key? key, this.state}) : super(key: key);
final BluetoothState? state;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.lightBlue,
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Icon(
Icons.bluetooth_disabled,
size: 200.0,
color: Colors.white54,
),
Text(
'Bluetooth Adapter is ${state != null ? state.toString().substring(15) : 'not available'}.',
style: Theme.of(context)
.primaryTextTheme
.headline1
?.copyWith(color: Colors.white),
),
],
),
),
);
}
}
class FindDevicesScreen extends StatelessWidget {
final Uint8List headedBitmap;
const FindDevicesScreen({Key? key, required this.headedBitmap})
: super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Find Devices'),
),
body: RefreshIndicator(
onRefresh: () =>
FlutterBlue.instance.startScan(timeout: const Duration(seconds: 4)),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
StreamBuilder<List<BluetoothDevice>>(
stream: Stream.periodic(const Duration(seconds: 2))
.asyncMap((_) => FlutterBlue.instance.connectedDevices),
initialData: [],
builder: (c, snapshot) => Column(
children: snapshot.data!
.map((d) => ListTile(
title: Text(
d.name,
style: kButtonText.copyWith(color: Colors.white),
),
subtitle: Text(
d.id.toString(),
style:
kSubtitleText.copyWith(color: Colors.white),
),
trailing: StreamBuilder<BluetoothDeviceState>(
stream: d.state,
initialData: BluetoothDeviceState.disconnected,
builder: (c, snapshot) {
if (snapshot.data ==
BluetoothDeviceState.connected) {
return TextButton(
child: Text(
'Send',
style: kButtonText.copyWith(
color: Colors.white),
),
onPressed: () {
_findTargetUUID(context, d);
});
}
return Text(snapshot.data.toString());
},
),
))
.toList(),
),
),
StreamBuilder<List<ScanResult>>(
stream: FlutterBlue.instance.scanResults,
initialData: [],
builder: (c, snapshot) => Column(
children: snapshot.data!
.map(
(r) => ScanResultTile(
result: r,
onTap: () {
r.device.connect();
},
),
)
.toList(),
),
),
],
),
),
),
floatingActionButton: StreamBuilder<bool>(
stream: FlutterBlue.instance.isScanning,
initialData: false,
builder: (c, snapshot) {
if (snapshot.data!) {
return FloatingActionButton(
child: const Icon(Icons.stop),
onPressed: () => FlutterBlue.instance.stopScan(),
backgroundColor: Colors.red,
);
} else {
return FloatingActionButton(
child: const Icon(Icons.search),
onPressed: () => FlutterBlue.instance
.startScan(timeout: const Duration(seconds: 4)));
}
},
),
);
}
final String SERVICE_UUID = "713d0001-503e-4c75-ba94-3148f18d941e";
final String CHARACTERISTIC_UUID = "713d0002-503e-4c75-ba94-3148f18d941e";
_findTargetUUID(BuildContext context, BluetoothDevice device) async {
print("device :${device.id}");
try {
List<BluetoothService> services = await device.discoverServices();
for (var service in services) {
print('service!!! : ${service}');
print('service last uuid!!! : ${service.uuid.toString()}');
if (service.uuid.toString() == SERVICE_UUID) {
for (var characteristic in service.characteristics) {
if (characteristic.uuid.toString() == CHARACTERISTIC_UUID) {
print(
'characteristic uuid!!! : ${characteristic.uuid.toString()}');
_sendData(context, characteristic);
// for (var pair in pairs) {
// print(pair);
// await characteristic.write(pair, withoutResponse: false);
//
// print('SENT!');
// }
}
}
}
}
} catch (e) {
await showOkAlertDialog(
context: context,
title: 'Error',
message: e.toString(),
);
}
}
_sendData(
BuildContext context, BluetoothCharacteristic characteristic) async {
Wakelock.enable();
print('headedBitmap length: ${headedBitmap.length}');
var pairs = partition(headedBitmap, 20);
var startSignal = await characteristic.write([], withoutResponse: false);
print('startSignal: $startSignal');
ProgressDialog pd = ProgressDialog(context: context);
pd.show(
max: pairs.length,
msg: 'Preparing Upload...',
progressType: ProgressType.valuable,
backgroundColor: const Color(0xff212121),
progressValueColor: Colors.amberAccent,
progressBgColor: Colors.white70,
msgColor: Colors.white,
valueColor: Colors.white);
int i = 0;
for (var pair in pairs) {
++i;
print(pair);
pd.update(value: i, msg: 'Bitmap Uploading...');
await characteristic.write(pair, withoutResponse: false);
}
var endSignal = await characteristic.write([], withoutResponse: false);
print('endSignal: $endSignal');
Wakelock.disable();
}
}

View File

@@ -0,0 +1,166 @@
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:bitmap/bitmap.dart';
import 'package:epaper_emoji_ble/const/custom_styles.dart';
import 'package:epaper_emoji_ble/route/routing_constants.dart';
import 'package:epaper_emoji_ble/util/bitmap24.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:image/image.dart' as img;
class EmojiConverterScreen extends StatefulWidget {
final String selectedEmoji;
const EmojiConverterScreen({Key? key, required this.selectedEmoji})
: super(key: key);
@override
_EmojiConverterScreenState createState() => _EmojiConverterScreenState();
}
class _EmojiConverterScreenState extends State<EmojiConverterScreen> {
GlobalKey globalKey = GlobalKey();
Uint8List? bitmap24WithHeader;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Emoji Converter'),
),
body: ListView(children: [
Center(
child: Column(
children: [
const SizedBox(
height: 40,
),
RepaintBoundary(
key: globalKey,
child: Container(
color: Colors.transparent,
width: 200,
height: 200,
child: Center(
child: Text(
widget.selectedEmoji,
style: const TextStyle(fontSize: 160),
)),
),
),
const SizedBox(
height: 40,
),
bitmap24WithHeader == null
? Container(
height: 60,
width: MediaQuery.of(context).size.width * 0.8,
decoration: BoxDecoration(
color: Colors.grey[850],
borderRadius: BorderRadius.circular(18),
),
child: TextButton(
style: ButtonStyle(
overlayColor: MaterialStateProperty.resolveWith(
(states) => Colors.black12,
),
),
onPressed: _convertImage,
child: Text(
'Convert to Bitmap',
style: kButtonText.copyWith(color: Colors.white),
),
))
: Container(
height: 100,
width: 100,
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(18),
),
child: Image.memory(
bitmap24WithHeader!,
)),
const SizedBox(
height: 40,
),
bitmap24WithHeader != null
? Container(
height: 60,
width: MediaQuery.of(context).size.width * 0.8,
decoration: BoxDecoration(
color: Colors.grey[850],
borderRadius: BorderRadius.circular(18),
),
child: TextButton(
style: ButtonStyle(
overlayColor: MaterialStateProperty.resolveWith(
(states) => Colors.black12,
),
),
onPressed: _findBLEDevice,
child: Text(
'Find & Select Your Mini E-Paper',
style: kButtonText.copyWith(color: Colors.white),
),
))
: Container()
],
),
),
]),
);
}
_convertImage() async {
final RenderRepaintBoundary boundary =
globalKey.currentContext!.findRenderObject()! as RenderRepaintBoundary;
final ui.Image image = await boundary.toImage();
final ByteData? byteData =
await image.toByteData(format: ui.ImageByteFormat.png);
final Uint8List pngBytes = byteData!.buffer.asUint8List();
var pngImage;
try {
pngImage = img.decodePng(pngBytes);
} catch (e) {
await showOkAlertDialog(
context: context,
title: 'Error',
message: e.toString(),
);
return;
}
var resizedImage = img.copyResize(pngImage, width: 80, height: 80);
var grayImage = img.grayscale(resizedImage);
var imgThreeColor = img.quantize(grayImage, numberOfColors: 3);
var flipImage = img.flip(imgThreeColor, img.Flip.vertical);
Bitmap bitmap = Bitmap.fromHeadless(
resizedImage.width, resizedImage.height, flipImage.getBytes());
Uint8List bitmap24Data = Bitmap24.fromBitMap32(
resizedImage.width, resizedImage.height, bitmap.content);
Bitmap24 bitmap24 = Bitmap24.fromHeadless(
resizedImage.width, resizedImage.height, bitmap24Data);
setState(() {
bitmap24WithHeader = bitmap24.buildHeaded();
});
}
_findBLEDevice() async {
if (bitmap24WithHeader == null) {
await showOkAlertDialog(
context: context,
title: 'Error',
message: 'Check the Bitmap Emoji',
);
return;
}
Navigator.pushNamed(context, BLEScreenRoute, arguments: bitmap24WithHeader);
}
}

View File

@@ -0,0 +1,51 @@
import 'package:epaper_emoji_ble/const/emoji_data.dart';
import 'package:epaper_emoji_ble/route/routing_constants.dart';
import 'package:flutter/material.dart';
class EmojiScreen extends StatelessWidget {
const EmojiScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.only(top: 40, bottom: 10),
child: Center(child: emojiGridView(context)),
),
);
}
Widget emojiGridView(BuildContext context) {
return MediaQuery.removePadding(
context: context,
removeTop: true,
child: GridView.builder(
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.all(8),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: MediaQuery.of(context).size.width >
MediaQuery.of(context).size.height
? 10
: 5,
),
itemCount: emojiArray.length,
itemBuilder: (BuildContext context, int index) {
return Card(
color: Colors.amber,
child: InkWell(
onTap: () {
Navigator.pushNamed(context, EmojiConverterScreenRoute,
arguments: emojiArray[index]);
},
child: Center(
child: Text(
emojiArray[index],
style: const TextStyle(fontSize: 30),
),
),
),
);
}),
);
}
}

View File

@@ -0,0 +1,87 @@
import 'package:epaper_emoji_ble/const/custom_styles.dart';
import 'package:epaper_emoji_ble/route/routing_constants.dart';
import 'package:flutter/material.dart';
class SplashScreen extends StatelessWidget {
const SplashScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: [
_getScreen(context),
],
),
);
}
_getScreen(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 20, right: 20, top: 40, bottom: 10),
child: Column(
children: [
Column(
children: [
Center(
child: Container(
child: const Image(
image: AssetImage(
'assets/images/iot_image.png',
),
height: 200,
color: Colors.white,
),
),
),
const SizedBox(
height: 20,
),
const Text(
"E-Paper\n^\n|\nBLE\n|\nEmoji😃",
style: kHeadline,
textAlign: TextAlign.center,
),
const SizedBox(
height: 20,
),
SizedBox(
width: MediaQuery.of(context).size.width * 0.8,
child: const Text(
"It's a project that allows you to send emojis to Mini E-Paper. For detail, check out my channel. www.that-project.com",
style: kBodyText,
textAlign: TextAlign.center,
),
)
],
),
const SizedBox(
height: 50,
),
Container(
height: 60,
width: MediaQuery.of(context).size.width * 0.8,
decoration: BoxDecoration(
color: Colors.grey[850],
borderRadius: BorderRadius.circular(18),
),
child: TextButton(
style: ButtonStyle(
overlayColor: MaterialStateProperty.resolveWith(
(states) => Colors.black12,
),
),
onPressed: () {
Navigator.pushNamedAndRemoveUntil(context, EmojiScreenRoute,
(Route<dynamic> route) => false);
},
child: Text(
'GET STARTED',
style: kButtonText.copyWith(color: Colors.white),
),
))
],
),
);
}
}

View File

@@ -0,0 +1,16 @@
import 'package:flutter/material.dart';
class UndefinedView extends StatelessWidget {
final String name;
const UndefinedView({Key? key, required this.name}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Route for $name is not defined'),
),
);
}
}

View File

@@ -0,0 +1,88 @@
import 'dart:typed_data';
class Bitmap24 {
/// The width in pixels of the image.
final int width;
/// The width in pixels of the image.
final int height;
/// A [Uint8List] of bytes in a RGB format.
final Uint8List content;
int get size => (width * height) * RGB24BitmapHeader.pixelLength;
Bitmap24.fromHeadless(this.width, this.height, this.content);
Bitmap24.fromHeadful(this.width, this.height, Uint8List headedIntList)
: content = headedIntList.sublist(
RGB24BitmapHeader.RGB24HeaderSize,
headedIntList.length,
);
Bitmap24.blank(
this.width,
this.height,
) : content = Uint8List.fromList(
List.filled(width * height * RGB24BitmapHeader.pixelLength, 0),
);
Uint8List buildHeaded() {
final header = RGB24BitmapHeader(size, width, height)
..applyContent(content);
return header.headerIntList;
}
static Uint8List fromBitMap32(int width, int height, Uint8List bitmap32) {
Uint8List R8G8B8 = Uint8List(width * height * 3);
int j = 0;
for (int i = 0; i < (bitmap32.length - 3); i = i + 4) {
var Red = bitmap32[i + 2];
var Green = bitmap32[i + 1];
var Blue = bitmap32[i];
R8G8B8[j] = Red;
R8G8B8[j + 1] = Green;
R8G8B8[j + 2] = Blue;
j = j + 3;
}
return R8G8B8;
}
}
class RGB24BitmapHeader {
static const int pixelLength = 3;
static const int RGB24HeaderSize = 54;
RGB24BitmapHeader(this.contentSize, int width, int height) {
headerIntList = Uint8List(fileLength);
final ByteData bd = headerIntList.buffer.asByteData();
bd.setUint8(0x0, 0x42);
bd.setUint8(0x1, 0x4d);
bd.setInt32(0x2, fileLength, Endian.little);
bd.setInt32(0xa, RGB24HeaderSize, Endian.little);
bd.setUint32(0xe, 28, Endian.little);
bd.setUint32(0x12, width, Endian.little);
bd.setUint32(0x16, height, Endian.little);
bd.setUint16(0x1a, 1, Endian.little);
bd.setUint32(0x1c, 24, Endian.little); // pixel size
bd.setUint32(0x1e, 0, Endian.little); //BI_BITFIELDS
bd.setUint32(0x22, contentSize, Endian.little);
}
int contentSize;
void applyContent(Uint8List contentIntList) {
headerIntList.setRange(
RGB24HeaderSize,
fileLength,
contentIntList,
);
}
late Uint8List headerIntList;
int get fileLength => contentSize + RGB24HeaderSize;
}

View File

@@ -0,0 +1,314 @@
// Copyright 2017, Paul DeMarco.
// All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:epaper_emoji_ble/const/custom_styles.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
class ScanResultTile extends StatelessWidget {
const ScanResultTile({Key? key, required this.result, this.onTap})
: super(key: key);
final ScanResult result;
final VoidCallback? onTap;
Widget _buildTitle(BuildContext context) {
if (result.device.name.isNotEmpty) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
result.device.name,
overflow: TextOverflow.ellipsis,
style: kButtonText.copyWith(color: Colors.white),
),
Text(
result.device.id.toString(),
style: kSubtitleText.copyWith(color: Colors.white),
)
],
);
} else {
return Text(result.device.id.toString(),
style: kSubtitleText.copyWith(color: Colors.white));
}
}
Widget _buildAdvRow(BuildContext context, String title, String value) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 4.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
title,
style: kSubtitleText.copyWith(color: Colors.white),
),
const SizedBox(
width: 12.0,
),
Expanded(
child: Text(
value,
style: kSubtitleText.copyWith(color: Colors.white),
softWrap: true,
),
),
],
),
);
}
String getNiceHexArray(List<int> bytes) {
return '[${bytes.map((i) => i.toRadixString(16).padLeft(2, '0')).join(', ')}]'
.toUpperCase();
}
String getNiceManufacturerData(Map<int, List<int>> data) {
if (data.isEmpty) {
return 'N/A';
}
List<String> res = [];
data.forEach((id, bytes) {
res.add(
'${id.toRadixString(16).toUpperCase()}: ${getNiceHexArray(bytes)}');
});
return res.join(', ');
}
String getNiceServiceData(Map<String, List<int>> data) {
if (data.isEmpty) {
return 'N/A';
}
List<String> res = [];
data.forEach((id, bytes) {
res.add('${id.toUpperCase()}: ${getNiceHexArray(bytes)}');
});
return res.join(', ');
}
@override
Widget build(BuildContext context) {
return ExpansionTile(
title: _buildTitle(context),
leading: Text(
result.rssi.toString(),
style: kButtonText.copyWith(color: Colors.white),
),
trailing: TextButton(
style: ButtonStyle(
overlayColor: MaterialStateProperty.resolveWith(
(states) => Colors.black12,
),
),
child: Text(
'CONNECT',
style: kButtonText.copyWith(color: Colors.white),
),
onPressed: (result.advertisementData.connectable) ? onTap : null,
),
children: <Widget>[
_buildAdvRow(
context, 'Complete Local Name', result.advertisementData.localName),
_buildAdvRow(context, 'Tx Power Level',
'${result.advertisementData.txPowerLevel ?? 'N/A'}'),
_buildAdvRow(context, 'Manufacturer Data',
getNiceManufacturerData(result.advertisementData.manufacturerData)),
_buildAdvRow(
context,
'Service UUIDs',
(result.advertisementData.serviceUuids.isNotEmpty)
? result.advertisementData.serviceUuids.join(', ').toUpperCase()
: 'N/A'),
_buildAdvRow(context, 'Service Data',
getNiceServiceData(result.advertisementData.serviceData)),
],
);
}
}
class ServiceTile extends StatelessWidget {
final BluetoothService service;
final List<CharacteristicTile> characteristicTiles;
const ServiceTile(
{Key? key, required this.service, required this.characteristicTiles})
: super(key: key);
@override
Widget build(BuildContext context) {
if (characteristicTiles.isNotEmpty) {
return ExpansionTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text('Service'),
Text(
'0x${service.uuid.toString().toUpperCase().substring(4, 8)}',
style: kSubtitleText.copyWith(color: Colors.white),
)
],
),
children: characteristicTiles,
);
} else {
return ListTile(
title: const Text('Service'),
subtitle:
Text('0x${service.uuid.toString().toUpperCase().substring(4, 8)}'),
);
}
}
}
class CharacteristicTile extends StatelessWidget {
final BluetoothCharacteristic characteristic;
final List<DescriptorTile> descriptorTiles;
final VoidCallback? onReadPressed;
final VoidCallback? onWritePressed;
final VoidCallback? onNotificationPressed;
const CharacteristicTile(
{Key? key,
required this.characteristic,
required this.descriptorTiles,
this.onReadPressed,
this.onWritePressed,
this.onNotificationPressed})
: super(key: key);
@override
Widget build(BuildContext context) {
return StreamBuilder<List<int>>(
stream: characteristic.value,
initialData: characteristic.lastValue,
builder: (c, snapshot) {
final value = snapshot.data;
return ExpansionTile(
title: ListTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text('Characteristic'),
Text(
'0x${characteristic.uuid.toString().toUpperCase().substring(4, 8)}',
style: Theme.of(context).textTheme.bodyText1?.copyWith(
color: Theme.of(context).textTheme.caption?.color))
],
),
subtitle: Text(value.toString()),
contentPadding: const EdgeInsets.all(0.0),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: Icon(
Icons.file_download,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5),
),
onPressed: onReadPressed,
),
IconButton(
icon: Icon(Icons.file_upload,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5)),
onPressed: onWritePressed,
),
IconButton(
icon: Icon(
characteristic.isNotifying
? Icons.sync_disabled
: Icons.sync,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5)),
onPressed: onNotificationPressed,
)
],
),
children: descriptorTiles,
);
},
);
}
}
class DescriptorTile extends StatelessWidget {
final BluetoothDescriptor descriptor;
final VoidCallback? onReadPressed;
final VoidCallback? onWritePressed;
const DescriptorTile(
{Key? key,
required this.descriptor,
this.onReadPressed,
this.onWritePressed})
: super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text('Descriptor'),
Text('0x${descriptor.uuid.toString().toUpperCase().substring(4, 8)}',
style: Theme.of(context)
.textTheme
.bodyText1
?.copyWith(color: Theme.of(context).textTheme.caption?.color))
],
),
subtitle: StreamBuilder<List<int>>(
stream: descriptor.value,
initialData: descriptor.lastValue,
builder: (c, snapshot) => Text(snapshot.data.toString()),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: Icon(
Icons.file_download,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5),
),
onPressed: onReadPressed,
),
IconButton(
icon: Icon(
Icons.file_upload,
color: Theme.of(context).iconTheme.color?.withOpacity(0.5),
),
onPressed: onWritePressed,
)
],
),
);
}
}
class AdapterStateTile extends StatelessWidget {
const AdapterStateTile({Key? key, required this.state}) : super(key: key);
final BluetoothState state;
@override
Widget build(BuildContext context) {
return Container(
color: Colors.redAccent,
child: ListTile(
title: Text(
'Bluetooth adapter is ${state.toString().substring(15)}',
style: Theme.of(context).primaryTextTheme.headline1,
),
trailing: Icon(
Icons.error,
color: Theme.of(context).primaryTextTheme.subtitle1?.color,
),
),
);
}
}

View File

@@ -0,0 +1,439 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
adaptive_dialog:
dependency: "direct main"
description:
name: adaptive_dialog
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
animations:
dependency: transitive
description:
name: animations
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
archive:
dependency: transitive
description:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.2"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.8.1"
bitmap:
dependency: "direct main"
description:
name: bitmap
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.2"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_blue:
dependency: "direct main"
description:
name: flutter_blue
url: "https://pub.dartlang.org"
source: hosted
version: "0.8.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
font_awesome_flutter:
dependency: "direct main"
description:
name: font_awesome_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "9.1.0"
google_fonts:
dependency: "direct main"
description:
name: google_fonts
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
http:
dependency: transitive
description:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.13.3"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
image:
dependency: "direct main"
description:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.10"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
path_provider:
dependency: transitive
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.11.1"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.0"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.3"
protobuf:
dependency: transitive
description:
name: protobuf
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
quiver:
dependency: "direct main"
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
rxdart:
dependency: transitive
description:
name: rxdart
url: "https://pub.dartlang.org"
source: hosted
version: "0.26.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
sn_progress_dialog:
dependency: "direct main"
description:
name: sn_progress_dialog
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.2"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
wakelock:
dependency: "direct main"
description:
name: wakelock
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.3+3"
wakelock_macos:
dependency: transitive
description:
name: wakelock_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0+2"
wakelock_platform_interface:
dependency: transitive
description:
name: wakelock_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.1+2"
wakelock_web:
dependency: transitive
description:
name: wakelock_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0+2"
wakelock_windows:
dependency: transitive
description:
name: wakelock_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0+1"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.9"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "5.2.0"
sdks:
dart: ">=2.13.0 <3.0.0"
flutter: ">=2.0.0"

View File

@@ -0,0 +1,101 @@
name: epaper_emoji_ble
description: App allows to send the emoji you choose to your e-paper via ble
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.12.0 <3.0.0"
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
google_fonts: ^2.1.0
adaptive_dialog: ^1.1.0
font_awesome_flutter: ^9.1.0
bitmap: ^0.1.2
image: ^3.0.2
flutter_blue: ^0.8.0
quiver: ^3.0.1
sn_progress_dialog: ^1.0.3
wakelock: ^0.5.3+3
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^1.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/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
assets:
- assets/images/
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - 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