大二下学期项目--校园消防安全

一.手机振动功能

1.1 引入库

dependencies:
  flutter:
    sdk: flutter
  vibration: ^1.8.4
 

1.2 在AndroidManifest.xml 中添加权限

</application>
<uses-permission android:name="android.permission.VIBRATE"/>

1.3  代码实例--在main.dart里

import 'package:flutter/material.dart';
import 'package:vibration/vibration.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Vibration Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 在主页加载时执行震动功能
    vibrateDevice();

    return Scaffold(
      appBar: AppBar(
        title: const Text('Vibration Demo'),
      ),
      body: Center(
        child: Text(
          '手机正在震动...',
          style: TextStyle(fontSize: 20),
        ),
      ),
    );
  }

  Future<void> vibrateDevice() async {
    bool? canVibrate = await Vibration.hasVibrator();
    if (canVibrate != null && canVibrate) {
      Vibration.vibrate(duration: 1000); // 震动1秒钟
    } else {
      print('设备不支持震动功能');
    }
  }
}

二. 警报弹窗

2.1  代码示例

在main.dart里

我用if语句写了等级判断,设定了危险阈值,当到达阈值时,会触发报警弹窗。



import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fire Detection System',
      home: SensorMonitoringPage(),
    );
  }
}

class SensorMonitoringPage extends StatefulWidget {
  @override
  _SensorMonitoringPageState createState() => _SensorMonitoringPageState();
}

class _SensorMonitoringPageState extends State<SensorMonitoringPage> {
  final double temperature = 75.5; // 温度
  final double smokeDensity = 30.0; // 烟雾浓度
  final double flameSize = 0.7; // 火焰大小
  final String location="A501";

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _evaluateFireLevel();
    });
  }

  String _evaluateFireLevel() {
    String fireLevel;
    if (temperature >= 80.0 || smokeDensity >= 50.0 || flameSize >= 0.8) {
      fireLevel = '一级火灾';
    } else if (temperature >= 70.0 || smokeDensity >= 30.0 || flameSize >= 0.5) {
      fireLevel = '二级火灾';
    } else if (temperature >= 60.0 || smokeDensity >= 20.0 || flameSize >= 0.3) {
      fireLevel = '三级火灾';
    } else {
      fireLevel = '无火灾';
    }

    if (fireLevel != '无火灾') {
      _showAlert(fireLevel);
    }
    return fireLevel;
  }


  void _showAlert(String fireLevel) {
    showDialog(
      barrierDismissible: false, //表示点击灰色背景的时候是否消失弹出框
      context: context,
      builder: (BuildContext context) {
        return
         AlertDialog(
          title: const Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Icon(Icons.warning, size:40,color: Colors.red), // 警告标志
              SizedBox(width: 8), // 警告标志与标题之间的间距
              Text('火灾警报'),
               // 对话框标题
            ],
          ),
          content: SingleChildScrollView(
            child:

            ListBody(
              children: <Widget>[
                ListTile(title: Text('在$location发生$fireLevel,现场温度为$temperature,烟雾浓度为$smokeDensity',)),

                ListTile(title: Text('在$location发生$fireLevel,现场温度为$temperature,烟雾浓度为$smokeDensity',)),

                ListTile(title: Text('在$location发生$fireLevel,现场温度为$temperature,烟雾浓度为$smokeDensity',)),

                ListTile(title: Text('在$location发生$fireLevel,现场温度为$temperature,烟雾浓度为$smokeDensity',)),

                ListTile(title:Text('在$location发生$fireLevel,现场温度为$temperature,烟雾浓度为$smokeDensity',)),

                ListTile(title:Text('在$location发生$fireLevel,现场温度为$temperature,烟雾浓度为$smokeDensity',)),
                ListTile(title: Text('在$location发生$fireLevel,现场温度为$temperature,烟雾浓度为$smokeDensity',)),

                ListTile(title: Text('在$location发生$fireLevel,现场温度为$temperature,烟雾浓度为$smokeDensity',)),

                ListTile(title: Text('在$location发生$fireLevel,现场温度为$temperature,烟雾浓度为$smokeDensity',)),

                ListTile(title: Text('在$location发生$fireLevel,现场温度为$temperature,烟雾浓度为$smokeDensity',)),

                ListTile(title:Text('在$location发生$fireLevel,现场温度为$temperature,烟雾浓度为$smokeDensity',)),

                ListTile(title:Text('在$location发生$fireLevel,现场温度为$temperature,烟雾浓度为$smokeDensity',)),

              ],
            ),
          ),
          actions: <Widget>[
            TextButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              child: Text('关闭'),
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Sensor Monitoring'),
      ),
      body: Center(
        child: Text('Monitoring Page Content'),
      ),
    );
  }
}

2.2 结果 

三. 按钮跳转报警页面

3.1 引入库

url_launcher: ^6.2.5

3.2  插入两个按钮

TextButton(
                      style: TextButton.styleFrom(
                        padding: EdgeInsets.zero, // 移除内边距
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(20),
                        ),
                        minimumSize: Size(55, 55 + 10 + 16), // 宽度和高度
                        tapTargetSize: MaterialTapTargetSize.shrinkWrap, // 紧缩点击区域到最小
                        backgroundColor: Colors.grey, // 按钮背景颜色
                        // primary: Colors.black, // 文本颜色
                        textStyle: TextStyle(fontSize: 16),
                      ),
                      onPressed: () {
                        _makePhoneCall("119");
                      },
                      child: Column(
                        mainAxisSize: MainAxisSize.min, // 控制大小
                        children: <Widget>[
                          Container(
                            height: 55,
                            width: 55,
                            decoration: BoxDecoration(
                              color: Colors.red,
                              border: Border.all(color: Colors.black12, width: 1),

                              borderRadius: BorderRadius.circular(20),
                            ),
                            child: Icon(
                              Icons.phone,
                              size: 30,
                              color: Colors.white,
                            ),
                          ),
                          SizedBox(height: 10),
                          Text('紧急SOS',style: TextStyle(color: Colors.black, fontSize: 16)),
                        ],
                      ),
                    ),
                    TextButton(
                      style: TextButton.styleFrom(
                        padding: EdgeInsets.zero, // 移除内边距
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(20),
                        ),
                        minimumSize: Size(55, 55 + 10 + 16), // 宽度和高度
                        tapTargetSize: MaterialTapTargetSize.shrinkWrap, // 紧缩点击区域到最小
                        backgroundColor: Colors.grey, // 按钮背景颜色
                        // primary: Colors.black, // 文本颜色
                        textStyle: TextStyle(fontSize: 16),
                      ),
                      onPressed: () {
                        _openSMSApp();
                      },
                      child: Column(
                        mainAxisSize: MainAxisSize.min, // 控制大小
                        children: <Widget>[
                          Container(
                            height: 55,
                            width: 55,
                            decoration: BoxDecoration(
                              color: Colors.yellow,
                              border: Border.all(color: Colors.black12, width: 1),

                              borderRadius: BorderRadius.circular(20),
                            ),
                            child: Icon(
                              Icons.message,
                              size: 30,
                              color: Color.fromARGB(255, 183, 119, 194),
                            ),
                          ),
                          SizedBox(height: 10),
                          Text('紧急MSM',style: TextStyle(color: Colors.black, fontSize: 16)),
                        ],
                      ),
                    ),

3.3 SOS和MSM

oid _openSMSApp() async {
  String uri = 'sms:';
  if (0 == 0) {
    await launch(uri);
  } else {
    throw 'Could not launch $uri';
  }
}

void _makePhoneCall(String phoneNumber) async {
  String uri = 'tel:$phoneNumber';
  if (await launchUrl(Uri.parse("tel:119"))) {
    await launch(uri);
  } else {
    throw 'Could not launch $uri';
  }
}

3.4 结果

四、 等级消防器械信息

4.1 导入库 

intl: ^0.19.0

4.2 示例代码

当当前日期超过更换日期时会产生弹窗提醒。

import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; // 用于格式化日期



class DateEntryPage extends StatefulWidget {
  @override
  _DateEntryPageState createState() => _DateEntryPageState();
}

class _DateEntryPageState extends State<DateEntryPage> {
  DateTime? productionDate;
  DateTime? replacementDate;

  TextEditingController productionDateController = TextEditingController();
  TextEditingController replacementDateController = TextEditingController();

  @override
  void initState() {
    super.initState();
    // 初始化日期控制器,用于显示已保存的日期
    productionDateController.text = productionDate != null ? DateFormat('yyyy-MM-dd').format(productionDate!) : '';
    replacementDateController.text = replacementDate != null ? DateFormat('yyyy-MM-dd').format(replacementDate!) : '';
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('消防器械日期管理'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            TextField(
              controller: productionDateController,
              readOnly: true,
              decoration: InputDecoration(
                labelText: '生产日期',
                suffixIcon: IconButton(
                  icon: Icon(Icons.calendar_today),
                  onPressed: () async {
                    // 显示日期选择器,并将选中日期更新到控制器中
                    DateTime? picked = await showDatePicker(
                      context: context,
                      initialDate: DateTime.now(),
                      firstDate: DateTime(2000),
                      lastDate: DateTime.now(),
                    );
                    if (picked != null && picked != productionDate) {
                      setState(() {
                        productionDate = picked;
                        productionDateController.text = DateFormat('yyyy-MM-dd').format(productionDate!);
                      });
                    }
                  },
                ),
              ),
            ),
            SizedBox(height: 20),
            TextField(
              controller: replacementDateController,
              readOnly: true,
              decoration: InputDecoration(
                labelText: '更换日期',
                suffixIcon: IconButton(
                  icon: Icon(Icons.calendar_today),
                  onPressed: () async {
                    // 显示日期选择器,并将选中日期更新到控制器中
                    DateTime? picked = await showDatePicker(
                      context: context,
                      initialDate: DateTime.now(),
                      firstDate: DateTime(2000),
                      lastDate: DateTime.now().add(Duration(days: 365 * 10)), // 最多选择10年后的日期
                    );
                    if (picked != null && picked != replacementDate) {
                      setState(() {
                        replacementDate = picked;
                        replacementDateController.text = DateFormat('yyyy-MM-dd').format(replacementDate!);
                      });
                    }
                  },
                ),
              ),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                // 模拟保存日期,这里可以将日期保存到本地或者数据库中
                // 保存逻辑可以根据实际需求进行扩展
                if (productionDate != null && replacementDate != null) {
                  // 检查日期是否已过期
                  if ( DateTime.now().isAfter(replacementDate!)) {
                    showDialog(
                      context: context,
                      builder: (BuildContext context) {
                        return AlertDialog(
                          title: Text('提醒'),
                          content: Text('当前日期已超过录入日期'),
                          actions: [
                            TextButton(
                              onPressed: () {
                                Navigator.of(context).pop();
                              },
                              child: Text('确定'),
                            ),
                          ],
                        );
                      },
                    );
                  } else {
                    showDialog(
                      context: context,
                      builder: (BuildContext context) {
                        return AlertDialog(
                          title: Text('提醒'),
                          content: Text('日期保存成功'),
                          actions: [
                            TextButton(
                              onPressed: () {
                                Navigator.of(context).pop();
                              },
                              child: Text('确定'),
                            ),
                          ],
                        );
                      },
                    );
                  }
                } else {
                  showDialog(
                    context: context,
                    builder: (BuildContext context) {
                      return AlertDialog(
                        title: Text('提醒'),
                        content: Text('请先选择生产日期和更换日期'),
                        actions: [
                          TextButton(
                            onPressed: () {
                              Navigator.of(context).pop();
                            },
                            child: Text('确定'),
                          ),
                        ],
                      );
                    },
                  );
                }
              },
              child: Text('保存日期'),
            ),
          ],
        ),
      ),
    );
  }
}

4.3  结果

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值