| | |
| | | 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() { |
| | | |
| | |
| | | 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. |
| | |
| | | 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() |
| | | } |
| | | } |
| | | } |