add server page

This commit is contained in:
csf 2022-01-23 21:37:19 +08:00
parent 39f7835df1
commit 6ca487e3e0
4 changed files with 238 additions and 22 deletions

View File

@ -97,6 +97,15 @@ MediaProjectionManager -> MediaProjection
<hr>
### 3.获取音频输入
https://developer.android.google.cn/guide/topics/media/playback-capture?hl=zh-cn
目前谷歌只开放了Android10系统同步音频内录功能
10之前录音的时候会截取原本系统的音频输出
即 开启内录时候无法在手机上正常使用耳机扬声器输出
<hr>
### 其他
- Kotlin 与 compose 版本设置问题
- https://stackoverflow.com/questions/67600344/jetpack-compose-on-kotlin-1-5-0

View File

@ -22,7 +22,6 @@ class HomePage extends StatefulWidget {
class _HomePageState extends State<HomePage> {
final _idController = TextEditingController();
var _updateUrl = '';
static const toAndroidChannel = MethodChannel("mChannel");
@override
void initState() {
@ -55,15 +54,21 @@ class _HomePageState extends State<HomePage> {
items: [
PopupMenuItem<String>(
child: Text(translate('ID Server')),
value: 'id_server'),
PopupMenuItem<String>(
child: Text(translate('Share My Screen')),
value: 'server'),
// TODO only android
PopupMenuItem<String>(
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<HomePage> {
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<Null> _toAndroidGetPer() async{
bool res = await toAndroidChannel.invokeMethod("getPer");
debugPrint("_toAndroidGetPer:$res");
}
Future<Null> _toAndroidStartSer() async{
bool res = await toAndroidChannel.invokeMethod("startSer");
debugPrint("_toAndroidStartSer:$res");
}
Future<Null> _toAndroidStopSer() async{
bool res = await toAndroidChannel.invokeMethod("stopSer");
debugPrint("_toAndroidStopSer:$res");
}
Future<Null> _toAndroidCheckInput() async{
bool res = await toAndroidChannel.invokeMethod("checkInput");
debugPrint("_toAndroidStopSer:$res");
}
void onConnect() {
var id = _idController.text.trim();

View File

@ -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),
],

218
lib/server_page.dart Normal file
View File

@ -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<ServerPage> {
@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<ServerInfo> {
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<PermissionChecker> {
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<Null> _toAndroidGetPer() async {
bool res = await toAndroidChannel.invokeMethod("getPer");
debugPrint("_toAndroidGetPer:$res");
}
Future<Null> _toAndroidStartSer() async {
bool res = await toAndroidChannel.invokeMethod("startSer");
debugPrint("_toAndroidStartSer:$res");
}
Future<Null> _toAndroidStopSer() async {
bool res = await toAndroidChannel.invokeMethod("stopSer");
debugPrint("_toAndroidStopSer:$res");
}
Future<Null> _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,
),
);
}