open_device_settings 1.0.1
open_device_settings: ^1.0.1 copied to clipboard
A Flutter plugin to open system settings panels (WiFi, Bluetooth, NFC, Display, etc.) on Android, iOS, Windows, macOS, and Linux.
import 'package:flutter/material.dart';
import 'package:open_device_settings/open_device_settings.dart';
import 'package:open_device_settings/settings_panel.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Device Settings Panel Explorer',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF6750A4),
brightness: Brightness.light,
),
useMaterial3: true,
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF6750A4),
brightness: Brightness.dark,
),
useMaterial3: true,
),
home: const SettingsExplorerPage(),
);
}
}
class SettingsExplorerPage extends StatefulWidget {
const SettingsExplorerPage({super.key});
@override
State<SettingsExplorerPage> createState() => _SettingsExplorerPageState();
}
class _SettingsExplorerPageState extends State<SettingsExplorerPage> {
final Map<String, List<SettingsPanel>> _categories = {};
@override
void initState() {
super.initState();
_groupPanelsByCategory();
}
void _groupPanelsByCategory() {
for (var panel in SettingsPanel.values) {
final cat = panel.category;
if (!_categories.containsKey(cat)) {
_categories[cat] = [];
}
_categories[cat]!.add(panel);
}
}
// Retourne une icône adaptée à chaque catégorie
IconData _getCategoryIcon(String category) {
switch (category) {
case 'Network': return Icons.wifi_rounded;
case 'Display': return Icons.dark_mode_rounded;
case 'Sound': return Icons.volume_up_rounded;
case 'Apps': return Icons.apps_rounded;
case 'Security & Privacy': return Icons.lock_rounded;
case 'Battery & Power': return Icons.battery_charging_full_rounded;
case 'Accounts': return Icons.person_rounded;
case 'Hardware': return Icons.mouse_rounded;
case 'Family': return Icons.family_restroom_rounded;
default: return Icons.settings_rounded;
}
}
Future<void> _openPanel(SettingsPanel panel) async {
// Message de statut temporaire
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Opening ${panel.label}...'),
duration: const Duration(milliseconds: 600),
behavior: SnackBarBehavior.floating,
),
);
try {
await DeviceSettings.open(panel);
} catch (e) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Not supported or failed to open: ${panel.label}'),
backgroundColor: Theme.of(context).colorScheme.error,
behavior: SnackBarBehavior.floating,
),
);
}
}
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: const Text(
'Settings Explorer',
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 22),
),
centerTitle: true,
backgroundColor: theme.colorScheme.surfaceContainer,
elevation: 0,
actions: [
IconButton(
icon: const Icon(Icons.info_outline_rounded),
onPressed: () {
showAboutDialog(
context: context,
applicationName: 'Open Settings Panel',
applicationVersion: '1.0.1',
children: [
const Text('Test and explore native settings shortcuts on Android and Windows.'),
],
);
},
)
],
),
body: Container(
color: theme.colorScheme.surfaceContainerLow,
child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
children: _categories.keys.map((categoryName) {
final panels = _categories[categoryName]!;
return Card(
margin: const EdgeInsets.only(bottom: 14.0),
elevation: 0,
color: theme.colorScheme.surface,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
side: BorderSide(color: theme.colorScheme.outlineVariant.withAlpha(120)),
),
child: ExpansionTile(
initiallyExpanded: categoryName == 'Network', // Ouvre par défaut la première section
leading: Icon(_getCategoryIcon(categoryName), color: theme.colorScheme.primary),
title: Text(
categoryName,
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
),
subtitle: Text(
'${panels.length} options available',
style: TextStyle(color: theme.colorScheme.onSurfaceVariant),
),
shape: const Border(), // Supprime les lignes de séparation par défaut
collapsedShape: const Border(),
childrenPadding: const EdgeInsets.only(left: 12.0, right: 12.0, bottom: 16.0),
children: [
Wrap(
spacing: 8.0,
runSpacing: 8.0,
children: panels.map((panel) {
return ActionChip(
elevation: 0,
pressElevation: 2,
shadowColor: Colors.transparent,
surfaceTintColor: Colors.transparent,
side: BorderSide(color: theme.colorScheme.outlineVariant.withAlpha(80)),
backgroundColor: theme.colorScheme.surfaceContainerHigh,
avatar: Icon(
Icons.arrow_outward_rounded,
size: 14,
color: theme.colorScheme.secondary,
),
label: Text(
panel.label,
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w500,
color: theme.colorScheme.onSurface,
),
),
onPressed: () => _openPanel(panel),
);
}).toList(),
),
],
),
);
}).toList(),
),
),
);
}
}