fix bluetooth device enumerate. (#281)
* fix bluetooth device enumerate. * update README.md * dart format. * revert pubspec.yaml. * fix analyzer.
This commit is contained in:
@@ -117,11 +117,36 @@ We require a set of permissions that need to be declared in your `AppManifest.xm
|
|||||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
|
||||||
...
|
...
|
||||||
</manifest>
|
</manifest>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For using the bluetooth headset correctly on the android device, you need to add `permission_handler` to your project.
|
||||||
|
And call the following code after launching your app for the first time.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
|
Future<void> _checkPremissions() async {
|
||||||
|
var status = await Permission.bluetooth.request();
|
||||||
|
if (status.isPermanentlyDenied) {
|
||||||
|
print('Bluetooth Permission disabled');
|
||||||
|
}
|
||||||
|
status = await Permission.bluetoothConnect.request();
|
||||||
|
if (status.isPermanentlyDenied) {
|
||||||
|
print('Bluetooth Connect Permission disabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() async {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
await _checkPremissions();
|
||||||
|
runApp(MyApp());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Desktop support
|
### Desktop support
|
||||||
|
|
||||||
In order to enable Flutter desktop development, please follow [instructions here](https://docs.flutter.dev/desktop#set-up).
|
In order to enable Flutter desktop development, please follow [instructions here](https://docs.flutter.dev/desktop#set-up).
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ analyzer:
|
|||||||
# https://dash-overflow.net/articles/getting_started/#step-3-disabling-_implicit-dynamic_--_implicit-cast_
|
# https://dash-overflow.net/articles/getting_started/#step-3-disabling-_implicit-dynamic_--_implicit-cast_
|
||||||
#
|
#
|
||||||
strong-mode:
|
strong-mode:
|
||||||
implicit-casts: false
|
|
||||||
implicit-dynamic: false
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# exclude protobuf files
|
# exclude protobuf files
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ analyzer:
|
|||||||
# https://dash-overflow.net/articles/getting_started/#step-3-disabling-_implicit-dynamic_--_implicit-cast_
|
# https://dash-overflow.net/articles/getting_started/#step-3-disabling-_implicit-dynamic_--_implicit-cast_
|
||||||
#
|
#
|
||||||
strong-mode:
|
strong-mode:
|
||||||
implicit-casts: false
|
|
||||||
implicit-dynamic: false
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# exclude protobuf files
|
# exclude protobuf files
|
||||||
@@ -44,3 +42,5 @@ linter:
|
|||||||
# Turn off avoid_print for example projects
|
# Turn off avoid_print for example projects
|
||||||
#
|
#
|
||||||
avoid_print: false
|
avoid_print: false
|
||||||
|
depend_on_referenced_packages: false
|
||||||
|
use_build_context_synchronously: false
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:flutter_svg/flutter_svg.dart';
|
|||||||
import 'package:livekit_client/livekit_client.dart';
|
import 'package:livekit_client/livekit_client.dart';
|
||||||
import 'package:livekit_example/widgets/text_field.dart';
|
import 'package:livekit_example/widgets/text_field.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
import '../exts.dart';
|
import '../exts.dart';
|
||||||
import 'room.dart';
|
import 'room.dart';
|
||||||
@@ -42,6 +43,9 @@ class _ConnectPageState extends State<ConnectPage> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_readPrefs();
|
_readPrefs();
|
||||||
|
if (lkPlatformIs(PlatformType.android)) {
|
||||||
|
_checkPremissions();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -51,6 +55,28 @@ class _ConnectPageState extends State<ConnectPage> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _checkPremissions() async {
|
||||||
|
var status = await Permission.bluetooth.request();
|
||||||
|
if (status.isPermanentlyDenied) {
|
||||||
|
print('Bluetooth Permission disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
status = await Permission.bluetoothConnect.request();
|
||||||
|
if (status.isPermanentlyDenied) {
|
||||||
|
print('Bluetooth Connect Permission disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
status = await Permission.camera.request();
|
||||||
|
if (status.isPermanentlyDenied) {
|
||||||
|
print('Camera Permission disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
status = await Permission.microphone.request();
|
||||||
|
if (status.isPermanentlyDenied) {
|
||||||
|
print('Microphone Permission disabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Read saved URL and Token
|
// Read saved URL and Token
|
||||||
Future<void> _readPrefs() async {
|
Future<void> _readPrefs() async {
|
||||||
final prefs = await SharedPreferences.getInstance();
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
|||||||
@@ -276,6 +276,7 @@ class _ControlsWidgetState extends State<ControlsWidget> {
|
|||||||
return [
|
return [
|
||||||
PopupMenuItem<MediaDevice>(
|
PopupMenuItem<MediaDevice>(
|
||||||
value: null,
|
value: null,
|
||||||
|
onTap: isMuted ? _enableAudio : _disableAudio,
|
||||||
child: const ListTile(
|
child: const ListTile(
|
||||||
leading: Icon(
|
leading: Icon(
|
||||||
EvaIcons.micOff,
|
EvaIcons.micOff,
|
||||||
@@ -283,7 +284,6 @@ class _ControlsWidgetState extends State<ControlsWidget> {
|
|||||||
),
|
),
|
||||||
title: Text('Mute Microphone'),
|
title: Text('Mute Microphone'),
|
||||||
),
|
),
|
||||||
onTap: isMuted ? _enableAudio : _disableAudio,
|
|
||||||
),
|
),
|
||||||
if (_audioInputs != null)
|
if (_audioInputs != null)
|
||||||
..._audioInputs!.map((device) {
|
..._audioInputs!.map((device) {
|
||||||
@@ -358,6 +358,7 @@ class _ControlsWidgetState extends State<ControlsWidget> {
|
|||||||
return [
|
return [
|
||||||
PopupMenuItem<MediaDevice>(
|
PopupMenuItem<MediaDevice>(
|
||||||
value: null,
|
value: null,
|
||||||
|
onTap: _disableVideo,
|
||||||
child: const ListTile(
|
child: const ListTile(
|
||||||
leading: Icon(
|
leading: Icon(
|
||||||
EvaIcons.videoOff,
|
EvaIcons.videoOff,
|
||||||
@@ -365,7 +366,6 @@ class _ControlsWidgetState extends State<ControlsWidget> {
|
|||||||
),
|
),
|
||||||
title: Text('Disable Camera'),
|
title: Text('Disable Camera'),
|
||||||
),
|
),
|
||||||
onTap: _disableVideo,
|
|
||||||
),
|
),
|
||||||
if (_videoInputs != null)
|
if (_videoInputs != null)
|
||||||
..._videoInputs!.map((device) {
|
..._videoInputs!.map((device) {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ dependencies:
|
|||||||
|
|
||||||
intl: ^0.17.0
|
intl: ^0.17.0
|
||||||
flutter_background: ^1.1.0
|
flutter_background: ^1.1.0
|
||||||
|
permission_handler: ^10.2.0
|
||||||
provider: ^6.0.1
|
provider: ^6.0.1
|
||||||
logging: ^1.0.1
|
logging: ^1.0.1
|
||||||
shared_preferences: ^2.0.7
|
shared_preferences: ^2.0.7
|
||||||
|
|||||||
Reference in New Issue
Block a user