Flutter插件cortex的使用_cortex一个用于访问Cortex库并操作Emotiv EEG头戴设备的Flutter插件

Flutter插件cortex的使用_cortex一个用于访问Cortex库并操作Emotiv EEG头戴设备的Flutter插件

cortex介绍

cortex是一个用于访问Cortex库并操作Emotiv EEG头戴设备的Flutter插件。

平台支持

Android iOS MacOS Web Linux Windows
✔️ ✔️

Flutter插件cortex使用方法

要使用此插件,在pubspec.yaml文件中添加cortex作为依赖项。

该插件通过三个不同的流暴露了Cortex事件:

  • ResponseEvent 描述了每个请求的Cortex响应。
  • WarningEvent 描述了来自Cortex的警告消息。
  • DataStreamEvent 描述了订阅数据(如EEG、运动等)时的数据流事件。

这些事件分别通过以下BroadcastStream暴露出来:

  • responseEvents
  • warningEvents
  • dataStreamEvents

此外,该插件还提供了四个函数来与Cortex进行交互:

  • startCortex 将启动Cortex。
  • authenticateWithCortex(clientId) 将打开一个webview供用户登录,并从Emotiv后端服务器获取认证码。
  • sendRequestToCortex 将以JSON格式向Cortex发送请求。
  • stopCortex 在应用终止时在Java层实现,但我们未将其导出到Dart层。

示例

import 'package:cortex/cortex.dart';

responseEvents.listen((event) {
  print(event);
});

warningEvents.listen((event) {
  print(event);
});

dataStreamEvents.listen((event) {
  print(event);
});

// 发送查询头戴设备的请求
sendRequestToCortex('{ "id": 1, "jsonrpc": "2.0", "method": "queryHeadsets"}');

另外,请参阅example子目录中的示例应用程序,该程序使用真实设备进行操作。请记得添加以下内容:

  • EmotivCortexLib.aar 到您的主项目中(Android构建)
  • EmotivCortexLib.xcframework 到iOS插件的Frameworks文件夹中(iOS构建)

注意事项

嵌入的Cortex库(对于Android为EmotivCortexLib.aar,对于iOS为EmotivCortexLib.xcframework)目前仅处于私人测试阶段,未来将发布正式版本。

完整示例Demo

以下是一个完整的示例Demo,展示了如何使用cortex插件与Emotiv EEG头戴设备进行交互。

import 'dart:io';

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:cortex/cortex.dart';
import 'package:permission_handler/permission_handler.dart';
import 'src/constant.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class Headset {
  String headsetId;
  bool isVirtual;
  String status;

  Headset(this.headsetId, this.isVirtual, this.status);

  void setHeadsetStatus(String status) {
    this.status = status;
  }
}

class _MyAppState extends State<MyApp> {
  final _streamSubscriptions = <StreamSubscription<dynamic>>[];
  late String _userName;
  late final String _cortexToken;
  late String _sessionId;
  late String _activeHeadset;

  [@override](/user/override)
  void initState() {
    super.initState();
    callCortexStart();
    _streamSubscriptions.add(
      responseEvents.listen(
        (event) {
          print(event);
          switch (event.getRequestId()) {
            case Constant.authorizeRequestId:
              // 获取Cortex令牌并保存到变量
              var data = event.getResponseBody() as Map<String, dynamic>;
              _cortexToken = data["cortexToken"];
              print("Cortex token: $_cortexToken");
              break;
            case Constant.queryHeadsetRequestId:
              var data = event.getResponseBody();
              List<Headset> headset = [];
              for (var element in data) {
                Headset h = Headset(
                    element["id"], element["isVirtual"], element["status"]);
                headset.add(h);
              }
              setState(() {
                _headsetList = headset;
              });
              break;
            case Constant.createSessionRequestId:
              var data = event.getResponseBody();
              _sessionId = data["id"];
              break;
            case Constant.getUserLoggedInRequestId:
              var data = event.getResponseBody();
              if(data.length != 0)
              {
                _userName = data[0]["username"] as String;
              }
              break;
            case Constant.loginRequestId:
              if(!event.isResponseError())
              {
                _userName = event.getResponseBody()["username"];
                print("User logged in: $_userName");
              }
              break;
            case Constant.logoutRequestId:
              if(!event.isResponseError())
              {
                _userName = "";
              }
              break;
            default:
              break;
          }
        },
      ),
    );
    _streamSubscriptions.add(warningEvents.listen((event) {
      if (event.getWarningCode() == Constant.headsetIsConnected) {
        // 查询头戴设备以更新状态
        var data = event.getWarningMessage();
        _activeHeadset = data["headsetId"];
        _queryHeadset();
      }
    }));
    _streamSubscriptions.add(dataStreamEvents.listen((event) {
      print("Data Stream Event: ${event.getDataStreamBody()}");
    }));
  }

  [@override](/user/override)
  void dispose() {
    super.dispose();
    for (final subscription in _streamSubscriptions) {
      subscription.cancel();
    }
  }

  Future<void> callCortexStart() async {
    bool result;
    try {
      if (Platform.isAndroid) {
        Map<Permission, PermissionStatus> statuses =
            await [Permission.location].request();
        print(statuses[Permission.location]);
      }
      result = await startCortex();
      print("Call cortex start: $result");
    } on Exception {
      print("Something wrong");
    }
  }

  void _queryHeadset() {
    sendRequestToCortex(
        '{ "id": ${Constant.queryHeadsetRequestId}, "jsonrpc": "2.0", "method": "queryHeadsets"}');
  }

  void _login() async {
    String code = await authenticateWithCortex(Constant.clientId);
    print("AuthenCode: $code");
    if (code.isNotEmpty) {
      String json = ''' { 
        "jsonrpc": "2.0",
        "id": ${Constant.loginRequestId},
        "method": "loginWithAuthenticationCode",
        "params": {
          "clientId": "${Constant.clientId}",
          "clientSecret": "${Constant.clientSecret}",
          "code": "$code"
          } 
        } ''';
      sendRequestToCortex(json);
    }
  }

  void _logout() async {
    String json = ''' { 
        "jsonrpc": "2.0",
        "id": ${Constant.logoutRequestId},
        "method": "logout",
        "params": {
          "username": "$_userName"
          } 
        } ''';
    sendRequestToCortex(json);
  }

  void _authorize() {
    //// 许可字段是可选的
    String json = ''' { 
        "jsonrpc": "2.0",
        "id": ${Constant.authorizeRequestId},
        "method": "authorize",
        "params": {
          "clientId": "${Constant.clientId}",
          "clientSecret": "${Constant.clientSecret}",
          "debit": ${Constant.debitNumber},
          "license": "${Constant.licenseId}"
          } 
        } ''';
    sendRequestToCortex(json);
  }

  void _getUserInfo() {
    String json = ''' { 
        "jsonrpc": "2.0",
        "id": ${Constant.getUserInfoRequestId},
        "method": "getUserInformation",
        "params": {
          "cortexToken": "$_cortexToken"
          } 
        } ''';
    sendRequestToCortex(json);
  }

  void _getLicenseInfo() {
    String json = ''' { 
        "jsonrpc": "2.0",
        "id": ${Constant.getLicenseInfoRequestId},
        "method": "getLicenseInfo",
        "params": {
          "cortexToken": "$_cortexToken"
          } 
        } ''';
    sendRequestToCortex(json);
  }

  void _createSession() {
    String json = ''' { 
        "jsonrpc": "2.0",
        "id": ${Constant.createSessionRequestId},
        "method": "createSession",
        "params": {
          "cortexToken": "$_cortexToken",
          "headset": "$_activeHeadset",
          "status": "active"
          } 
        } ''';
    sendRequestToCortex(json);
  }

  void _subscribeData() {
    String json = ''' { 
        "jsonrpc": "2.0",
        "id": ${Constant.subscribeDataRequestId},
        "method": "subscribe",
        "params": {
          "cortexToken": "$_cortexToken",
          "session": "$_sessionId",
          "streams": ["eeg"]
          } 
        } ''';
    sendRequestToCortex(json);
  }

  void _unsubscribeData() {
    String json = ''' { 
        "jsonrpc": "2.0",
        "id": ${Constant.subscribeDataRequestId},
        "method": "unsubscribe",
        "params": {
          "cortexToken": "$_cortexToken",
          "session": "$_sessionId",
          "streams": ["eeg"]
          } 
        } ''';
    sendRequestToCortex(json);
  }

  void _closeSession() {
    String json = ''' { 
        "jsonrpc": "2.0",
        "id": ${Constant.updateSessionRequestId},
        "method": "updateSession",
        "params": {
          "cortexToken": "$_cortexToken",
          "session": "$_sessionId",
          "status": "close"
          } 
        } ''';
    sendRequestToCortex(json);
  }

  List<Headset> _headsetList = [];

  DataRow _getDataRow(Headset result) {
    return DataRow(
        cells: [
          DataCell(Text(result.headsetId)),
          DataCell(Text(result.isVirtual.toString())),
          DataCell(Text(result.status)),
        ],
        onSelectChanged: (bool? selected) {
          if (selected != null && selected) {
            sendRequestToCortex('''
              { "id": ${Constant.controlDeviceRequestId}, 
              "jsonrpc": "2.0", 
              "method": "controlDevice",
              "params": {
                "command": "connect",
                "headset": "${result.headsetId}"
              }
              }
              ''');
          }
        },
        onLongPress: () {
          sendRequestToCortex('''
              { "id": ${Constant.controlDeviceRequestId}, 
              "jsonrpc": "2.0", 
              "method": "controlDevice",
              "params": {
                "command": "disconnect",
                "headset": "${result.headsetId}"
              }
              }
              ''');
        });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Center(
            child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            DataTable(
              showCheckboxColumn: false,
              horizontalMargin: 5,
              dataTextStyle: const TextStyle(fontSize: 12, color: Colors.black),
              columns: const [
                DataColumn(label: Text('HeadsetId')),
                DataColumn(label: Text('isVirtualHeadset')),
                DataColumn(label: Text('Status')),
              ],
              rows: List.generate(_headsetList.length,
                  (index) => _getDataRow(_headsetList[index])),
            ),
            const SizedBox(height: 100.0),
            TextButton(
                onPressed: () => sendRequestToCortex(
                    '{ "id": ${Constant.getUserLoggedInRequestId}, "jsonrpc": "2.0", "method": "getUserLogin"}'),
                child: const Text("Get User Login")),
            const SizedBox(height: 5.0),
            TextButton(
              onPressed: _login,
              child: const Text("Login"),
            ),
            const SizedBox(
              height: 5.0,
            ),
            TextButton(
              onPressed: _logout,
              child: const Text("Logout"),
            ),
            const SizedBox(
              height: 5.0,
            ),
            TextButton(
              onPressed: _authorize,
              child: const Text("Authorize"),
            ),
            const SizedBox(
              height: 5.0,
            ),
            TextButton(
              onPressed: _getUserInfo,
              child: const Text("Get User Information"),
            ),
            const SizedBox(
              height: 5.0,
            ),
            TextButton(
              onPressed: _getLicenseInfo,
              child: const Text("Get License Information"),
            ),
            const SizedBox(
              height: 5.0,
            ),
            TextButton(
              onPressed: _queryHeadset,
              child: const Text("QueryHeadset"),
            ),
            const SizedBox(
              height: 5.0,
            ),
            TextButton(
              onPressed: _createSession,
              child: const Text("Create Session"),
            ),
            const SizedBox(
              height: 5.0,
            ),
            TextButton(
              onPressed: _subscribeData,
              child: const Text("Subscribe Data"),
            ),
            const SizedBox(
              height: 5.0,
            ),
            TextButton(
              onPressed: _unsubscribeData,
              child: const Text("Unsubscribe Data"),
            ),
            const SizedBox(
              height: 5.0,
            ),
            TextButton(
              onPressed: _closeSession,
              child: const Text("Close Session"),
            )
          ],
        )),
      ),
    );
  }
}

更多关于Flutter插件cortex的使用_cortex一个用于访问Cortex库并操作Emotiv EEG头戴设备的Flutter插件的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter插件cortex的使用_cortex一个用于访问Cortex库并操作Emotiv EEG头戴设备的Flutter插件的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于Flutter中的Cortex插件的使用,我可以为你提供一些相关的代码案例来展示其基本功能和用法。Cortex插件通常用于增强Flutter应用的性能和功能,尤其是在处理复杂的UI和数据处理任务时。不过,请注意,由于Cortex插件的具体实现和功能可能会随着版本更新而变化,以下代码仅作为示例,你可能需要根据实际使用的Cortex版本进行调整。

首先,确保你已经在pubspec.yaml文件中添加了Cortex插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  cortex: ^最新版本号  # 替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

以下是一个简单的示例,展示如何在Flutter应用中使用Cortex插件:

import 'package:flutter/material.dart';
import 'package:cortex/cortex.dart'; // 导入Cortex插件

void main() {
  // 初始化Cortex(如果需要)
  Cortex.initialize();

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Cortex Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: CortexDemoScreen(),
    );
  }
}

class CortexDemoScreen extends StatefulWidget {
  @override
  _CortexDemoScreenState createState() => _CortexDemoScreenState();
}

class _CortexDemoScreenState extends State<CortexDemoScreen> {
  String resultText = "";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Cortex Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Result:',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 10),
            Text(
              resultText,
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                // 使用Cortex进行某些操作(这里以一个简单的计算为例)
                // 注意:这里的代码是假设性的,因为Cortex的具体API未知
                // 你需要根据Cortex的实际API文档进行调整
                try {
                  // 假设Cortex有一个performComplexTask方法
                  var result = await Cortex.performComplexTask(parameters: {
                    'input': 42, // 示例输入
                  });

                  // 更新状态
                  setState(() {
                    resultText = 'Result: ${result?.toString() ?? 'null'}';
                  });
                } catch (e) {
                  // 处理错误
                  setState(() {
                    resultText = 'Error: ${e.toString()}';
                  });
                }
              },
              child: Text('Perform Cortex Task'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个按钮,点击按钮时会调用Cortex插件的某个假设方法(performComplexTask)。请注意,performComplexTask方法及其参数是假设性的,因为Cortex插件的实际API和功能未知。你需要根据Cortex插件的实际文档和API来调整这部分代码。

此外,Cortex插件可能提供了一些初始化、配置或清理的方法,这些都需要根据插件的文档进行适当调用。由于Cortex插件的具体实现细节未知,上述代码仅作为展示如何在Flutter应用中集成和使用插件的一个框架性示例。

为了获得更准确和具体的代码示例,请查阅Cortex插件的官方文档和示例代码。

回到顶部