cloudroam
2025-02-26 b653b90d4598ee2a65bceffa793bb75353b6d186
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
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.ui.home.HomeViewModel
import com.example.firstapp.utils.Log
import com.example.firstapp.workers.KeywordUpdateWorker
import java.util.Calendar
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 permissionRequest = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
        if (isGranted) {
            // 权限授予后注册短信监听器
            registerSmsReceiver()
            syncRecentSms()
        } else {
            // 权限拒绝,提示用户
            Toast.makeText(this, "Permission Denied", 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.READ_SMS) != android.content.pm.PackageManager.PERMISSION_GRANTED) {
            // 请求权限
            permissionRequest.launch(Manifest.permission.READ_SMS)
            syncRecentSms()
        } 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)
 
    }
 
    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"),
                arrayOf("address", "body", "date"),
                "date >= ?",
                arrayOf(threeDaysAgo.toString()),
                "date DESC"
            )
 
            cursor?.use {
                while (cursor.moveToNext()) {
                    val address = cursor.getString(cursor.getColumnIndexOrThrow("address"))
                    val body = cursor.getString(cursor.getColumnIndexOrThrow("body"))
                    val date = cursor.getLong(cursor.getColumnIndexOrThrow("date"))
 
                    // 使用正则表达式提取验证码
                    val regex = "\\d{4,6}".toRegex()
                    val matchResult = regex.find(body)
                    matchResult?.let { result ->
                        val code = result.value
                        // 使用 ViewModel 保存到数据库
                        println("address")
                        println(address)
                        println(code)
                        println(date)
                       // homeViewModel.saveCode(address, code, date)
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(this, "同步短信失败:${e.message}", Toast.LENGTH_SHORT).show()
        }
    }
}