diff --git a/lib/base/DBManager.dart b/lib/base/DBManager.dart new file mode 100644 index 0000000..f2f2fd9 --- /dev/null +++ b/lib/base/DBManager.dart @@ -0,0 +1,103 @@ +import 'dart:io'; + +import 'package:flustars/flustars.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:project_telephony/model/send_number_model.dart'; +import 'package:sqflite/sqflite.dart'; +import 'package:path/path.dart'; + +class DBManager { + /// 数据库名 + final String _dbName = "dbName"; + + /// 数据库版本 + final int _version = 1; + + static final DBManager _instance = DBManager._(); + + factory DBManager() { + return _instance; + } + + DBManager._(); + + static Database? _db; + + Future get db async { + return _db ??= await _initDB(); + } + + /// 初始化数据库 + Future _initDB() async { + Directory directory = await getApplicationDocumentsDirectory(); + String path = join(directory.path, _dbName); + return await openDatabase( + path, + version: _version, + onCreate: _onCreate, + onUpgrade: _onUpgrade, + ); + } + + /// 创建表 + Future _onCreate(Database db, int version) async { + const String sql = """ + CREATE TABLE SendNumber( + id INTEGER primary key AUTOINCREMENT, + sendNumber TEXT, + createdAt datetime + ) + """; + return await db.execute(sql); + } + + /// 更新表 + Future _onUpgrade(Database db, int oldVersion, int newVersion) async {} + + /// 保存数据 + Future saveData(SendNumber sendNumber) async { + Database database = await db; + return await database.insert("SendNumber", sendNumber.toJson()); + } + + /// 使用SQL保存数据 + Future saveDataBySQL(SendNumber sendNumber) async { + const String sql = """ + INSERT INTO SendNumber(sendNumber,createdAt) values(?,?) + """; + Database database = await db; + return await database.rawInsert(sql, [sendNumber.sendNumber, sendNumber.createdAt]); + } + + /// 查询全部数据 + Future?> findAll() async { + Database? database = await db; + List> result = await database.query("SendNumber"); + if (result.isNotEmpty) { + return result.map((e) => SendNumber.fromJson(e)).toList(); + } else { + return []; + } + } + + ///条件查询 + Future?> find(String sendNumber) async { + Database database = await db; + List> result = + await database.query("SendNumber", where: "sendNumber=?", whereArgs: [sendNumber]); + if (result.isNotEmpty) { + return result.map((e) => SendNumber.fromJson(e)).toList(); + } else { + return []; + } + } + + /// 修改 + Future update(SendNumber sendNumber) async { + Database database = await db; + sendNumber.createdAt = DateUtil.formatDate(DateTime.now()); + int count = + await database.update("SendNumber", sendNumber.toJson(), where: "sendNumber=?", whereArgs: [sendNumber.sendNumber]); + return count; + } +} diff --git a/lib/constants/api.dart b/lib/constants/api.dart index 24d8ec4..5b96cbd 100644 --- a/lib/constants/api.dart +++ b/lib/constants/api.dart @@ -31,6 +31,7 @@ class API { static _Pay pay = _Pay(); static _Exclude exclude = _Exclude(); static _Content content = _Content(); + static _Send send = _Send(); } class _App { @@ -56,16 +57,16 @@ class _App { String get trialVip => '/app/user/trialVip'; ///版本更新 - String get updateSelect =>'/app/update/select'; + String get updateSelect => '/app/update/select'; ///版本添加 - String get updateAdd => '/manage/update/add'; + String get updateAdd => '/manage/update/add'; ///输入密码 - String get psdAdd=>'/app/register'; + String get psdAdd => '/app/register'; ///密码登录 - String get psdLogin=>'/app/loginByPwd'; + String get psdLogin => '/app/loginByPwd'; } class _Content { @@ -122,5 +123,13 @@ class _Exclude { String get find => '/app/exclude/find'; ///查看所有排除手机号列表 - String get findAll =>'/app/exclude/findAll'; + String get findAll => '/app/exclude/findAll'; +} + +class _Send { + ///添加发送短信手机号 + String get add => '/app/send/add'; + + ///查看发送短信手机号 + String get select => '/send/select'; } diff --git a/lib/model/send_number_model.dart b/lib/model/send_number_model.dart new file mode 100644 index 0000000..f51fb34 --- /dev/null +++ b/lib/model/send_number_model.dart @@ -0,0 +1,27 @@ +import 'dart:convert'; + +SendNumber sendNumberFromJson(String str) => SendNumber.fromJson(json.decode(str)); + +String sendNumberToJson(SendNumber data) => json.encode(data.toJson()); + +class SendNumber { + SendNumber({ + this.sendNumber, + this.createdAt, + }); + + SendNumber.fromJson(dynamic json) { + sendNumber = json['sendNumber']; + createdAt = json['createdAt']; + } + + String? sendNumber; + String? createdAt; + + Map toJson() { + final map = {}; + map['sendNumber'] = sendNumber; + map['createdAt'] = createdAt; + return map; + } +} diff --git a/lib/ui/home/call.dart b/lib/ui/home/call.dart index 253bd43..a9ea61d 100644 --- a/lib/ui/home/call.dart +++ b/lib/ui/home/call.dart @@ -2,29 +2,34 @@ import 'dart:async'; import 'dart:ui'; import 'package:call_log/call_log.dart'; +import 'package:flustars/flustars.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_background_service/flutter_background_service.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:project_telephony/model/send_number_model.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:telephony/telephony.dart'; +import '../../base/DBManager.dart'; +import '../user/user_page.dart'; + const nId = "my_foreground"; const notificationId = 888; + Future initializeService() async { final service = FlutterBackgroundService(); const AndroidNotificationChannel channel = AndroidNotificationChannel( nId, // id '我的前台服务', // title - description: - '此通道用于重要通知。', // description + description: '此通道用于重要通知。', // description importance: Importance.low, // importance must be at low or higher level ); final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = - FlutterLocalNotificationsPlugin(); + FlutterLocalNotificationsPlugin(); await flutterLocalNotificationsPlugin .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>() + AndroidFlutterLocalNotificationsPlugin>() ?.createNotificationChannel(channel); await service.configure( iosConfiguration: IosConfiguration( @@ -43,7 +48,8 @@ Future initializeService() async { autoStart: true, isForegroundMode: true, - notificationChannelId: nId, // this must match with notification channel you created above. + notificationChannelId: nId, + // this must match with notification channel you created above. initialNotificationTitle: 'AWESOME SERVICE', initialNotificationContent: 'Initializing', foregroundServiceNotificationId: notificationId, @@ -62,7 +68,7 @@ bool onIosBackground(ServiceInstance service) { void onStart(ServiceInstance service) async { DartPluginRegistrant.ensureInitialized(); final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = - FlutterLocalNotificationsPlugin(); + FlutterLocalNotificationsPlugin(); service.on("stopService").listen((event) { service.stopSelf(); }); @@ -70,6 +76,7 @@ void onStart(ServiceInstance service) async { int flag = 0; String? phoneNum = ""; String callState; + bool fff=false; Timer.periodic(const Duration(seconds: 1), (timer) async { //数据储存读取 @@ -77,97 +84,113 @@ void onStart(ServiceInstance service) async { //获取来电状态 CallState state = await Telephony.instance.callState; callState = state.name; - List noNumberList = prefs.getStringList("specified") ??[]; - flutterLocalNotificationsPlugin.show( - notificationId, - '短信帮手', - '$callState ${DateTime.now().second}', - const NotificationDetails( - android: AndroidNotificationDetails( - nId, - '我的前台服务', - icon: 'ic_bg_service_small', - ongoing: true, - ), - ), - ); + List noNumberList = prefs.getStringList("specified") ?? []; + flutterLocalNotificationsPlugin.show( + notificationId, + '短信帮手', + '$callState ${DateTime.now().second}', + const NotificationDetails( + android: AndroidNotificationDetails( + nId, + '我的前台服务', + icon: 'ic_bg_service_small', + ongoing: true, + ), + ), + ); //发送内容信息 String content = prefs.getString("refSms") ?? "现在有事,等会回电"; //发送信息的状态 int? numberSet = prefs.getInt("numIndex") ?? 1; + int? dayTimes =prefs.getInt("dayTimes")??0; print("号码设置$numberSet 发送内容$content 指定不发送$noNumberList"); // print(flag); if (callState == "IDLE") { if (flag != 0) { + print(dayTimes); final Iterable entry = await CallLog.query(); phoneNum = entry.first.number; - // print(phoneNum); - switch (numberSet) { - case 0: - - if(!noNumberList.contains(phoneNum)){ - print("所有都发+号码设置$numberSet+发送内容$content"); - Telephony.backgroundInstance - .sendSms(to: phoneNum!, message: content); - flag = 0; - }else{ - print("指定不发送"); - flag = 0; - } - break; - case 1: - if (flag > 0) { - // print("来电拒接/未接"); - // print("${phoneNum!}:${ref!}"); - if(!noNumberList.contains(phoneNum)) { - print("来电拒接+号码设置$numberSet+发送内容$content"); - Telephony.backgroundInstance - .sendSms(to: phoneNum!, message: content); - flag = 0; - }else{ - print("指定不发送"); - flag = 0; - } - // print("发送成功"); - } else if (flag == -1) { - // print("来电接听"); - // print("${phoneNum!}:$content"); - if(!noNumberList.contains(phoneNum)) { - print("来电接听+号码设置$numberSet+发送内容$content"); + var phone = SendNumber( + sendNumber: phoneNum, + createdAt: DateUtil.formatDate(DateTime.now()), + ); + var s = await DBManager().find(phoneNum!); + if (s!.isEmpty) { + await DBManager().saveData(phone); + fff=true; + }else if(DateTime.parse(s.first.createdAt!) + .add(Duration(days: dayTimes)) + .isBefore(DateTime.now())) { + await DBManager().update(phone); + fff=true; + } + if(fff){ + switch (numberSet) { + case 0: + if (!noNumberList.contains(phoneNum)) { + print("所有都发+号码设置$numberSet+发送内容$content"); Telephony.backgroundInstance .sendSms(to: phoneNum!, message: content); flag = 0; - }else{ + } else { print("指定不发送"); flag = 0; } - } - - break; - case 2: - if(flag==-2){ - if (entry.first.duration! > 0) { - // print("${phoneNum!}:$content"); - if(!noNumberList.contains(phoneNum)) { - print("去电接听+号码设置$numberSet+发送内容$content"); + break; + case 1: + if (flag > 0) { + // print("来电拒接/未接"); + // print("${phoneNum!}:${ref!}"); + if (!noNumberList.contains(phoneNum)) { + print("来电拒接+号码设置$numberSet+发送内容$content"); Telephony.backgroundInstance .sendSms(to: phoneNum!, message: content); + flag = 0; + } else { + print("指定不发送"); + flag = 0; } - } else { + // print("发送成功"); + } else if (flag == -1) { + // print("来电接听"); // print("${phoneNum!}:$content"); - if(!noNumberList.contains(phoneNum)) { - print("去电挂断+号码设置$numberSet+发送内容$content"); + if (!noNumberList.contains(phoneNum)) { + print("来电接听+号码设置$numberSet+发送内容$content"); Telephony.backgroundInstance .sendSms(to: phoneNum!, message: content); - }else{ + flag = 0; + } else { print("指定不发送"); flag = 0; } } - } - flag = 0; - break; + break; + case 2: + if (flag == -2) { + if (entry.first.duration! > 0) { + // print("${phoneNum!}:$content"); + if (!noNumberList.contains(phoneNum)) { + print("去电接听+号码设置$numberSet+发送内容$content"); + Telephony.backgroundInstance + .sendSms(to: phoneNum!, message: content); + } + } else { + // print("${phoneNum!}:$content"); + if (!noNumberList.contains(phoneNum)) { + print("去电挂断+号码设置$numberSet+发送内容$content"); + Telephony.backgroundInstance + .sendSms(to: phoneNum!, message: content); + } else { + print("指定不发送"); + flag = 0; + } + } + } + flag = 0; + break; + } + fff=false; } } } else if (callState == "RINGING") { diff --git a/lib/ui/home/set/phone_set_page.dart b/lib/ui/home/set/phone_set_page.dart index e6fd194..64b5303 100644 --- a/lib/ui/home/set/phone_set_page.dart +++ b/lib/ui/home/set/phone_set_page.dart @@ -76,13 +76,14 @@ class _PhoneSetPageState extends State { }, ]; List cycleList = [ - '每天发送', + '发送无限制', "一天内发送一次", "三天内发送一次", "七天天内发送一次", "十五天内发送一次", "三十天内发送一次" ]; + List dayTimes=[0,1,3,7,15,30]; String cycleText = ""; @override @@ -123,7 +124,7 @@ class _PhoneSetPageState extends State { await SharedPreferences.getInstance(); // print(prefs.getInt("numIndex")); select = (prefs.getInt("numIndex")) ?? 0; - cycleText = prefs.getString("cycle") ?? "每天发送"; + cycleText = prefs.getString("cycle") ?? "发送无限制"; UserTool.userProvider.viewLoading(); _getRequests(); @@ -388,6 +389,7 @@ class _PhoneSetPageState extends State { BotToast.showText(text: "成功"); prefs.setString( "cycle", cycleList[index]); + prefs.setInt('dayTimes', dayTimes[index]); BotToast.showText( text: cycleList[index]); Navigator.pop(context); diff --git a/lib/ui/user/content_details_page.dart b/lib/ui/user/content_details_page.dart index 46f8a43..c8623c6 100644 --- a/lib/ui/user/content_details_page.dart +++ b/lib/ui/user/content_details_page.dart @@ -93,7 +93,7 @@ final FocusNode verifyNode=FocusNode(); filled: true, isDense: true, fillColor: Colors.transparent , - hintText: widget.content.isNotEmpty ? "" : "请输入所需短信", + hintText: UserTool.userProvider.userInfo.tag.isNotEmpty ? UserTool.userProvider.userInfo.tag : "请输入所需短信", hintStyle: TextStyle( color: widget.content != "" ? const Color(0xFF333333) @@ -122,7 +122,7 @@ final FocusNode verifyNode=FocusNode(); service.startService(); }); } - // UserTool.userProvider.updateUserInfo(); + UserTool.userProvider.updateUserInfo(); // UserTool.userProvider.updateConSms(); Get.back(); } else { diff --git a/pubspec.lock b/pubspec.lock index 86dac7f..14b0dc5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1035,6 +1035,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.3" + sqflite: + dependency: "direct main" + description: + name: sqflite + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3+1" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + url: "https://pub.dartlang.org" + source: hosted + version: "2.4.0" stack_trace: dependency: transitive description: @@ -1270,4 +1284,4 @@ packages: version: "3.1.1" sdks: dart: ">=2.17.0 <3.0.0" - flutter: ">=2.10.0" + flutter: ">=3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index fa96e56..dd8b4f2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -91,9 +91,11 @@ dependencies: flutter_update_dialog: ^2.0.0 # http dio: ^4.0.6 -# 版本跟新 +# 版本更新 flutter_xupdate: ^2.0.3 path_provider: ^2.0.11 +# 本地数据库 + sqflite: ^2.0.3+1 ## 生成适配器 # hive_generator: ^1.1.3 # # jdk