Bluetooth e mapa a funcionar
This commit is contained in:
@@ -1,12 +1,23 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Bluetooth permissions for Android 12 (API 31) and higher -->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
||||
|
||||
<!-- Legacy Bluetooth permissions for Android 11 (API 30) and lower -->
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
|
||||
|
||||
<!-- Location permissions (required for Bluetooth scanning on older Android versions) -->
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:label="teste_projeto_turma"
|
||||
android:label="runvisionpro_app"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
<activity
|
||||
@@ -18,10 +29,6 @@
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
@@ -31,21 +38,13 @@
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
|
||||
<!-- TODO: Replace with your actual Google Maps API Key -->
|
||||
<meta-data android:name="com.google.android.geo.API_KEY"
|
||||
android:value="AIzaSyCk84rxmF044cxKLABf55rEKHDqOcyoV5k"/>
|
||||
</application>
|
||||
<!-- Required to query activities that can process text, see:
|
||||
https://developer.android.com/training/package-visibility and
|
||||
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
||||
|
||||
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
||||
|
||||
@@ -16,7 +16,7 @@ class BluetoothConnectionScreen extends StatefulWidget {
|
||||
class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
|
||||
List<ScanResult> _scanResults = [];
|
||||
bool _isScanning = false;
|
||||
BluetoothDevice? _connectedDevice; // Track connected device
|
||||
BluetoothDevice? _connectedDevice;
|
||||
late StreamSubscription<List<ScanResult>> _scanResultsSubscription;
|
||||
late StreamSubscription<bool> _isScanningSubscription;
|
||||
|
||||
@@ -27,7 +27,7 @@ class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
|
||||
_scanResultsSubscription = FlutterBluePlus.scanResults.listen((results) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
// FILTRO: Mantém apenas dispositivos que possuem um nome identificado
|
||||
// Filtra os dispositivos para mostrar apenas aqueles que possuem um nome identificado
|
||||
_scanResults = results.where((r) => r.device.platformName.isNotEmpty).toList();
|
||||
});
|
||||
}
|
||||
@@ -54,16 +54,30 @@ class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
|
||||
Map<Permission, PermissionStatus> statuses = await [
|
||||
Permission.bluetoothScan,
|
||||
Permission.bluetoothConnect,
|
||||
Permission.bluetoothAdvertise,
|
||||
Permission.location,
|
||||
].request();
|
||||
|
||||
if (statuses[Permission.bluetoothScan]!.isGranted &&
|
||||
statuses[Permission.bluetoothConnect]!.isGranted) {
|
||||
bool allGranted = true;
|
||||
if (statuses[Permission.bluetoothScan]?.isDenied ?? true) allGranted = false;
|
||||
if (statuses[Permission.bluetoothConnect]?.isDenied ?? true) allGranted = false;
|
||||
|
||||
final bool scanPermanentlyDenied = statuses[Permission.bluetoothScan]?.isPermanentlyDenied ?? false;
|
||||
final bool connectPermanentlyDenied = statuses[Permission.bluetoothConnect]?.isPermanentlyDenied ?? false;
|
||||
|
||||
if (scanPermanentlyDenied || connectPermanentlyDenied) {
|
||||
if (mounted) {
|
||||
_showSettingsDialog();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (allGranted) {
|
||||
_startScan();
|
||||
} else {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
const SnackBar(
|
||||
content: Text(AppStrings.permissionsDenied),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
),
|
||||
@@ -75,12 +89,35 @@ class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
void _showSettingsDialog() {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text("Permissões Necessárias"),
|
||||
content: const Text("As permissões de Bluetooth foram negadas permanentemente. Por favor, habilite-as nas configurações do sistema para continuar."),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: const Text("CANCELAR"),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
openAppSettings();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: const Text("CONFIGURAÇÕES"),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _startScan() async {
|
||||
try {
|
||||
if (await FlutterBluePlus.adapterState.first != BluetoothAdapterState.on) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
const SnackBar(
|
||||
content: Text(AppStrings.turnOnBluetooth),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
),
|
||||
@@ -89,7 +126,9 @@ class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
|
||||
return;
|
||||
}
|
||||
|
||||
await FlutterBluePlus.startScan(timeout: const Duration(seconds: 15));
|
||||
await FlutterBluePlus.startScan(
|
||||
timeout: const Duration(seconds: 15),
|
||||
);
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
@@ -135,7 +174,7 @@ class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
|
||||
});
|
||||
FlutterBluePlus.stopScan();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
const SnackBar(
|
||||
content: Text(AppStrings.connectedSuccess),
|
||||
backgroundColor: AppColors.success,
|
||||
behavior: SnackBarBehavior.floating,
|
||||
@@ -190,7 +229,6 @@ class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
|
||||
Column(
|
||||
children: [
|
||||
const SizedBox(height: 20),
|
||||
// Header Card
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 25),
|
||||
child: Container(
|
||||
@@ -282,7 +320,6 @@ class _BluetoothConnectionScreenState extends State<BluetoothConnectionScreen> {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
// Device List
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: _connectedDevice != null ? 1 : _scanResults.length,
|
||||
|
||||
16
pubspec.lock
16
pubspec.lock
@@ -37,10 +37,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
version: "1.4.1"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -388,18 +388,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.17"
|
||||
version: "0.12.19"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.1"
|
||||
version: "0.13.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -577,10 +577,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
||||
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.7"
|
||||
version: "0.7.10"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
Reference in New Issue
Block a user