cloudroam
2025-02-28 1097c45d8d6aa4b74a50e8d9a99dedab73f2bbad
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
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 com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.example.firstapp.databinding.ActivityMainBinding
import com.example.firstapp.receiver.SmsReceiver
import android.Manifest
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import com.example.firstapp.activity.LoginActivity
import com.example.firstapp.adapter.MyAdapter
import com.example.firstapp.core.Core
import com.example.firstapp.database.entity.Code
import com.example.firstapp.database.entity.Msg
import com.example.firstapp.entity.Rule
import com.example.firstapp.ui.home.HomeViewModel
import com.example.firstapp.utils.Log
import com.example.firstapp.workers.KeywordUpdateWorker
import java.text.SimpleDateFormat
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.concurrent.TimeUnit
 
class MainActivity : AppCompatActivity() {
 
    private lateinit var binding: ActivityMainBinding
 
    private var smsReceiver:SmsReceiver? = null
 
    private lateinit var adapter: MyAdapter
    private lateinit var homeViewModel: HomeViewModel
 
    private val multiplePermissionRequest = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
        when {
            permissions.getOrDefault(Manifest.permission.RECEIVE_SMS, false) &&
                    permissions.getOrDefault(Manifest.permission.READ_SMS, false) -> {
                // 两个权限都获得授权
                registerSmsReceiver()
                syncRecentSms()
            }
            else -> {
                // 有权限被拒绝
                Toast.makeText(this, "需要短信读取和接收权限才能正常使用功能", Toast.LENGTH_SHORT).show()
            }
        }
    }
 
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
 
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setupViews()
//        binding.btnLogout.setOnClickListener {
//            logout()
//        }
        // 在此位置初始化 homeViewModel
//        homeViewModel = ViewModelProvider(this).get(HomeViewModel::class.java)
//
//        val navView: BottomNavigationView = binding.navView
        val navView = binding.navView
        val navController = findNavController(R.id.nav_host_fragment_activity_main)
 
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications
            )
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)
 
        // 检查权限
        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()
        }
//        val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
//        recyclerView.layoutManager = LinearLayoutManager(this)
//
//        // 初始化适配器
//        adapter = MyAdapter()
//        recyclerView.adapter = adapter
//
//        // 观察 LiveData 数据
//        homeViewModel.codeList.observe(this) { codeList ->
//            // 如果 codeList 为 null,避免闪退
//            if (codeList != null) {
//                adapter.submitList(codeList)
//                // 滚动到顶部
//                recyclerView.scrollToPosition(0)
//            } else {
//                // 如果数据为空,可以显示空列表或其他处理
//                Toast.makeText(this, "No data available", Toast.LENGTH_SHORT).show()
//            }
//        }
 
//        // 注册广播接收器来监听数据更新
//        val filter = IntentFilter("com.example.firstapp.DATA_UPDATED")
//        registerReceiver(object : BroadcastReceiver() {
//            override fun onReceive(context: Context, intent: Intent) {
//                // 数据已更新,刷新 LiveData
//                homeViewModel.loadData()
//            }
//        }, filter)
 
    }
    override fun onSupportNavigateUp(): Boolean {
        val navController = findNavController(R.id.nav_host_fragment_activity_main)
        return navController.navigateUp() || super.onSupportNavigateUp()
    }
    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 setupKeywordUpdate() {
        val updateRequest = PeriodicWorkRequestBuilder<KeywordUpdateWorker>(
            1, TimeUnit.HOURS,  // 每小时更新一次
            15, TimeUnit.MINUTES  // 灵活时间窗口
        ).build()
 
        WorkManager.getInstance(this).enqueueUniquePeriodicWork(
            "keyword_update", ExistingPeriodicWorkPolicy.REPLACE, updateRequest
        )
    }
 
    private fun setupViews() {
        // 获取并显示当前登录的手机号
        val phone =
            getSharedPreferences("user_info", Context.MODE_PRIVATE).getString("phone", "") ?: ""
 
//        binding.apply {
//            tvPhone.text = "当前登录手机号:$phone"
//        }
    }
 
    private fun logout() {
        // 清除登录信息
        getSharedPreferences("user_info", Context.MODE_PRIVATE)
            .edit()
            .clear()
            .apply()
 
        // 跳转回登录页
        startActivity(Intent(this, LoginActivity::class.java))
        finish()
    }
 
    private fun syncRecentSms() {
        try {
            val calendar = Calendar.getInstance()
            calendar.add(Calendar.DAY_OF_YEAR, -3) // 获取3天前的时间
            val threeDaysAgo = calendar.timeInMillis
 
            val cursor = contentResolver.query(
//                Uri.parse("content://sms/sent"), //发送短信
                Uri.parse("content://sms/inbox"),
                arrayOf("address", "body", "date"),
                "date >= ?",
                arrayOf(threeDaysAgo.toString()),
                "date DESC"
            )
 
            cursor?.use {
                while (cursor.moveToNext()) {
                    //手机号
                    val address = cursor.getString(cursor.getColumnIndexOrThrow("address"))
                    //短信内容
                    val messageBody = cursor.getString(cursor.getColumnIndexOrThrow("body"))
                    //短信时间
                    val datetime = cursor.getLong(cursor.getColumnIndexOrThrow("date"))
                    // 这里我要写个数组,并创建个对象存放一些内容,如这个对象的属性有匹配内容,正则表达式,并循环遍历
                    val ruleList = mutableListOf(
                        Rule("快递","京东","\\d{6}"),
                        Rule("快递","菜鸟","\\d{1,2}-\\d{1,2}-\\d{4}")
                    )
                    for (rule in ruleList) {
                        val code = rule.extractCodeFromMessage(messageBody.toString())
                        if (code!==null) {
 
                            // 转换为 Date 对象
                            val date = Date(datetime)
                            // 如果需要格式化显示
                            val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
                            val dateString = sdf.format(date)
                            val existingCode = Core.code.queryByTypeAndCodeAndDate(rule.content, code, dateString)
                            if (existingCode == null) {
                                android.util.Log.d("SmsReceiver", "Received SMS code: ${code}")
                                val msg = Msg(0, "1111", "111111", messageBody.toString(), 1, "111", 1, 1)
                                val msgId = Core.msg.insert(msg)
                                val code = Code(0, rule.type, 1, rule.content, 1, 1, msgId, code, dateString, "中通")
                                Core.code.insert(code)
                                android.util.Log.d("SMS_DEBUG", "历史短信已保存到数据库")
                            }else{
                                android.util.Log.d("SmsReceiver", "Received SMS code: 已存在相同记录,不保存")
                            }
                        }else{
                            android.util.Log.d("SmsReceiver", "Received SMS code: 没有匹配到历史短信内容")
                        }
                    }
                    // 发送广播通知数据已更新
                    val updateIntent = Intent("com.example.firstapp.DATA_UPDATED")
                    sendBroadcast(updateIntent)
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(this, "同步短信失败:${e.message}", Toast.LENGTH_SHORT).show()
        }
    }
}