1
tj
2025-02-27 768f1d38c5357e214e6cff018e57ef7bcb64ee60
app/src/main/java/com/example/firstapp/MainActivity.kt
@@ -18,13 +18,20 @@
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.entity.Item
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() {
@@ -41,23 +48,28 @@
        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
//        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.
@@ -73,59 +85,130 @@
        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 items = listOf(
//            Item(1, "First Item", "This is the first item description"),
//            Item(2, "Second Item", "This is the second item description"),
//            Item(3, "Third Item", "This is the third item description")
//        )
//
//        val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
//        recyclerView.layoutManager = LinearLayoutManager(this)
//        recyclerView.adapter = MyAdapter(items)
//
//        // 初始化适配器
//        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()
//            }
//        }
//        var codeList = Core.code.getAllDesc()
        val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)
//        recyclerView.adapter = MyAdapter(codeList)
        // 初始化适配器
        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)
//        // 注册广播接收器来监听数据更新
//        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()
        }
    }
}