{"id":1257,"date":"2021-05-18T01:15:10","date_gmt":"2021-05-17T16:15:10","guid":{"rendered":"http:\/\/blog.box.kr\/?p=1257"},"modified":"2021-05-18T01:15:14","modified_gmt":"2021-05-17T16:15:14","slug":"ble-%ec%82%ac%ec%9a%a9%ed%95%98%ea%b8%b0","status":"publish","type":"post","link":"https:\/\/blog.box.kr\/?p=1257","title":{"rendered":"BLE \uc0ac\uc6a9\ud558\uae30"},"content":{"rendered":"\n<p>\ub77c\uc774\ube0c\ub7ec\ub9ac \ucd94\uac00 \ubc0f SCAN \uae30\ub2a5 \uad6c\ud604<br>flutter_ble_lib<br>https:\/\/pub.dev\/packages\/flutter_ble_lib<br><br>permission_handler<br>https:\/\/pub.dev\/packages\/permission_handler<br><br>\ud504\ub85c\uc81d\ud2b8\uc5d0 \uc548\ub4dc\ub85c\uc774\ub4dc SDK \ubc84\uc804\uc774 \ub0ae\uac8c \uc124\uc815\ub418\uc5b4 \uc544\ub798\uc640 \uac19\uc740 \uc5d0\ub7ec\uac00 \ubc1c\uc0dd\ud560 \uc218\uc774\ub2e4<br><\/p>\n\n\n\n<p>ble_example\\android\\app\\src\\debug\\AndroidManifest.xml Error: uses-sdk:minSdkVersion 16 cannot be smaller than version 18 declared in library [:flutter_ble_lib] E:\\study\\flutter\\ble_example\\build\\flutter_ble_lib\\intermediates\\library_manifest\\debug\\AndroidManifest.xml as the library might be using APIs not available in 16 Suggestion: use a compatible library with a minSdk of at most 16, or increase this project&#8217;s minSdk version to at least 18, or use tools:overrideLibrary=&#8221;com.polidea.flutter_ble_lib&#8221; to force usage (may lead to runtime failures) FAILURE: Build failed with an exception. * What went wrong: Execution failed for task &#8216;:app:processDebugManifest&#8217;. > Manifest merger failed : uses-sdk:minSdkVersion 16 cannot be smaller than version 18 declared in library [:flutter_ble_lib] E:\\study\\flutter\\ble_example\\build\\flutter_ble_lib\\intermediates\\library_manifest\\debug\\AndroidManifest.xml as the library might be using APIs not available in 16 Suggestion: use a compatible library with a minSdk of at most 16, or increase this project&#8217;s minSdk version to at least 18, or use tools:overrideLibrary=&#8221;com.polidea.flutter_ble_lib&#8221; to force usage (may lead to runtime failures) * Try: Run with &#8211;stacktrace option to get the stack trace. Run with &#8211;info or &#8211;debug option to get more log output. Run with &#8211;scan to get full insights. * Get more help at https:\/\/help.gradle.org BUILD FAILED in 1m 3s Exception: Gradle task assembleDebug failed with exit code 1 Exited (sigterm)<\/p>\n\n\n\n<p><br>\ud574\ub2f9 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\ub824\uba74 \ucd5c\uc18c SDK \ubc84\uc804\uc744 1.8 \uc774\uc0c1\uc73c\ub85c \uc62c\ub824\uc57c \ud55c\ub2e4.<br><\/p>\n\n\n\n<p id=\"SE-5705fe95-1682-415f-851c-ca716c871d56\">android\/app\/build.gradle&#8221;\uc744 \ud30c\uc77c\uc5d0\uc11c<\/p>\n\n\n\n<p id=\"SE-22064bc5-fcdf-46c9-b4d3-0dc728d167de\">defaultConfig \ud56d\ubaa9 \uc911 minSdkVersion\ub97c 18 \uc774\uc0c1\uc73c\ub85c \ubcc0\uacbd \ud574\uc57c\ud568.<br><br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import 'dart:io';\r\nimport 'package:flutter\/material.dart';\r\nimport 'package:flutter_ble_lib\/flutter_ble_lib.dart';\r\nimport 'package:permission_handler\/permission_handler.dart';\r\n\r\nvoid main() {\r\n  runApp(MyApp());\r\n}\r\n\r\nclass MyApp extends StatelessWidget {\r\n  @override\r\n  Widget build(BuildContext context) {\r\n    return MaterialApp(\r\n      title: 'Flutter BLE Demo',\r\n      home: MyHomePage(title: 'Flutter BLE Demo Page'),\r\n    );\r\n  }\r\n}\r\n\r\nclass MyHomePage extends StatefulWidget {\r\n  MyHomePage({Key key, this.title}) : super(key: key);\r\n  final String title;\r\n\r\n  @override\r\n  _MyHomePageState createState() => _MyHomePageState();\r\n}\r\n\r\nclass _MyHomePageState extends State&lt;MyHomePage> {\r\n  BleManager _bleManager = BleManager(); \/\/BLE \uba54\ub2c8\uc800\r\n  bool _isScanning= false;               \/\/\uc2a4\uce94 \ud655\uc778\uc6a9\r\n  List&lt;BleDeviceItem> deviceList = &#91;];   \/\/BLE \uc815\ubcf4 \uc800\uc7a5\uc6a9\r\n\r\n  @override\r\n  void initState() {\r\n    init(); \/\/BLE \ucd08\uae30\ud654\r\n    super.initState();\r\n  }\r\n\r\n  void init() async {\r\n      \/\/BLE \uc0dd\uc131\r\n      await _bleManager.createClient(\r\n        restoreStateIdentifier: \"example-restore-state-identifier\",\r\n        restoreStateAction: (peripherals) {\r\n          peripherals?.forEach((peripheral) {\r\n            print(\"Restored peripheral: ${peripheral.name}\");\r\n          });\r\n        })\r\n        .catchError((e) => print(\"Couldn't create BLE client  $e\"))\r\n        .then((_) => _checkPermissions()) \/\/BLE \uc0dd\uc131 \ud6c4 \ud37c\ubbf8\uc158 \uccb4\ud06c\r\n        .catchError((e) => print(\"Permission check error $e\"));\r\n        \/\/.then((_) => _waitForBluetoothPoweredOn())        \r\n  }\r\n  \/\/\ud37c\ubbf8\uc158 \uccb4\ud06c \ubc0f \uc5c6\uc73c\uba74 \ud37c\ubbf8\uc158 \ub3d9\uc758 \ud654\uba74 \ucd9c\ub825\r\n  _checkPermissions() async {\r\n    if (Platform.isAndroid) {\r\n      if (await Permission.contacts.request().isGranted) {        \r\n      }\r\n      Map&lt;Permission, PermissionStatus> statuses = await &#91;\r\n        Permission.location\r\n      ].request();\r\n      print(statuses&#91;Permission.location]);      \r\n    }\r\n  }\r\n\r\n  \/\/\uc2a4\uce94 ON\/OFF \r\n  void scan() async {\r\n    if(!_isScanning) {\r\n      deviceList.clear();\r\n      _bleManager.startPeripheralScan().listen((scanResult) {          \r\n        \/\/ \ud398\ub9ac\ud398\ub7f4 \ud56d\ubaa9\uc5d0 \uc774\ub984\uc774 \uc788\uc73c\uba74 \uadf8\uac78 \uc0ac\uc6a9\ud558\uace0 \r\n        \/\/ \uc5c6\ub2e4\uba74 \uc5b4\ub4dc\ubc84\ud0c0\uc774\uc9c0\uba3c\ud2b8 \ub370\uc774\ud130\uc758 \uc774\ub984\uc744 \uc0ac\uc6a9\ud558\uace0 \uadf8\uac83 \ub9c8\uc838 \uc5c6\ub2e4\uba74 Unknown\uc73c\ub85c \ud45c\uc2dc\r\n        var name = scanResult.peripheral.name ?? scanResult.advertisementData.localName ?? \"Unknown\";\r\n        \/*\r\n        \/\/ \uc5ec\ub7ec\uac00\uc9c0 \uc815\ubcf4 \ud655\uc778\r\n        print(\"Scanned Name ${name}, RSSI ${scanResult.rssi}\");        \r\n        print(\"\\tidentifier(mac) ${scanResult.peripheral.identifier}\"); \/\/mac address\r\n        print(\"\\tservice UUID : ${scanResult.advertisementData.serviceUuids}\");        \r\n        print(\"\\tmanufacture Data : ${scanResult.advertisementData.manufacturerData}\");        \r\n        print(\"\\tTx Power Level : ${scanResult.advertisementData.txPowerLevel}\");\r\n        print(\"\\t${scanResult.peripheral}\");\r\n        *\/ \r\n        \/\/\uc774\ubbf8 \uac80\uc0c9\ub41c \uc7a5\uce58\uc778\uc9c0 \ud655\uc778 mac \uc8fc\uc18c\ub85c \ud655\uc778\r\n        var findDevice = deviceList.any((element) {                    \r\n          if(element.peripheral.identifier == scanResult.peripheral.identifier)\r\n          {\r\n            \/\/\uc774\ubbf8 \uc874\uc7ac\ud558\uba74 \uae30\uc874 \uac12\uc744 \uac31\uc2e0.\r\n            element.peripheral = scanResult.peripheral;\r\n            element.advertisementData = scanResult.advertisementData;            \r\n            element.rssi = scanResult.rssi;\r\n            return true;            \r\n          }        \r\n          return false;\r\n        });\r\n        \/\/\ucc98\uc74c \ubc1c\uacac\ub41c \uc7a5\uce58\ub77c\uba74 devicelist\uc5d0 \ucd94\uac00\r\n        if(!findDevice) {\r\n          deviceList.add(BleDeviceItem(name, scanResult.rssi, scanResult.peripheral, scanResult.advertisementData));\r\n        }\r\n        \/\/\uac31\uae34 \uc801\uc6a9.\r\n        setState((){});\r\n      });      \r\n      \/\/\uc2a4\uce94\uc911\uc73c\ub85c \ubcc0\uc218 \ubcc0\uacbd\r\n      setState(() { _isScanning = true; });\r\n    }\r\n    else {      \r\n      \/\/\uc2a4\uce94\uc911\uc774\uc5c8\ub2e4\uba74 \uc2a4\uce94 \uc815\uc9c0\r\n      _bleManager.stopPeripheralScan();      \r\n      setState(() { _isScanning = false; });\r\n    }\r\n  }\r\n  \r\n  \/\/\ub514\ubc14\uc774\uc2a4 \ub9ac\uc2a4\ud2b8 \ud654\uba74\uc5d0 \ucd9c\ub825\r\n  list() {\r\n    return ListView.builder( \r\n      itemCount: deviceList.length, \r\n      itemBuilder: (context, index) { \r\n        return ListTile( \r\n          \/\/\ub514\ubc14\uc774\uc2a4 \uc774\ub984\uacfc \ub9e5\uc8fc\uc18c \uadf8\ub9ac\uace0 \uc2e0\ud638 \uc138\uae30\ub97c \ud45c\uc2dc\ud55c\ub2e4.\r\n          title: Text(deviceList&#91;index].deviceName), \r\n          subtitle: Text(deviceList&#91;index].peripheral.identifier),\r\n          trailing: Text(\"${deviceList&#91;index].rssi}\"),          \r\n        ); \r\n      },\r\n    );\r\n  }\r\n\r\n  @override\r\n  Widget build(BuildContext context) {\r\n    return Scaffold(\r\n      appBar: AppBar(\r\n        title: Text(widget.title),\r\n      ),\r\n      body: Center(\r\n            \/\/\ub514\ubc14\uc774\uc2a4 \ub9ac\uc2a4\ud2b8 \ud568\uc218 \ud638\ucd9c\r\n            child: list(),\r\n      ),\r\n      floatingActionButton: FloatingActionButton(\r\n        onPressed: scan, \/\/\ubc84\ud2bc\uc774 \ub20c\ub9ac\uba74 \uc2a4\uce94 ON\/OFF \ub3d9\uc791       \r\n        child: Icon(_isScanning?Icons.stop:Icons.bluetooth_searching), \/\/_isScanning \ubcc0\uc218\uc5d0 \ub530\ub77c \uc544\uc774\ucf58 \ud45c\uc2dc \ubcc0\uacbd\r\n      ),\r\n    );\r\n  }\r\n}\r\n\r\n\/\/\ub514\ubc14\uc774\uc2a4 \uc815\ubcf4 \uc800\uc7a5\uc6a9 \ud074\ub798\uc2a4\r\nclass BleDeviceItem {\r\n    String deviceName;\r\n    Peripheral peripheral;\r\n    int rssi;\r\n    AdvertisementData advertisementData;   \r\n    BleDeviceItem(this.deviceName, this.rssi, this.peripheral, this.advertisementData);\r\n}<\/code><\/pre>\n\n\n\n<p><br>\uc5f0\uacb0 + \ud574\uc81c \uae30\ub2a5 \uad6c\ud604<br><br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import 'dart:io';\r\nimport 'package:flutter\/material.dart';\r\nimport 'package:flutter_ble_lib\/flutter_ble_lib.dart';\r\nimport 'package:permission_handler\/permission_handler.dart';\r\n\r\nvoid main() {\r\n  runApp(MyApp());\r\n}\r\n\r\nclass MyApp extends StatelessWidget {\r\n  @override\r\n  Widget build(BuildContext context) {\r\n    return MaterialApp(\r\n      title: 'Flutter BLE Demo',\r\n      home: MyHomePage(title: 'Flutter BLE Demo Page'),\r\n    );\r\n  }\r\n}\r\n\r\nclass MyHomePage extends StatefulWidget {\r\n  MyHomePage({Key key, this.title}) : super(key: key);\r\n  final String title;\r\n\r\n  @override\r\n  _MyHomePageState createState() => _MyHomePageState();\r\n}\n\n\nclass _MyHomePageState extends State&lt;MyHomePage> {\r\n\r\n  BleManager _bleManager = BleManager();\r\n  bool _isScanning = false;      \r\n  bool _connected = false;\r\n  Peripheral _curPeripheral;           \/\/ \uc5f0\uacb0\ub41c \uc7a5\uce58 \ubcc0\uc218\r\n  List&lt;BleDeviceItem> deviceList = &#91;]; \/\/ BLE \uc7a5\uce58 \ub9ac\uc2a4\ud2b8 \ubcc0\uc218\r\n  String _statusText = '';             \/\/ BLE \uc0c1\ud0dc \ubcc0\uc218\r\n\r\n  @override\r\n  void initState() {\r\n    init();\r\n    super.initState();\r\n  }\r\n\r\n  \/\/ BLE \ucd08\uae30\ud654 \ud568\uc218\r\n  void init() async {\r\n      \/\/ble \ub9e4\ub2c8\uc800 \uc0dd\uc131\r\n      await _bleManager.createClient(\r\n        restoreStateIdentifier: \"example-restore-state-identifier\",\r\n        restoreStateAction: (peripherals) {\r\n          peripherals?.forEach((peripheral) {\r\n            print(\"Restored peripheral: ${peripheral.name}\");\r\n          });\r\n        })\r\n        .catchError((e) => print(\"Couldn't create BLE client  $e\"))\r\n        .then((_) => _checkPermissions())  \/\/\ub9e4\ub2c8\uc800 \uc0dd\uc131\ub418\uba74 \uad8c\ud55c \ud655\uc778\r\n        .catchError((e) => print(\"Permission check error $e\"));\r\n  }\r\n\r\n  \/\/ \uad8c\ud55c \ud655\uc778 \ud568\uc218 \uad8c\ud55c \uc5c6\uc73c\uba74 \uad8c\ud55c \uc694\uccad \ud654\uba74 \ud45c\uc2dc, \uc548\ub4dc\ub85c\uc774\ub4dc\ub9cc \uc0c1\uad00 \uc788\uc74c\r\n  _checkPermissions() async {\r\n    if (Platform.isAndroid) {\r\n      if (await Permission.contacts.request().isGranted) {        \r\n      }\r\n      Map&lt;Permission, PermissionStatus> statuses = await &#91;\r\n        Permission.location\r\n      ].request();\r\n      print(statuses&#91;Permission.location]);      \r\n    }\r\n  }\r\n  \r\n  \/\/\uc7a5\uce58 \ud654\uba74\uc5d0 \ucd9c\ub825\ud558\ub294 \uc704\uc82f \ud568\uc218\r\n  list() {\r\n    return ListView.builder( \r\n      itemCount: deviceList.length, \r\n      itemBuilder: (context, index) { \r\n        return ListTile( \r\n          title: Text(deviceList&#91;index].deviceName), \r\n          subtitle: Text(deviceList&#91;index].peripheral.identifier),\r\n          trailing: Text(\"${deviceList&#91;index].rssi}\"),          \r\n          onTap: () {  \/\/ \ub9ac\uc2a4\ud2b8\uc911 \ud55c\uac1c\ub97c \ud0ed(\ud130\uce58) \ud558\uba74 \ud574\ub2f9 \ub514\ubc14\uc774\uc2a4\uc640 \uc5f0\uacb0\uc744 \uc2dc\ub3c4\ud55c\ub2e4.\r\n            connect(index);\r\n          }\r\n        ); \r\n      },      \r\n    );\r\n  }\r\n  \/\/scan \ud568\uc218\r\n  void scan() async {\r\n    if(!_isScanning) {\r\n      deviceList.clear(); \/\/\uae30\uc874 \uc7a5\uce58 \ub9ac\uc2a4\ud2b8 \ucd08\uae30\ud654\r\n      \/\/SCAN \uc2dc\uc791\r\n      _bleManager.startPeripheralScan().listen((scanResult) {\r\n        \/\/listen \uc774\ubca4\ud2b8 \ud615\uc2dd\uc73c\ub85c \uc7a5\uce58\uac00 \ubc1c\uacac\ub418\uba74 \ud574\ub2f9 \ub8e8\ud2f4\uc744 \uacc4\uc18d \ud0d0.\r\n        \/\/periphernal.name\uc774 \uc5c6\uc73c\uba74 advertisementData.localName\ud655\uc778 \uc774\uac83\ub3c4 \uc5c6\ub2e4\uba74 unknown\uc73c\ub85c \ud45c\uc2dc\r\n        var name = scanResult.peripheral.name ?? scanResult.advertisementData.localName ?? \"Unknown\";   \r\n        \/\/ \uae30\uc874\uc5d0 \uc874\uc7ac\ud558\ub294 \uc7a5\uce58\uba74 \uc5c5\ub370\uc774\ud2b8\r\n        var findDevice = deviceList.any((element) {                    \r\n          if(element.peripheral.identifier == scanResult.peripheral.identifier)\r\n          {\r\n            element.peripheral = scanResult.peripheral;\r\n            element.advertisementData = scanResult.advertisementData;            \r\n            element.rssi = scanResult.rssi;\r\n            return true;            \r\n          }        \r\n          return false;\r\n        });\r\n        \/\/ \uc0c8\ub85c \ubc1c\uacac\ub41c \uc7a5\uce58\uba74 \ucd94\uac00\r\n        if(!findDevice) {\r\n          deviceList.add(BleDeviceItem(name, scanResult.rssi, scanResult.peripheral, scanResult.advertisementData));\r\n        }\r\n        \/\/\ud398\uc774\uc9c0 \uac31\uc2e0\uc6a9\r\n        setState((){});\r\n      });      \r\n      setState(() { \/\/BLE \uc0c1\ud0dc\uac00 \ubcc0\uacbd\ub418\uba74 \ud654\uba74\ub3c4 \uac31\uc2e0\r\n        _isScanning = true;  \r\n        setBLEState('Scanning');\r\n      });\r\n    }\r\n    else {      \r\n      \/\/\uc2a4\ucf04\uc911\uc774\uc5c8\uc73c\uba74 \uc2a4\uce94 \uc911\uc9c0\r\n      _bleManager.stopPeripheralScan();      \r\n      setState(() { \/\/BLE \uc0c1\ud0dc\uac00 \ubcc0\uacbd\ub418\uba74 \ud398\uc774\uc9c0\ub3c4 \uac31\uc2e0\r\n        _isScanning = false; \r\n        setBLEState('Stop Scan');\r\n      });\r\n    }\r\n  }\r\n\r\n  \/\/BLE \uc5f0\uacb0\uc2dc \uc608\uc678 \ucc98\ub9ac\ub97c \uc704\ud55c \ub798\ud551 \ud568\uc218\r\n  _runWithErrorHandling(runFunction) async {\r\n    try {  \r\n      await runFunction();\r\n    } on BleError catch (e) {\r\n      print(\"BleError caught: ${e.errorCode.value} ${e.reason}\");\r\n    } catch (e) {\r\n      if (e is Error) {\r\n        debugPrintStack(stackTrace: e.stackTrace);\r\n      }\r\n      print(\"${e.runtimeType}: $e\");\r\n    }\r\n  }\r\n\r\n  \/\/ \uc0c1\ud0dc \ubcc0\uacbd\ud558\uba74\uc11c \ud398\uc774\uc9c0\ub3c4 \uac31\uc2e0\ud558\ub294 \ud568\uc218\r\n  void setBLEState(txt){\r\n    setState(() => _statusText = txt);\r\n  }\r\n\r\n \/\/\uc5f0\uacb0 \ud568\uc218\r\n connect(index) async {\r\n    if(_connected) {  \/\/\uc774\ubbf8 \uc5f0\uacb0\uc0c1\ud0dc\uba74 \uc5f0\uacb0 \ud574\uc81c\ud6c4 \uc885\ub8cc\r\n      await _curPeripheral?.disconnectOrCancelConnection();\r\n      return;\r\n    }\r\n\r\n    \/\/\uc120\ud0dd\ud55c \uc7a5\uce58\uc758 peripheral \uac12\uc744 \uac00\uc838\uc628\ub2e4.\r\n    Peripheral peripheral = deviceList&#91;index].peripheral;        \r\n\r\n    \/\/\ud574\ub2f9 \uc7a5\uce58\uc640\uc758 \uc5f0\uacb0\uc0c1\ud0dc\ub97c \uad00\ucd2c\ud558\ub294 \ub9ac\uc2a4\ub108 \uc2e4\ud589\r\n    peripheral.observeConnectionState(emitCurrentValue: true)\r\n      .listen((connectionState) {\r\n      \/\/ \uc5f0\uacb0\uc0c1\ud0dc\uac00 \ubcc0\uacbd\ub418\uba74 \ud574\ub2f9 \ub8e8\ud2f4\uc744 \ud0d0.\r\n      switch(connectionState) {        \r\n        case PeripheralConnectionState.connected: {  \/\/\uc5f0\uacb0\ub428\r\n          _curPeripheral = peripheral;\r\n          setBLEState('connected');\r\n        }        \r\n        break;\r\n        case PeripheralConnectionState.connecting: { setBLEState('connecting'); }\/\/\uc5f0\uacb0\uc911\r\n        break;\r\n        case PeripheralConnectionState.disconnected: { \/\/\ud574\uc81c\ub428\r\n            _connected=false;         \r\n            print(\"${peripheral.name} has DISCONNECTED\"); \r\n            setBLEState('disconnected');\r\n        }\r\n        break;\r\n        case PeripheralConnectionState.disconnecting: { setBLEState('disconnecting');}\/\/\ud574\uc81c\uc911\r\n        break;\r\n        default:{\/\/\uc54c\uc218\uc5c6\uc74c...\r\n            print(\"unkown connection state is: \\n $connectionState\");\r\n        }\r\n        break;\r\n      }\r\n    });\r\n\r\n    _runWithErrorHandling(() async {\r\n      \/\/\ud574\ub2f9 \uc7a5\uce58\uc640 \uc774\ubbf8 \uc5f0\uacb0\ub418\uc5b4 \uc788\ub294\uc9c0 \ud655\uc778\r\n      bool isConnected = await peripheral.isConnected();\r\n      if(isConnected) {\r\n        print('device is already connected');\r\n        \/\/\uc774\ubbf8 \uc5f0\uacb0\ub418\uc5b4 \uc788\uae30\ub54c\ubb38\uc5d0 \ubb34\uc2dc\ud558\uace0 \uc885\ub8cc.. \r\n        return;\r\n      }\r\n\r\n      \/\/\uc5f0\uacb0 \uc2dc\uc791!\r\n      await peripheral.connect().then((_) {\r\n        \/\/\uc5f0\uacb0\uc774 \ub418\uba74 \uc7a5\uce58\uc758 \ubaa8\ub4e0 \uc11c\ube44\uc2a4\uc640 \uce90\ub9ad\ud130\ub9ac\uc2a4\ud2f1\uc744 \uac80\uc0c9\ud55c\ub2e4.\r\n        peripheral.discoverAllServicesAndCharacteristics()\r\n        .then((_) => peripheral.services())\r\n        .then((services) async {           \r\n          print(\"PRINTING SERVICES for ${peripheral.name}\");\r\n          \/\/\uac01\uac01\uc758 \uc11c\ube44\uc2a4\uc758 \ud558\uc704 \uce90\ub9ad\ud130\ub9ac\uc2a4\ud2f1 \uc815\ubcf4\ub97c \ub514\ubc84\uae45\ucc3d\uc5d0 \ud45c\uc2dc\ud55c\ub2e4.\r\n          for(var service in services) {\r\n            print(\"Found service ${service.uuid}\");\r\n            List&lt;Characteristic> characteristics = await service.characteristics();\r\n            for( var characteristic in characteristics ) {\r\n              print(\"${characteristic.uuid}\");\r\n            }\r\n          }\r\n          \/\/\ubaa8\ub4e0 \uacfc\uc815\uc774 \ub9c8\ubb34\ub9ac\ub418\uba74 \uc5f0\uacb0\ub418\uc5c8\ub2e4\uace0 \ud45c\uc2dc\r\n          _connected = true;                    \r\n          print(\"${peripheral.name} has CONNECTED\");     \r\n        });\r\n      });\r\n    });\r\n  }\r\n \r\n  \/\/\ud398\uc774\uc9c0 \uad6c\uc131\r\n  @override\r\n  Widget build(BuildContext context) {\r\n    return Scaffold(\r\n      appBar: AppBar(\r\n        title: Text(widget.title),\r\n      ),\r\n      body: Center(\r\n        child: Column(\r\n          children: &lt;Widget>&#91;\r\n            Expanded(\r\n              flex: 1,\r\n              child: list(), \/\/\ub9ac\uc2a4\ud2b8 \ucd9c\ub825\r\n            ),\r\n            Container(\r\n              child: Row(\r\n                children: &lt;Widget>&#91;\r\n                  RaisedButton( \/\/scan \ubc84\ud2bc\r\n                    onPressed: scan,\r\n                    child: Icon(_isScanning?Icons.stop:Icons.bluetooth_searching),\r\n                  ),\r\n                  SizedBox(width: 10,),\r\n                  Text(\"State : \"), Text(_statusText), \/\/\uc0c1\ud0dc \uc815\ubcf4 \ud45c\uc2dc\r\n                ],\r\n              ),  \r\n            ),\r\n          ],\r\n        ),\r\n      ),\r\n    );\r\n  }\r\n}\r\n\r\n\/\/BLE \uc7a5\uce58 \uc815\ubcf4 \uc800\uc7a5 \ud074\ub798\uc2a4\r\nclass BleDeviceItem {\r\n    String deviceName;\r\n    Peripheral peripheral;\r\n    int rssi;\r\n    AdvertisementData advertisementData;   \r\n    BleDeviceItem(this.deviceName, this.rssi, this.peripheral, this.advertisementData);\r\n}<\/code><\/pre>\n\n\n\n<p>\uc608\ub97c \ub4e4\uc5b4 \uc704\uc640 \uac19\uc774 Nordic_UART\ub97c \uc120\ud0dd\ud574 \uc5f0\uacb0\uc744 \ud558\uac8c \ub418\uba74 \uc544\ub798\uc640 \uac19\uc740 \uba54\uc2dc\uc9c0\ub4e4\uc744 \ubcfc \uc218 \uc788\ub2e4.<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-attachment-id=\"1258\" data-permalink=\"https:\/\/blog.box.kr\/?attachment_id=1258\" data-orig-file=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image.png?fit=729%2C464&amp;ssl=1\" data-orig-size=\"729,464\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image.png?fit=300%2C191&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image.png?fit=623%2C397&amp;ssl=1\" decoding=\"async\" loading=\"lazy\" width=\"623\" height=\"397\" src=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image.png?resize=623%2C397&#038;ssl=1\" alt=\"\" class=\"wp-image-1258\" srcset=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image.png?w=729&amp;ssl=1 729w, https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image.png?resize=300%2C191&amp;ssl=1 300w, https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image.png?resize=189%2C120&amp;ssl=1 189w\" sizes=\"(max-width: 623px) 100vw, 623px\" data-recalc-dims=\"1\" \/><\/figure>\n\n\n\n<p>\uc704\uc5d0 \ud45c\uc2dc\ud55c \uac83\ub4e4\uc740 \ud574\ub2f9 \uc7a5\uce58\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc11c\ube44\uc2a4 UUID\uc774\ub2e4.<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-attachment-id=\"1259\" data-permalink=\"https:\/\/blog.box.kr\/?attachment_id=1259\" data-orig-file=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-1.png?fit=735%2C460&amp;ssl=1\" data-orig-size=\"735,460\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image-1\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-1.png?fit=300%2C188&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-1.png?fit=623%2C390&amp;ssl=1\" decoding=\"async\" loading=\"lazy\" width=\"623\" height=\"390\" src=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-1.png?resize=623%2C390&#038;ssl=1\" alt=\"\" class=\"wp-image-1259\" srcset=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-1.png?w=735&amp;ssl=1 735w, https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-1.png?resize=300%2C188&amp;ssl=1 300w, https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-1.png?resize=192%2C120&amp;ssl=1 192w\" sizes=\"(max-width: 623px) 100vw, 623px\" data-recalc-dims=\"1\" \/><\/figure>\n\n\n\n<p>\uadf8\ub9ac\uace0 \uc774\uac83\uc740 \uac01 \uc11c\ube44\uc2a4\uc758 \uce90\ub9ac\ud130\ub9ac\uc2a4\ud2f1\uc774\ub2e4.<br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-attachment-id=\"1260\" data-permalink=\"https:\/\/blog.box.kr\/?attachment_id=1260\" data-orig-file=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-2.png?fit=704%2C463&amp;ssl=1\" data-orig-size=\"704,463\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image-2\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-2.png?fit=300%2C197&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-2.png?fit=623%2C410&amp;ssl=1\" decoding=\"async\" loading=\"lazy\" width=\"623\" height=\"410\" src=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-2.png?resize=623%2C410&#038;ssl=1\" alt=\"\" class=\"wp-image-1260\" srcset=\"https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-2.png?w=704&amp;ssl=1 704w, https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-2.png?resize=300%2C197&amp;ssl=1 300w, https:\/\/i0.wp.com\/blog.box.kr\/wp-content\/uploads\/2021\/05\/image-2.png?resize=182%2C120&amp;ssl=1 182w\" sizes=\"(max-width: 623px) 100vw, 623px\" data-recalc-dims=\"1\" \/><figcaption>\ub9c8\uc9c0\ub9c9\uc73c\ub85c \ub178\ub974\ub515 UART \uc7a5\uce58\uc758 \uacbd\uc6b0 \uc704\uc5d0 \ud45c\uc2dc\ud55c \uc11c\ube44\uc2a4 UUID\uc640 \ubc14\ub85c \uc544\ub798 \uce90\ub9ad\ud130\ub9ac\uc2a4\ud2f1 UUID 2\uac00\uc9c0\ub9cc \uc54c\uace0 \uc788\uc73c\uba74 \ud1b5\uc2e0\uc744 \ud560 \uc218 \uc788\ub2e4.<br>\u200b<br>\ub2e4\uc74c\ubc88\uc5d4 \ud574\ub2f9 \uc815\ubcf4\ub4e4\ub85c \ub370\uc774\ud130\ub97c \uc8fc\uace0\ubc1b\ub294 \ubc29\ubc95\uc744 \uc54c\uc544\ubcfc \uac83\uc774\ub2e4.<br>\uc7a0\uae50 \ub9db\ubcf4\uae30\ub85c \ubcf4\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\ub2e4.<br>\uc6b0\uc120 \ub370\uc774\ud130 \ubcf4\ub0bc \ub54c<br><br><\/figcaption><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/\ubcf4\ub0bc\ub54c\r\nperipheral.writeCharacteristic(\r\n      BLE_SERVICE_UUID,\r\n      BLE_RX_CHARACTERISTIC,\r\n      Uint8List.fromList(message.codeUnits),\r\n      false);  \n\n\/\/\ubc1b\ub294 \uce90\ub9ac\ud130\ub9ac\uc2a4\ud2f1 \ubaa8\ub2c8\ud130\ub9c1 ON \ud568\uc218, \ubcf4\ud1b5 Notification Enable \uc815\ub3c4\ub85c \uc0dd\uac01\ud558\uba74\ub420 \uac83 \uac19\ub2e4.\r\ncharacteristicUpdates = peripheral.monitorCharacteristic(\r\n     BLE_SERVICE_UUID, \r\n     BLE_TX_CHARACTERISTIC);\r\n\r\n\/\/\ub370\uc774\ud130 \ubc1b\ub294 \ub9ac\uc2a4\ub108 \ud578\ub4e4 \ubcc0\uc218\r\nStreamSubscription monitoringStreamSubscription;\r\n\r\n\/\/\uc774\ubbf8 \ub9ac\uc2a4\ub108\uac00 \uc788\ub2e4\uba74 \ucde8\uc18c\r\nawait monitoringStreamSubscription?.cancel(); \/\/ ?. = \ud574\ub2f9\uac1d\uccb4\uac00 null\uc774\uba74 \ubb34\uc2dc\ud558\uace0 \ub118\uc5b4\uac10.\r\nmonitoringStreamSubscription = characteristicUpdates.listen( (value) {        \r\n     print(\"read data : ${value.value}\");  \/\/\ub370\uc774\ud130 \ucd9c\ub825\r\n   },\r\n   onError: (error) {\r\n     print(\"Error while monitoring characteristic \\n$error\"); \/\/\uc2e4\ud328\uc2dc\r\n   },\r\n   cancelOnError: true, \/\/\uc5d0\ub7ec \ubc1c\uc0dd\uc2dc \uc790\ub3d9\uc73c\ub85c listen \ucde8\uc18c\r\n);<\/code><\/pre>\n\n\n\n<p><br><br>\uc774\uac8c \ub354 \uc88b\ub2e4\ub124&#8230;<br>https:\/\/pub.dev\/packages\/flutter_blue<br><br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ub77c\uc774\ube0c\ub7ec\ub9ac \ucd94\uac00 \ubc0f SCAN \uae30\ub2a5 \uad6c\ud604flutter_ble_libhttps:\/\/pub.dev\/packages\/flutter_ble_lib permission_handlerhttps:\/\/pub.dev\/packages\/permission_handler \ud504\ub85c\uc81d\ud2b8\uc5d0 \uc548\ub4dc\ub85c\uc774\ub4dc SDK \ubc84\uc804\uc774 \ub0ae\uac8c \uc124\uc815\ub418\uc5b4 \uc544\ub798\uc640 \uac19\uc740 \uc5d0\ub7ec\uac00 \ubc1c\uc0dd\ud560 \uc218\uc774\ub2e4 ble_example\\android\\app\\src\\debug\\AndroidManifest.xml Error: uses-sdk:minSdkVersion 16 cannot be smaller than version 18 declared in library [:flutter_ble_lib] E:\\study\\flutter\\ble_example\\build\\flutter_ble_lib\\intermediates\\library_manifest\\debug\\AndroidManifest.xml as the library might be using APIs not available in 16 Suggestion: use a compatible library with a minSdk of at most 16, or increase this project&#8217;s minSdk version to at least 18, or use tools:overrideLibrary=&#8221;com.polidea.flutter_ble_lib&#8221; to force usage (may lead to runtime failures) FAILURE: Build failed with an exception. * What went wrong: Execution failed for task &#8216;:app:processDebugManifest&#8217;. > Manifest merger failed : uses-sdk:minSdkVersion 16 cannot be smaller than version 18 declared in library [:flutter_ble_lib] E:\\study\\flutter\\ble_example\\build\\flutter_ble_lib\\intermediates\\library_manifest\\debug\\AndroidManifest.xml as the library might be using APIs not available in 16 Suggestion: use a compatible library with a minSdk of at most 16, or increase this project&#8217;s minSdk version to at least 18, or use tools:overrideLibrary=&#8221;com.polidea.flutter_ble_lib&#8221; to force usage (may lead to runtime failures) * Try: Run with &#8211;stacktrace option to get the stack trace. Run with &#8211;info or &#8211;debug option to get more log output. Run with &#8211;scan to get full insights. * Get more help at https:\/\/help.gradle.org BUILD FAILED in 1m 3s Exception: Gradle task assembleDebug failed with [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"ngg_post_thumbnail":0,"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[41],"tags":[],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5q9Zn-kh","jetpack-related-posts":[{"id":1266,"url":"https:\/\/blog.box.kr\/?p=1266","url_meta":{"origin":1257,"position":0},"title":"QR \ucf54\ub4dc \uc2a4\uce94(QR Code Scan) \ucd08\uac04\ub2e8 \uc608\uc81c(Simple example)","date":"2021-05-18","format":false,"excerpt":"https:\/\/pub.dev\/packages \uc5d0\uc11c qrscan \uac80\uc0c9 AndroidManifest.xml \ud37c\ubbf8\uc158 \ucd94\uac00 \uc704\uce58 : project\/android\/app\/src\/main\/AndroidManifext.xml \uc548\ub4dc\ub85c\uc774\ub4dc\uc758 \uce74\uba54\ub77c\uc640 \uc800\uc7a5\uc18c \uc81c\uc5b4\ub97c \uc704\ud55c \ud37c\ubbf8\uc158\uc744 \ucd94\uac00\ud574 \uc900\ub2e4. \uc2e4\uc81c \uc6b0\ub9ac\uac00 \ud14c\uc2a4\ud2b8\ud558\ub294 \ucf54\ub4dc\uc5d0\ub294 \uad73\uc774 \uc800\uc7a5\uc18c \uad00\ub828\uc740 \ud544\uc694 \uc5c6\uc9c0\ub9cc qrscan \ud328\ud0a4\uc9c0 \ub0b4\uc5d0\uc11c \ubaa8\ub450 \uc0ac\uc6a9\ud558\ub2c8 \uc5b4\uca54 \uc218 \uc5c6\ub2e4. <uses-permission android:name=\"android.permission.CAMERA\" \/> <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"\/> <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"\/> import 'dart:async'; import 'package:flutter\/material.dart'; import 'package:qrscan\/qrscan.dart' as scanner;\u2026","rel":"","context":"In &quot;flutter&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1239,"url":"https:\/\/blog.box.kr\/?p=1239","url_meta":{"origin":1257,"position":1},"title":"Flutter \uc0ac\uc6a9 \uc815\ub9ac","date":"2021-05-14","format":false,"excerpt":"OSX, Windows, Linux, Web\uc5d0\uc11c \uc0ac\uc6a9\ud558\uae30 \uc704\ud574\uc11c\ub294 \uac01 \uae30\ub2a5\uc744 \ucf1c\uc918\uc57c\ud568. Flutter\ub85c \ub370\uc2a4\ud06c\ud1b1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uac1c\ubc1c \uc2dc\uc791\ud558\uae30 \uc77c\ud68c\uc131 \uad6c\uc131 \ubcc0\uacbd\uc73c\ub85c \ub370\uc2a4\ud06c\ud1b1 \uc9c0\uc6d0\uc744 \uad6c\uc131\ud574\uc57c\ud569\ub2c8\ub2e4.$ flutter config --enable-windows-desktop # for the Windows runner$ flutter config --enable-macos-desktop \u00a0 # for the macOS runner$ flutter config --enable-linux-desktop \u00a0 # for the Linux runner \ub370\uc2a4\ud06c\ud1b1 \uc6a9 Flutter\uac00 \ud65c\uc131\ud654\ub418\uc5c8\ub294\uc9c0\u2026","rel":"","context":"In &quot;flutter&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":899,"url":"https:\/\/blog.box.kr\/?p=899","url_meta":{"origin":1257,"position":2},"title":"Cassandra cpp driver install","date":"2015-06-16","format":false,"excerpt":"http:\/\/datastax.github.io\/cpp-driver\/topics\/building\/ \u00a0 Building Supported Platforms The driver is known to work on CentOS\/RHEL 5\/6\/7, Mac OS X 10.8\/10.9 (Mavericks and Yosemite), Ubuntu 12.04\/14.04 LTS, and Windows 7 SP1. It has been built using GCC 4.1.2+, Clang 3.4+, and MSVC 2010\/2012\/2013. Dependencies Driver CMake libuv (1.x or 0.10.x) OpenSSL (optional) NOTE:\u2026","rel":"","context":"In &quot;\uae30\uc220&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":953,"url":"https:\/\/blog.box.kr\/?p=953","url_meta":{"origin":1257,"position":3},"title":"How to install openssl on windows with visual studio 2015","date":"2015-08-26","format":false,"excerpt":"cite from\u00a0http:\/\/developer.covenanteyes.com\/building-openssl-for-visual-studio\/ and some edit.. ================================================== \u00a0 You need to install\u2026 Visual Studio 2015 (this will likely work with older versions as well) ActivePerl 1 Latest version of OpenSSL source-code 2\u00a0or $ git clone git:\/\/git.openssl.org\/openssl.git $ cd openssl $ git config core.autocrlf false $ git config core.eol lf $ git\u2026","rel":"","context":"In &quot;\uae30\uc220&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":883,"url":"https:\/\/blog.box.kr\/?p=883","url_meta":{"origin":1257,"position":4},"title":"how to make debug build on cmake","date":"2015-06-10","format":false,"excerpt":"cmake -DCMAKE_BUILD_TYPE:STRING=Debug \u00a0","rel":"","context":"In &quot;cmake\/make&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":541,"url":"https:\/\/blog.box.kr\/?p=541","url_meta":{"origin":1257,"position":5},"title":"[\uc624\ub958\ub300\ucc98]Unity3D Android Build Error WIN32 Exception ZipAlign","date":"2015-01-06","format":false,"excerpt":"Unity3D\uc5d0\uc11c Android Build \ud560\ub54c \uc624\ub958..\ub0b4\uc5ed Error building Player: Win32Exception: ApplicationName='...\/...\/...\/...\/adt-bundle-mac-x86_64-20140624\/sdk\/tools\/zipalign', CommandLine='4\"\/...\/...\/...\/...\/Asteroid2(2)\/Temp\/StagingArea\/Package.apk'\". CurrentDirectory='Temp\/StagingArea' \u00a0 \ud574\uacb0\ucc45.. Find your copy of the Android SDK in explorer Go to build-tools and choose a version (e.g.build-tools19.1.0) Copy zipalign.exe Come back out of build-tools Go into tools Paste zipalign.exe","rel":"","context":"In &quot;UNITY3D\/COCOS2D&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/posts\/1257"}],"collection":[{"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.box.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1257"}],"version-history":[{"count":1,"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/posts\/1257\/revisions"}],"predecessor-version":[{"id":1261,"href":"https:\/\/blog.box.kr\/index.php?rest_route=\/wp\/v2\/posts\/1257\/revisions\/1261"}],"wp:attachment":[{"href":"https:\/\/blog.box.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1257"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.box.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1257"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.box.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}