From 0fce8fea0b83afb02b5d8780160787e87b8ceedb Mon Sep 17 00:00:00 2001
From: cloudroam <cloudroam>
Date: 星期二, 25 二月 2025 08:43:47 +0800
Subject: [PATCH] 新增
---
app/src/main/java/com/example/firstapp/database/entity/Reminder.kt | 13 +
app/src/main/java/com/example/firstapp/adapter/ReminderAdapter.kt | 39 ++++
app/src/main/java/com/example/firstapp/database/repository/KeywordRepository.kt | 11
app/src/main/java/com/example/firstapp/core/Core.kt | 2
app/src/main/java/com/example/firstapp/database/entity/KeywordEntity.kt | 2
app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt | 99 +++++++---
app/src/main/java/com/example/firstapp/ui/reminder/ReminderViewModel.kt | 33 +++
app/src/main/res/layout/fragment_reminder_settings.xml | 82 ++++++--
app/src/main/java/com/example/firstapp/database/dao/KeywordDao.kt | 36 ++-
app/src/main/java/com/example/firstapp/database/service/ApiService.kt | 2
app/src/main/res/layout/item_reminder.xml | 39 ++++
app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt | 17 +
app/src/main/java/com/example/firstapp/database/AppDatabase.kt | 15 +
app/src/main/java/com/example/firstapp/database/entity/KeywordConfig.kt | 11 +
app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt | 21 ++
app/src/main/java/com/example/firstapp/App.kt | 18 -
app/src/main/java/com/example/firstapp/ui/reminder/ReminderSettingsFragment.kt | 71 ++++++-
17 files changed, 408 insertions(+), 103 deletions(-)
diff --git a/app/src/main/java/com/example/firstapp/App.kt b/app/src/main/java/com/example/firstapp/App.kt
index f46c3a9..4e0a37b 100644
--- a/app/src/main/java/com/example/firstapp/App.kt
+++ b/app/src/main/java/com/example/firstapp/App.kt
@@ -3,14 +3,10 @@
import android.annotation.SuppressLint
import android.app.Application
import android.app.PendingIntent
-import android.bluetooth.BluetoothAdapter
-import android.bluetooth.BluetoothDevice
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.location.Geocoder
-import android.net.ConnectivityManager
-import android.net.wifi.WifiManager
import android.os.Build
import androidx.lifecycle.MutableLiveData
import androidx.multidex.MultiDex
@@ -20,34 +16,26 @@
import com.gyf.cactus.callback.CactusCallback
import com.gyf.cactus.ext.cactus
import com.hjq.language.MultiLanguages
-import com.hjq.language.OnLanguageListener
import com.example.firstapp.core.Core
+import com.example.firstapp.database.repository.ReminderRepository
import com.example.firstapp.database.repository.CodeRepository
import com.example.firstapp.database.repository.KeywordRepository
import com.example.firstapp.database.repository.MsgRepository
import com.example.firstapp.database.service.RetrofitClient
import com.example.firstapp.receiver.CactusReceiver
-import com.example.firstapp.service.BluetoothScanService
-import com.example.firstapp.service.HttpServerService
-import com.example.firstapp.utils.ACTION_START
import com.example.firstapp.utils.AppInfo
-import com.example.firstapp.utils.CactusSave
import com.example.firstapp.utils.FRONT_CHANNEL_ID
import com.example.firstapp.utils.FRONT_CHANNEL_NAME
import com.example.firstapp.utils.FRONT_NOTIFY_ID
import com.example.firstapp.utils.FRPC_LIB_VERSION
-import com.example.firstapp.utils.HistoryUtils
import com.example.firstapp.utils.Log
import com.example.firstapp.utils.SettingUtils
-import com.example.firstapp.utils.SharedPreference
import com.example.firstapp.utils.tinker.TinkerLoadLibrary
import com.king.location.LocationClient
import com.xuexiang.xutil.file.FileUtils
import frpclib.Frpclib
-import io.reactivex.Observable
import io.reactivex.disposables.Disposable
-import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
import java.io.BufferedWriter
@@ -57,8 +45,6 @@
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
-import java.util.TimeZone
-import java.util.concurrent.TimeUnit
@Suppress("DEPRECATION")
class App : Application(), CactusCallback, Configuration.Provider by Core {
@@ -67,8 +53,10 @@
val database by lazy { AppDatabase.getInstance(this) }
val msgRepository by lazy { MsgRepository(database.msgDao()) }
val codeRepository by lazy { CodeRepository(database.codeDao()) }
+ val reminderRepository by lazy { ReminderRepository(database.reminderDao()) }
val keywordRepository by lazy { KeywordRepository(RetrofitClient.apiService,database.keywordDao()) }
+
companion object {
const val TAG: String = "SmsForwarder"
diff --git a/app/src/main/java/com/example/firstapp/adapter/ReminderAdapter.kt b/app/src/main/java/com/example/firstapp/adapter/ReminderAdapter.kt
new file mode 100644
index 0000000..fb4335b
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/adapter/ReminderAdapter.kt
@@ -0,0 +1,39 @@
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.ListAdapter
+import androidx.recyclerview.widget.RecyclerView
+import com.example.firstapp.database.entity.Reminder
+import com.example.firstapp.databinding.ItemReminderBinding
+import com.sun.mail.imap.protocol.FetchResponse.getItem
+
+class ReminderAdapter(private val onDelete: (Reminder) -> Unit) :
+ ListAdapter<Reminder, ReminderAdapter.ReminderViewHolder>(ReminderDiffCallback()) {
+
+ class ReminderViewHolder(private val binding: ItemReminderBinding) :
+ RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(reminder: Reminder, onDelete: (Reminder) -> Unit) {
+ binding.textNickname.text = reminder.nickname
+ binding.textKeywords.text = reminder.keywords
+ binding.btnDelete.setOnClickListener { onDelete(reminder) }
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ReminderViewHolder {
+ return ReminderViewHolder(
+ ItemReminderBinding.inflate(
+ LayoutInflater.from(parent.context), parent, false
+ )
+ )
+ }
+
+ override fun onBindViewHolder(holder: ReminderViewHolder, position: Int) {
+ holder.bind(getItem(position), onDelete)
+ }
+}
+
+class ReminderDiffCallback : DiffUtil.ItemCallback<Reminder>() {
+ override fun areItemsTheSame(oldItem: Reminder, newItem: Reminder) = oldItem.id == newItem.id
+ override fun areContentsTheSame(oldItem: Reminder, newItem: Reminder) = oldItem == newItem
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/core/Core.kt b/app/src/main/java/com/example/firstapp/core/Core.kt
index 47c3d20..6a18b64 100644
--- a/app/src/main/java/com/example/firstapp/core/Core.kt
+++ b/app/src/main/java/com/example/firstapp/core/Core.kt
@@ -6,6 +6,7 @@
import com.example.firstapp.database.repository.CodeRepository
import com.example.firstapp.database.repository.KeywordRepository
import com.example.firstapp.database.repository.MsgRepository
+import com.example.firstapp.database.repository.ReminderRepository
import kotlinx.coroutines.launch
@@ -15,6 +16,7 @@
val msg: MsgRepository by lazy { (app as App).msgRepository }
val code: CodeRepository by lazy { (app as App).codeRepository }
val keyword: KeywordRepository by lazy { (app as App).keywordRepository }
+ val reminder: ReminderRepository by lazy { (app as App).reminderRepository }
fun init(app: Application) {
this.app = app
diff --git a/app/src/main/java/com/example/firstapp/database/AppDatabase.kt b/app/src/main/java/com/example/firstapp/database/AppDatabase.kt
index 15e5bec..8c2b7c0 100644
--- a/app/src/main/java/com/example/firstapp/database/AppDatabase.kt
+++ b/app/src/main/java/com/example/firstapp/database/AppDatabase.kt
@@ -1,5 +1,6 @@
package com.example.firstapp
+
import android.content.Context
import androidx.room.Database
import androidx.room.Room
@@ -10,9 +11,11 @@
import com.example.firstapp.database.dao.CodeDao
import com.example.firstapp.database.dao.KeywordDao
import com.example.firstapp.database.dao.MsgDao
+import com.example.firstapp.database.dao.ReminderDao
import com.example.firstapp.database.entity.Code
import com.example.firstapp.database.entity.KeywordEntity
import com.example.firstapp.database.entity.Msg
+import com.example.firstapp.database.entity.Reminder
import com.example.firstapp.utils.DATABASE_NAME
import com.example.firstapp.utils.SettingUtils
import com.example.firstapp.utils.TAG_LIST
@@ -22,8 +25,7 @@
@Database(
- entities = [ Msg::class, Code::class, KeywordEntity::class],
-// views = [LogsDetail::class],
+ entities = [ Msg::class, Code::class, KeywordEntity::class, Reminder::class],
version = 20,
exportSchema = false
)
@@ -32,6 +34,7 @@
abstract fun msgDao(): MsgDao
abstract fun codeDao(): CodeDao
abstract fun keywordDao(): KeywordDao
+ abstract fun reminderDao(): ReminderDao
companion object {
@Volatile
@@ -108,6 +111,14 @@
`isEnabled` INTEGER NOT NULL
)
""")
+// database.execSQL("""
+// CREATE TABLE IF NOT EXISTS `reminders` (
+// id INTEGER PRIMARY KEY AUTOINCREMENT,
+// type TEXT NOT NULL,
+// nickname TEXT NOT NULL,
+// keywords TEXT NOT NULL,
+// );
+// """)
}
}
diff --git a/app/src/main/java/com/example/firstapp/database/dao/KeywordDao.kt b/app/src/main/java/com/example/firstapp/database/dao/KeywordDao.kt
index f4011d5..81a54e1 100644
--- a/app/src/main/java/com/example/firstapp/database/dao/KeywordDao.kt
+++ b/app/src/main/java/com/example/firstapp/database/dao/KeywordDao.kt
@@ -8,20 +8,30 @@
import com.example.firstapp.database.entity.KeywordConfig
import com.example.firstapp.database.entity.KeywordEntity
-@Dao
-interface KeywordDao {
- @Query("SELECT * FROM keywords")
- fun getAllKeywords(): List<KeywordEntity>
-
+//@Dao
+//interface KeywordDao {
+// @Query("SELECT * FROM keywords")
+// fun getAllKeywords(): List<KeywordEntity>
+//
// @Insert(onConflict = OnConflictStrategy.REPLACE)
// suspend fun insertAll(keywords: List<KeywordEntity>)
//
-// @Query("DELETE FROM keywords")
-// suspend fun deleteAll()
//
-// @Update
-// suspend fun update(keyword: KeywordEntity)
-//
-// @Query("SELECT * FROM keywords WHERE isEnabled = 1")
-// fun getEnabledKeywords(): List<KeywordConfig>
-}
+////
+//// @Query("DELETE FROM keywords")
+//// suspend fun deleteAll()
+////
+//// @Update
+//// suspend fun update(keyword: KeywordEntity)
+////
+//// @Query("SELECT * FROM keywords WHERE isEnabled = 1")
+//// fun getEnabledKeywords(): List<KeywordConfig>
+//}
+@Dao
+interface KeywordDao {
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun insertAll(keywords: List<KeywordEntity>)
+
+ @Query("SELECT * FROM keywords")
+ fun getAllKeywords(): List<KeywordEntity>
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt b/app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt
new file mode 100644
index 0000000..8c9b629
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/database/dao/ReminderDao.kt
@@ -0,0 +1,17 @@
+package com.example.firstapp.database.dao
+import androidx.room.*
+import com.example.firstapp.database.entity.Reminder
+import kotlinx.coroutines.flow.Flow
+
+@Dao
+interface ReminderDao {
+
+ @Query("SELECT * FROM reminders ORDER BY type")
+ fun getAllReminders(): Flow<List<Reminder>>
+
+ @Insert
+ fun insert(reminder: Reminder)
+
+ @Delete
+ fun delete(reminder: Reminder)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/entity/KeywordConfig.kt b/app/src/main/java/com/example/firstapp/database/entity/KeywordConfig.kt
index 2a3e3a2..c7cfca8 100644
--- a/app/src/main/java/com/example/firstapp/database/entity/KeywordConfig.kt
+++ b/app/src/main/java/com/example/firstapp/database/entity/KeywordConfig.kt
@@ -8,4 +8,13 @@
val type: String,
val keyword: String,
val isEnable: Boolean
-)
+){
+ fun toEntity(): KeywordEntity {
+ return KeywordEntity(
+ id = id, // 确保与@Entity类字段匹配
+ type = type,
+ keyword = keyword,
+ isEnabled = isEnable // 注意字段名是否一致(isEnabled vs isEnable)
+ )
+ }
+}
diff --git a/app/src/main/java/com/example/firstapp/database/entity/KeywordEntity.kt b/app/src/main/java/com/example/firstapp/database/entity/KeywordEntity.kt
index 55226ec..db51169 100644
--- a/app/src/main/java/com/example/firstapp/database/entity/KeywordEntity.kt
+++ b/app/src/main/java/com/example/firstapp/database/entity/KeywordEntity.kt
@@ -10,4 +10,4 @@
val keyword: String,
val type: String,
val isEnabled: Boolean
-)
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/entity/Reminder.kt b/app/src/main/java/com/example/firstapp/database/entity/Reminder.kt
new file mode 100644
index 0000000..256b45d
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/database/entity/Reminder.kt
@@ -0,0 +1,13 @@
+package com.example.firstapp.database.entity
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+
+@Entity(tableName = "reminders")
+data class Reminder(
+ @PrimaryKey(autoGenerate = true) val id: Long = 0,
+ val type: String,
+ val nickname: String,
+ val keywords: String
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/repository/KeywordRepository.kt b/app/src/main/java/com/example/firstapp/database/repository/KeywordRepository.kt
index ef48270..4b9caf7 100644
--- a/app/src/main/java/com/example/firstapp/database/repository/KeywordRepository.kt
+++ b/app/src/main/java/com/example/firstapp/database/repository/KeywordRepository.kt
@@ -18,7 +18,7 @@
if (response.status == 1) {
// 保存到本地数据库作为缓存
saveToLocal(response.data)
- response.data
+ keywordDao.getAllKeywords()
} else {
// 如果接口请求失败,使用本地缓存
keywordDao.getAllKeywords()
@@ -32,9 +32,12 @@
}
}
- private suspend fun saveToLocal(keywords: List<KeywordEntity>) {
- true
- //keywordDao.insertAll(keywords.map { it.toEntity() })
+ private suspend fun saveToLocal(keywords: List<KeywordConfig>) {
+// keywords.map { it.toEntity() }
+// keywordDao.insertAll(keywords)
+ val keywordEntities = keywords.map { it.toEntity() }
+ keywordDao.insertAll(keywordEntities)
}
+
}
diff --git a/app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt b/app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt
new file mode 100644
index 0000000..6017712
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/database/repository/ReminderRepository.kt
@@ -0,0 +1,21 @@
+package com.example.firstapp.database.repository
+
+import com.example.firstapp.database.dao.ReminderDao
+import androidx.annotation.WorkerThread
+import com.example.firstapp.database.entity.Reminder
+import kotlinx.coroutines.flow.Flow
+
+class ReminderRepository(private val reminderDao: ReminderDao) {
+
+ val allReminders: Flow<List<Reminder>> = reminderDao.getAllReminders()
+
+ @WorkerThread
+ fun insert(reminder: Reminder) {
+ reminderDao.insert(reminder)
+ }
+
+ @WorkerThread
+ fun delete(reminder: Reminder) {
+ reminderDao.delete(reminder)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/firstapp/database/service/ApiService.kt b/app/src/main/java/com/example/firstapp/database/service/ApiService.kt
index 0ff9daf..0df8e04 100644
--- a/app/src/main/java/com/example/firstapp/database/service/ApiService.kt
+++ b/app/src/main/java/com/example/firstapp/database/service/ApiService.kt
@@ -13,7 +13,7 @@
interface ApiService {
@GET("keywords")
- suspend fun getKeywords():ApiResponse<List<KeywordEntity>> //异步挂起
+ suspend fun getKeywords():ApiResponse<List<KeywordConfig>> //异步挂起
}
// 创建Retrofit实例(单例)
diff --git a/app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt b/app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt
index 18dc9ee..f6fcaa2 100644
--- a/app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt
+++ b/app/src/main/java/com/example/firstapp/receiver/SmsReceiver.kt
@@ -48,7 +48,7 @@
Log.d("SmsReceiver", "Received SMS msgId: ${msgId}")
// 这里我要写个数组,并创建个对象存放一些内容,如这个对象的属性有匹配内容,正则表达式,并循环遍历
- val ruleList = listOf(
+ val ruleList = mutableListOf(
Rule("快递","京东","\\d{6}"),
Rule("快递","菜鸟驿站","\\d{1,2}-\\d{1,2}-\\d{4}")
)
@@ -58,41 +58,76 @@
// 获取最新的关键词配置
val keywords = Core.keyword.getKeywords()
Log.d("keywords", keywords.toString())
- println(keywords)
- // 保存匹配的短信
- //saveMessage(content)
+ keywords.forEach { keyword ->
+ ruleList.add(
+ Rule(
+ keyword.type,
+ keyword.keyword,
+ "\\d{1,2}-\\d{1,2}-\\d{4}"
+ )
+ )
+ }
+ Log.d("RuleList", ruleList.toString())
+ for (rule in ruleList) {
+ val code = rule.extractCodeFromMessage(messageBody.toString())
+
+ if (code!==null) {
+ Log.d("SmsReceiver", "Received SMS code: ${code}")
+
+
+ // 获取当前时间
+ val currentTime = LocalDateTime.now()
+ // 加2小时
+ val futureTime = currentTime.plusHours(2)
+ // 定义时间格式
+ val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
+ // 转换为字符串
+ val overtime = futureTime.format(formatter)
+ // 封装成一个Code对象,并保存在数据库中
+ val code = Code(0, rule.type,1, rule.content,1, 1, msgId, code, overtime)
+ Core.code.insert(code)
+ Log.d("SMS_DEBUG", "新短信已保存到数据库")
+ // 发送广播通知数据已更新
+ //"com.example.firstapp.DATA_UPDATED" 是一个自定义的广播 Action,相当于一个标识符或者说是一个频道名称。这个名称是我们自己定义的,通常使用应用的包名作为前缀,以避免与其他应用的广播冲突。
+ val updateIntent = Intent("com.example.firstapp.DATA_UPDATED")
+ context.sendBroadcast(updateIntent)
+ Log.d("SMS_DEBUG", "发送数据更新广播")
+ }else{
+ Log.d("SmsReceiver", "Received SMS code: 没有匹配到内容")
+ }
+ }
}
// kotlin 怎么创建一个类
- for (rule in ruleList) {
- val code = rule.extractCodeFromMessage(messageBody.toString())
-
- if (code!==null) {
- Log.d("SmsReceiver", "Received SMS code: ${code}")
-
-
- // 获取当前时间
- val currentTime = LocalDateTime.now()
- // 加2小时
- val futureTime = currentTime.plusHours(2)
- // 定义时间格式
- val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
- // 转换为字符串
- val overtime = futureTime.format(formatter)
- // 封装成一个Code对象,并保存在数据库中
- val code = Code(0, rule.type,1, rule.content,1, 1, msgId, code, overtime)
- Core.code.insert(code)
- Log.d("SMS_DEBUG", "新短信已保存到数据库")
- // 发送广播通知数据已更新
- //"com.example.firstapp.DATA_UPDATED" 是一个自定义的广播 Action,相当于一个标识符或者说是一个频道名称。这个名称是我们自己定义的,通常使用应用的包名作为前缀,以避免与其他应用的广播冲突。
- val updateIntent = Intent("com.example.firstapp.DATA_UPDATED")
- context.sendBroadcast(updateIntent)
- Log.d("SMS_DEBUG", "发送数据更新广播")
- }else{
- Log.d("SmsReceiver", "Received SMS code: 没有匹配到内容")
- }
- }
+// for (rule in ruleList) {
+// val code = rule.extractCodeFromMessage(messageBody.toString())
+//
+// if (code!==null) {
+// Log.d("SmsReceiver", "Received SMS code: ${code}")
+//
+//
+// // 获取当前时间
+// val currentTime = LocalDateTime.now()
+// // 加2小时
+// val futureTime = currentTime.plusHours(2)
+// // 定义时间格式
+// val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
+// // 转换为字符串
+// val overtime = futureTime.format(formatter)
+// // 封装成一个Code对象,并保存在数据库中
+// val code = Code(0, rule.type,1, rule.content,1, 1, msgId, code, overtime)
+// Core.code.insert(code)
+// Log.d("SMS_DEBUG", "新短信已保存到数据库")
+// // 发送广播通知数据已更新
+// //"com.example.firstapp.DATA_UPDATED" 是一个自定义的广播 Action,相当于一个标识符或者说是一个频道名称。这个名称是我们自己定义的,通常使用应用的包名作为前缀,以避免与其他应用的广播冲突。
+// val updateIntent = Intent("com.example.firstapp.DATA_UPDATED")
+// context.sendBroadcast(updateIntent)
+// Log.d("SMS_DEBUG", "发送数据更新广播")
+// }else{
+// Log.d("SmsReceiver", "Received SMS code: 没有匹配到内容")
+// }
+// }
}
}
diff --git a/app/src/main/java/com/example/firstapp/ui/reminder/ReminderSettingsFragment.kt b/app/src/main/java/com/example/firstapp/ui/reminder/ReminderSettingsFragment.kt
index 4454886..5b26509 100644
--- a/app/src/main/java/com/example/firstapp/ui/reminder/ReminderSettingsFragment.kt
+++ b/app/src/main/java/com/example/firstapp/ui/reminder/ReminderSettingsFragment.kt
@@ -1,18 +1,30 @@
package com.example.firstapp.ui.reminder
+import ReminderAdapter
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.example.firstapp.App
+import com.example.firstapp.database.entity.Reminder
import com.example.firstapp.databinding.FragmentReminderSettingsBinding
class ReminderSettingsFragment : Fragment() {
private var _binding: FragmentReminderSettingsBinding? = null
private val binding get() = _binding!!
+
+ private val reminderViewModel: ReminderViewModel by viewModels {
+ ReminderViewModelFactory((requireActivity().application as App).reminderRepository)
+ }
+
+ private lateinit var adapter: ReminderAdapter
override fun onCreateView(
inflater: LayoutInflater,
@@ -26,21 +38,60 @@
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- // 返回按钮点击事件
- binding.btnBack.setOnClickListener {
+ setupSpinner()
+ setupRecyclerView()
+ setupClickListeners()
+ observeReminders()
+ }
+
+ private fun setupSpinner() {
+ val types = arrayOf("驿站", "财务", "其他")
+ val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, types)
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
+ binding.spinnerType.adapter = adapter
+ }
+
+ private fun setupRecyclerView() {
+ adapter = ReminderAdapter { reminder ->
+ reminderViewModel.deleteReminder(reminder)
+ }
+ binding.recyclerReminders.apply {
+ layoutManager = LinearLayoutManager(context)
+ this.adapter = this@ReminderSettingsFragment.adapter
+ }
+ }
+
+ private fun setupClickListeners() {
+ binding.btnClose.setOnClickListener {
findNavController().navigateUp()
}
- // 添加提醒按钮点击事件
binding.btnAddReminder.setOnClickListener {
- val reminderText = binding.editQuickReminder.text.toString()
- if (reminderText.isNotEmpty()) {
- // TODO: 保存提醒到数据库
- Toast.makeText(context, "提醒已添加", Toast.LENGTH_SHORT).show()
- binding.editQuickReminder.text.clear()
- } else {
- Toast.makeText(context, "请输入提醒内容", Toast.LENGTH_SHORT).show()
+ val type = binding.spinnerType.selectedItem.toString()
+ val nickname = binding.editNickname.text.toString()
+ val keywords = binding.editKeywords.text.toString()
+
+ if (nickname.isBlank() || keywords.isBlank()) {
+ Toast.makeText(context, "请填写完整信息", Toast.LENGTH_SHORT).show()
+ return@setOnClickListener
}
+
+ reminderViewModel.insertReminder(
+ Reminder(
+ type = type,
+ nickname = nickname,
+ keywords = keywords
+ )
+ )
+
+ binding.editNickname.text.clear()
+ binding.editKeywords.text.clear()
+ }
+ }
+
+ private fun observeReminders() {
+ reminderViewModel.allReminders.observe(viewLifecycleOwner) { reminders ->
+ adapter.submitList(reminders)
}
}
diff --git a/app/src/main/java/com/example/firstapp/ui/reminder/ReminderViewModel.kt b/app/src/main/java/com/example/firstapp/ui/reminder/ReminderViewModel.kt
new file mode 100644
index 0000000..d1bab81
--- /dev/null
+++ b/app/src/main/java/com/example/firstapp/ui/reminder/ReminderViewModel.kt
@@ -0,0 +1,33 @@
+package com.example.firstapp.ui.reminder
+
+import androidx.lifecycle.*
+import com.example.firstapp.database.entity.Reminder
+import com.example.firstapp.database.repository.ReminderRepository
+import kotlinx.coroutines.launch
+
+class ReminderViewModel(private val repository: ReminderRepository) : ViewModel() {
+
+ // 使用 Flow 获取所有提醒
+ val allReminders: LiveData<List<Reminder>> = repository.allReminders.asLiveData()
+
+ // 插入新提醒
+ fun insertReminder(reminder: Reminder) = viewModelScope.launch {
+ repository.insert(reminder)
+ }
+
+ // 删除提醒
+ fun deleteReminder(reminder: Reminder) = viewModelScope.launch {
+ repository.delete(reminder)
+ }
+}
+
+// ViewModel Factory
+class ReminderViewModelFactory(private val repository: ReminderRepository) : ViewModelProvider.Factory {
+ override fun <T : ViewModel> create(modelClass: Class<T>): T {
+ if (modelClass.isAssignableFrom(ReminderViewModel::class.java)) {
+ @Suppress("UNCHECKED_CAST")
+ return ReminderViewModel(repository) as T
+ }
+ throw IllegalArgumentException("Unknown ViewModel class")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_reminder_settings.xml b/app/src/main/res/layout/fragment_reminder_settings.xml
index 2a5addf..8403cd9 100644
--- a/app/src/main/res/layout/fragment_reminder_settings.xml
+++ b/app/src/main/res/layout/fragment_reminder_settings.xml
@@ -8,47 +8,81 @@
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
- android:background="#FFFFFF"
- android:elevation="4dp">
-
- <!-- 返回按钮 -->
- <ImageButton
- android:id="@+id/btn_back"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:layout_centerVertical="true"
- android:background="?attr/selectableItemBackgroundBorderless"
- android:src="@android:drawable/ic_menu_close_clear_cancel"
- android:contentDescription="返回" />
+ android:background="#FFFFFF">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
- android:text="标题"
+ android:text="新增短信提醒"
android:textSize="18sp"
android:textColor="#000000" />
+
+ <!-- 关闭按钮 -->
+ <ImageButton
+ android:id="@+id/btn_close"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_alignParentEnd="true"
+ android:layout_centerVertical="true"
+ android:background="?attr/selectableItemBackgroundBorderless"
+ android:src="@android:drawable/ic_menu_close_clear_cancel" />
</RelativeLayout>
- <!-- 快速提醒输入框 -->
- <EditText
- android:id="@+id/edit_quick_reminder"
+ <!-- 提醒类型选择 -->
+ <Spinner
+ android:id="@+id/spinner_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
- android:background="@android:drawable/edit_text"
- android:hint="快速提醒"
- android:padding="12dp" />
+ android:padding="12dp"
+ android:background="@android:drawable/btn_dropdown" />
- <!-- 添加提醒按钮 -->
+ <!-- 昵称输入框 -->
+ <EditText
+ android:id="@+id/edit_nickname"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="16dp"
+ android:hint="昵称"
+ android:padding="12dp"
+ android:background="@android:drawable/edit_text" />
+
+ <!-- 关键词输入框 -->
+ <EditText
+ android:id="@+id/edit_keywords"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="16dp"
+ android:hint="关键词"
+ android:padding="12dp"
+ android:background="@android:drawable/edit_text" />
+
+ <!-- 已添加列表标题 -->
<Button
android:id="@+id/btn_add_reminder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginHorizontal="16dp"
- android:layout_marginTop="16dp"
+ android:layout_margin="16dp"
android:backgroundTint="#03A9F4"
- android:text="添加到提醒"
+ android:text="确定新增"
android:textColor="#FFFFFF" />
-</LinearLayout>
\ No newline at end of file
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="16dp"
+ android:text="已添加列表"
+ android:textStyle="bold" />
+
+ <!-- 已添加列表 -->
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/recycler_reminders"
+ android:layout_width="match_parent"
+ android:layout_height="221dp"
+ android:layout_weight="1"
+ android:padding="8dp" />
+
+ <!-- 确定新增按钮 -->
+
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_reminder.xml b/app/src/main/res/layout/item_reminder.xml
new file mode 100644
index 0000000..98b1aa9
--- /dev/null
+++ b/app/src/main/res/layout/item_reminder.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="12dp"
+ android:background="@android:color/white">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_toStartOf="@id/btn_delete"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/text_nickname"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="16sp"
+ android:textColor="#000000" />
+
+ <TextView
+ android:id="@+id/text_keywords"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="4dp"
+ android:textSize="14sp"
+ android:textColor="#666666" />
+ </LinearLayout>
+
+ <ImageButton
+ android:id="@+id/btn_delete"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_alignParentEnd="true"
+ android:layout_centerVertical="true"
+ android:background="@null"
+ android:src="@android:drawable/ic_delete" />
+
+</RelativeLayout>
\ No newline at end of file
--
Gitblit v1.9.3