From 6ca487e3e076abb80cb6b1ce7c680c6cd59e28ee Mon Sep 17 00:00:00 2001 From: csf Date: Sun, 23 Jan 2022 21:37:19 +0800 Subject: [PATCH] add server page --- android_doc.md | 9 ++ lib/home_page.dart | 29 ++---- lib/main.dart | 4 + lib/server_page.dart | 218 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 238 insertions(+), 22 deletions(-) create mode 100644 lib/server_page.dart diff --git a/android_doc.md b/android_doc.md index a809c8a9d..96a18f438 100644 --- a/android_doc.md +++ b/android_doc.md @@ -97,6 +97,15 @@ MediaProjectionManager -> MediaProjection
+### 3.获取音频输入 +https://developer.android.google.cn/guide/topics/media/playback-capture?hl=zh-cn + +目前谷歌只开放了Android10系统同步音频内录功能 +10之前录音的时候会截取原本系统的音频输出 +即 开启内录时候无法在手机上正常使用耳机扬声器输出 + +
+ ### 其他 - Kotlin 与 compose 版本设置问题 - https://stackoverflow.com/questions/67600344/jetpack-compose-on-kotlin-1-5-0 diff --git a/lib/home_page.dart b/lib/home_page.dart index 8d5cde352..dcb858510 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -22,7 +22,6 @@ class HomePage extends StatefulWidget { class _HomePageState extends State { final _idController = TextEditingController(); var _updateUrl = ''; - static const toAndroidChannel = MethodChannel("mChannel"); @override void initState() { @@ -55,15 +54,21 @@ class _HomePageState extends State { items: [ PopupMenuItem( child: Text(translate('ID Server')), + value: 'id_server'), + PopupMenuItem( + child: Text(translate('Share My Screen')), value: 'server'), + // TODO only android PopupMenuItem( child: Text(translate('About') + ' RustDesk'), value: 'about'), ], elevation: 8, ); - if (value == 'server') { + if (value == 'id_server') { showServer(context); + } else if (value == 'server') { + Navigator.pushNamed(context, "server_page"); } else if (value == 'about') { showAbout(context); } @@ -98,29 +103,9 @@ class _HomePageState extends State { fontWeight: FontWeight.bold)))), getSearchBarUI(), getPeers(), - ElevatedButton(onPressed:_toAndroidGetPer, child: Text("获取权限事件")), - ElevatedButton(onPressed:_toAndroidStartSer, child: Text("开启录屏服务")), - ElevatedButton(onPressed:_toAndroidStopSer, child: Text("停止录屏服务")), - ElevatedButton(onPressed:_toAndroidCheckInput, child: Text("检查输入权限")), ]), )); } - Future _toAndroidGetPer() async{ - bool res = await toAndroidChannel.invokeMethod("getPer"); - debugPrint("_toAndroidGetPer:$res"); - } - Future _toAndroidStartSer() async{ - bool res = await toAndroidChannel.invokeMethod("startSer"); - debugPrint("_toAndroidStartSer:$res"); - } - Future _toAndroidStopSer() async{ - bool res = await toAndroidChannel.invokeMethod("stopSer"); - debugPrint("_toAndroidStopSer:$res"); - } - Future _toAndroidCheckInput() async{ - bool res = await toAndroidChannel.invokeMethod("checkInput"); - debugPrint("_toAndroidStopSer:$res"); -} void onConnect() { var id = _idController.text.trim(); diff --git a/lib/main.dart b/lib/main.dart index c16780ca2..62abe4b25 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_hbb/server_page.dart'; import 'package:provider/provider.dart'; import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:firebase_analytics/observer.dart'; @@ -31,6 +32,9 @@ class App extends StatelessWidget { visualDensity: VisualDensity.adaptivePlatformDensity, ), home: HomePage(title: 'RustDesk'), + routes: { + "server_page":(context) => ServerPage(), + }, navigatorObservers: [ FirebaseAnalyticsObserver(analytics: analytics), ], diff --git a/lib/server_page.dart b/lib/server_page.dart new file mode 100644 index 000000000..7e76874b8 --- /dev/null +++ b/lib/server_page.dart @@ -0,0 +1,218 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_hbb/model.dart'; + +import 'common.dart'; + +class ServerPage extends StatefulWidget { + @override + _ServerPageState createState() => _ServerPageState(); +} + +class _ServerPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: MyTheme.grayBg, + appBar: AppBar( + centerTitle: true, + title: const Text("Share My Screen"), + ), + body: SingleChildScrollView( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + ServerInfo(), + PermissionChecker(), + ], + ), + ), + )); + } +} + +class ServerInfo extends StatefulWidget { + @override + _ServerInfoState createState() => _ServerInfoState(); +} + +class _ServerInfoState extends State { + var _passwdShow = true; + + // TODO set ID / PASSWORD + var _serverId = ""; + var _serverPasswd = ""; + + @override + void initState() { + super.initState(); + _serverId = FFI.getByName("server_id"); + _serverPasswd = FFI.getByName("server_password"); + } + + @override + Widget build(BuildContext context) { + return myCard(Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextFormField( + readOnly: true, + style: TextStyle( + fontSize: 25.0, + fontWeight: FontWeight.bold, + color: MyTheme.accent), + initialValue: _serverId, + decoration: InputDecoration( + icon: const Icon(Icons.perm_identity), + labelText: '服务ID', + labelStyle: + TextStyle(fontWeight: FontWeight.bold, color: MyTheme.accent50), + ), + onSaved: (String value) {}, + ), + TextFormField( + readOnly: true, + obscureText: _passwdShow, + style: TextStyle( + fontSize: 25.0, + fontWeight: FontWeight.bold, + color: MyTheme.accent), + initialValue: _serverPasswd, + decoration: InputDecoration( + icon: const Icon(Icons.lock), + labelText: '密码', + labelStyle: TextStyle( + fontWeight: FontWeight.bold, color: MyTheme.accent50), + suffix: IconButton( + icon: Icon(Icons.visibility), + onPressed: () { + debugPrint("icon btn"); + setState(() { + _passwdShow = !_passwdShow; + }); + })), + onSaved: (String value) {}, + ), + ], + )); + } +} + +class PermissionChecker extends StatefulWidget { + @override + _PermissionCheckerState createState() => _PermissionCheckerState(); +} + +class _PermissionCheckerState extends State { + static const toAndroidChannel = MethodChannel("mChannel"); + + var videoOk = false; + var inputOk = false; + var audioOk = false; + + @override + Widget build(BuildContext context) { + return myCard(Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + cardTitle("权限列表"), + PermissionRow("视频权限", videoOk, _toAndroidGetPer), + const Divider(height: 0), + PermissionRow("音频权限", videoOk, () => {debugPrint("获取视频权限")}), + const Divider(height: 0), + PermissionRow("输入权限", inputOk, _toAndroidCheckInput), + const Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + TextButton.icon( + icon: Icon(Icons.play_arrow), + onPressed: _toAndroidStartSer, + label: Text("Start")), + TextButton.icon( + icon: Icon(Icons.stop), + onPressed: _toAndroidStopSer, + label: Text("Stop")), + ], + ) + ], + )); + } + + Future _toAndroidGetPer() async { + bool res = await toAndroidChannel.invokeMethod("getPer"); + debugPrint("_toAndroidGetPer:$res"); + } + + Future _toAndroidStartSer() async { + bool res = await toAndroidChannel.invokeMethod("startSer"); + debugPrint("_toAndroidStartSer:$res"); + } + + Future _toAndroidStopSer() async { + bool res = await toAndroidChannel.invokeMethod("stopSer"); + debugPrint("_toAndroidStopSer:$res"); + } + + Future _toAndroidCheckInput() async { + bool res = await toAndroidChannel.invokeMethod("checkInput"); + debugPrint("_toAndroidStopSer:$res"); + } +} + +class PermissionRow extends StatelessWidget { + PermissionRow(this.name, this.isOk, this.onPressed); + + final String name; + final bool isOk; + final VoidCallback onPressed; + + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text.rich(TextSpan(children: [ + TextSpan( + text: name + ":", + style: TextStyle(fontSize: 16.0, color: MyTheme.accent50)), + TextSpan( + text: isOk ? "已开启" : "未开启", + style: TextStyle( + fontSize: 16.0, color: isOk ? Colors.green : Colors.red)), + ])), + TextButton( + onPressed: onPressed, + child: const Text( + "去开启", + style: TextStyle(fontWeight: FontWeight.bold), + )), + ], + ); + } +} + +Widget cardTitle(String text) { + return Padding( + padding: EdgeInsets.symmetric(vertical: 5.0), + child: Text( + text, + style: TextStyle( + fontFamily: 'WorkSans', + fontWeight: FontWeight.bold, + fontSize: 25, + color: Color(0xFF00B6F0), + ), + )); +} + +Widget myCard(Widget child) { + return Card( + margin: EdgeInsets.all(15.0), + child: Padding( + padding: EdgeInsets.symmetric(vertical: 15.0, horizontal: 30.0), + child: child, + ), + ); +}