cloudroam
2025-04-15 3466799c94227c5ebba9fb201621e745058867ee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
package com.example.firstapp
 
import android.content.IntentFilter
import android.os.Bundle
import android.provider.Telephony
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController
import com.example.firstapp.databinding.ActivityMainBinding
import com.example.firstapp.receiver.SmsReceiver
import android.Manifest
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import androidx.annotation.RequiresApi
import com.example.firstapp.activity.LoginActivity
import com.example.firstapp.core.Core
import com.example.firstapp.database.entity.Code
import com.example.firstapp.database.entity.Msg
import com.example.firstapp.database.service.RetrofitClient
import com.example.firstapp.database.service.RetrofitModelClient
import com.example.firstapp.utils.Log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
 
class MainActivity : AppCompatActivity() {
    // 安全防护关键词数组
    private var securityKeywordsList = emptyList<String>()
 
    private lateinit var binding: ActivityMainBinding
 
    private var smsReceiver: SmsReceiver? = null
 
    private val multiplePermissionRequest =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
            when {
                permissions.getOrDefault(
                    Manifest.permission.RECEIVE_SMS,
                    false
                ) && permissions.getOrDefault(Manifest.permission.READ_SMS, false) -> {
                    // 两个权限都获得授权
                    registerSmsReceiver()
                }
 
                else -> {
                    // 有权限被拒绝
                    Toast.makeText(
                        this, "需要短信读取和接收权限才能正常使用功能", Toast.LENGTH_SHORT
                    ).show()
                }
            }
        }
 
    private val syncLock = Object()
 
    @RequiresApi(Build.VERSION_CODES.O)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
 
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setupViews()
        val navView = binding.navView
        val navController = findNavController(R.id.nav_host_fragment_activity_main)
 
        // 只保留底部导航的设置
        navView.setupWithNavController(navController)
 
        // 重置提醒计划并检查是否有错过的提醒
        resetReminders()
        
        // 检查权限
        if (ContextCompat.checkSelfPermission(
                this, Manifest.permission.RECEIVE_SMS
            ) != android.content.pm.PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(
                this, Manifest.permission.READ_SMS
            ) != android.content.pm.PackageManager.PERMISSION_GRANTED
        ) {
            // 同时请求两个权限
            multiplePermissionRequest.launch(
                arrayOf(
                    Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS
                )
            )
        } else {
            // 权限已经授予,继续执行相关操作
            registerSmsReceiver()
            syncRecentSms()
        }
    }
 
    private fun registerSmsReceiver() {
//        应用启动时执行 registerSmsReceiver()
//        创建 SmsReceiver 实例
//        注册广播接收器,开始监听短信
//        等待新短信到达
//        新短信到达时,系统发送广播
//        SmsReceiver 的 onReceive 方法被调用
//        处理短信内容
//        发送数据更新广播
//        MainActivity 接收到更新广播
//        更新 UI
        Log.d("SMS_DEBUG", "MainActivity收到数据更新广播")
        smsReceiver = SmsReceiver()
        val filter = IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)
        registerReceiver(smsReceiver, filter)
    }
 
    private fun setupViews() {
        // 获取并显示当前登录的手机号
        getSharedPreferences("user_info", Context.MODE_PRIVATE).getString("phone", "") ?: ""
    }
 
    private fun logout() {
        // 清除登录信息
        getSharedPreferences("user_info", Context.MODE_PRIVATE).edit().clear().apply()
 
        // 跳转回登录页
        startActivity(Intent(this, LoginActivity::class.java))
        finish()
    }
 
    // 初始化禁用词
    @RequiresApi(Build.VERSION_CODES.O)
    private fun initializeSecurityKeywords() {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val response = RetrofitClient.apiService.getSecurityList()
                if (response.code == 200) {
                    securityKeywordsList = response.data.map { it.keyword }
                    android.util.Log.d(
                        "MainActivity", "securityKeywordsList: $securityKeywordsList"
                    )
                    // 确保在主线程中调用 syncRecentSms
                    runOnUiThread {
                        syncRecentSms()
                    }
                } else {
                    android.util.Log.e(
                        "MainActivity", "Failed to get security list: ${response.code}"
                    )
                }
            } catch (e: Exception) {
                android.util.Log.e("MainActivity", "Error fetching security list", e)
            }
        }
    }
 
    @RequiresApi(Build.VERSION_CODES.O)
    private fun syncRecentSms() {
        try {
            val calendar = Calendar.getInstance()
            calendar.add(Calendar.DAY_OF_YEAR, -3)
            val threeDaysAgo = calendar.timeInMillis
 
            val cursor = contentResolver.query(
                Uri.parse("content://sms/inbox"),
                arrayOf("address", "body", "date"),
                "date >= ?",
                arrayOf(threeDaysAgo.toString()),
                "date DESC"
            )
 
            cursor?.use {
                while (cursor.moveToNext()) {
                    val messageBody = cursor.getString(cursor.getColumnIndexOrThrow("body"))
                    val datetime = cursor.getLong(cursor.getColumnIndexOrThrow("date"))
                    
                    // 转换为 Date 对象
                    val date = Date(datetime)
                    val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
                    val dateString = sdf.format(date)
 
                    // 保存原始短信
                    val msg = Msg(0, "1111", "111111", messageBody, 1, "111", 1, 1)
                    val msgId = Core.msg.insert(msg)
 
                    // 禁用关键词拦截
//                    if (securityKeywordsList.any { it in messageBody }) {
//                        android.util.Log.d("MainActivity", "历史短信含有禁用关键词,跳过处理")
//                        continue
//                    }
 
                    // 使用协程处理API调用和数据库操作
                    CoroutineScope(Dispatchers.IO).launch {
                        try {
                            val response = RetrofitModelClient.modelService.processSms(mapOf("content" to messageBody))
                            
                            synchronized(syncLock) {
                                if (response.status == "success") {
                                    when (response.data.category) {
                                        "快递" -> {
                                            val pickupCode = response.data.details.pickupCode ?: ""
                                            if (pickupCode.isNotEmpty()) {
                                                val existingCode = Core.code.queryByTypeAndCodeAndDate(
                                                    response.data.category,
                                                    pickupCode,
                                                    dateString
                                                )
 
                                                if (existingCode == null) {
                                                    val code = Code(
                                                        id = 0,
                                                        category = response.data.category,
                                                        categoryId = 1,
                                                        typeId = 1,
                                                        ruleId = 1,
                                                        msgId = msgId,
                                                        createTime = dateString,
                                                        oneLevel = response.data.details.post ?: "",
                                                        secondLevel = response.data.details.company ?: "",
                                                        code = pickupCode,
                                                        pickup = 0,
                                                        pickupTime = "",
                                                        overTime = "",
                                                        address = response.data.details.address ?: "",
                                                        remarks = response.data.details.time ?: "",
                                                    )
//                                                    if(code.oneLevel.isNotEmpty() && code.secondLevel.isNotEmpty() && code.code.isNotEmpty()) {
                                                    if(code.oneLevel.isNotEmpty()  && code.code.isNotEmpty()) {
                                                        Core.code.insert(code)
                                                        android.util.Log.d("MainActivity", "历史快递短信已保存: $pickupCode")
                                                    }
                                                } else {
                                                    android.util.Log.d("MainActivity", "发现重复快递短信,跳过保存: $pickupCode")
                                                }
                                            }
                                        }
                                        "还款" -> {
                                            val amount = response.data.details.amount ?: ""
                                            if (amount.isNotEmpty()) {
                                                val existingCode = Core.code.queryByTypeAndCodeAndDate(
                                                    response.data.category,
                                                    amount,
                                                    dateString
                                                )
 
                                                if (existingCode == null) {
                                                    val code = Code(
                                                        id = 0,
                                                        category = response.data.category,
                                                        categoryId = 2,
                                                        typeId = 1,
                                                        ruleId = 2,
                                                        msgId = msgId,
                                                        createTime = dateString,
                                                        oneLevel = response.data.details.type ?: "",
                                                        secondLevel = response.data.details.bank ?: "",
                                                        code = amount,
                                                        pickup = 0,
                                                        pickupTime = "",
                                                        overTime = response.data.details.date ?: "",
                                                        address = response.data.details.address ?: "",
                                                        remarks = "最小还款金额${response.data.details.min_amount}还款卡号${response.data.details.number}"
                                                    )
                                                    if(code.oneLevel.isNotEmpty() && code.secondLevel.isNotEmpty() && code.code.isNotEmpty()) {
                                                        Core.code.insert(code)
                                                        android.util.Log.d("MainActivity", "历史还款短信已保存: $amount")
                                                    }
                                                } else {
                                                    android.util.Log.d("MainActivity", "发现重复还款短信,跳过保存: $amount")
                                                }
                                            }
                                        }
                                        "收入" -> {
                                            val amount = response.data.details.amount ?: ""
                                            if (amount.isNotEmpty()) {
                                                val existingCode = Core.code.queryByTypeAndCodeAndDate(
                                                    response.data.category,
                                                    amount,
                                                    dateString
                                                )
 
                                                if (existingCode == null) {
                                                    val code = Code(
                                                        id = 0,
                                                        category = response.data.category,
                                                        categoryId = 3, // 3-收入类型
                                                        typeId = 1,     //暂时没有根据type分类
                                                        ruleId = 2,     //1-还款类型
                                                        msgId = msgId,
                                                        createTime = dateString,
                                                        oneLevel = response.data.details.bank ?: "",
                                                        secondLevel = response.data.details.bank ?: "",
                                                        code = amount,
                                                        pickup = 0, // 0-未取件,1-已取件
                                                        pickupTime = "", // 取件时间为空
                                                        overTime = response.data.details.datetime
                                                            ?: "",  // 超时时间为空,暂时没有这块处理逻辑
                                                        address = response.data.details.address ?: "",
                                                        remarks = "余额" + response.data.details.balance ?: "",
                                                    )
                                                    if(code.oneLevel.isNotEmpty() && code.secondLevel.isNotEmpty() && code.code.isNotEmpty()) {
                                                        Core.code.insert(code)
                                                        android.util.Log.d("MainActivity", "历史还款短信已保存: $amount")
                                                    }
                                                } else {
                                                    android.util.Log.d("MainActivity", "发现重复还款短信,跳过保存: $amount")
                                                }
                                            }
                                        }
                                    }
 
                                    // 发送广播通知数据已更新
                                    val updateIntent = Intent("com.example.firstapp.DATA_UPDATED")
                                    sendBroadcast(updateIntent)
                                }
                            }
                        } catch (e: Exception) {
                            android.util.Log.e("MainActivity", "处理历史短信出错: ${e.message}", e)
                        }
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(this, "同步短信失败:${e.message}", Toast.LENGTH_SHORT).show()
        }
    }
 
    // 重置提醒计划
    private fun resetReminders() {
        try {
            // 取消所有现有的提醒任务
            androidx.work.WorkManager.getInstance(this).cancelAllWorkByTag("reminder_worker")
            
            // 清除旧的提醒偏好设置
            getSharedPreferences("reminder_prefs", Context.MODE_PRIVATE).edit().clear().apply()
            
            // 重新设置提醒任务
            (application as App).setupReminderWorker()
            
            // 检查是否有错过的提醒
            com.example.firstapp.service.ReminderWorker.checkMissedReminders(this)
            
            android.util.Log.d("MainActivity", "已重置提醒计划")
        } catch (e: Exception) {
            android.util.Log.e("MainActivity", "重置提醒计划失败: ${e.message}")
        }
    }
}