Bluetooth e mapa a funcionar

This commit is contained in:
2026-03-06 11:46:17 +00:00
parent 05f54e6a37
commit 6b1d4b8cea
3 changed files with 67 additions and 31 deletions

View File

@@ -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"/>

View File

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

View File

@@ -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: