检测到在线JSON新地震数据后,如何为ListView创建系统通知?
实现地震数据更新时的系统通知方案
咱们先梳理整个流程:定时刷新获取最新地震JSON数据 → 对比新旧数据判断是否有更新 → 有新数据时触发系统通知。下面分步骤给你讲具体实现:
一、先搞定新数据的检测逻辑
要判断有没有新地震数据,核心是记录上一次获取的最新地震标识(比如地震ID、发生时间戳),每次刷新后和新数据的最新条目对比。
比如用SharedPreferences来存储上次的最新地震ID:
// 存储上次的最新地震ID fun saveLastEarthquakeId(context: Context, id: String) { val sharedPref = context.getSharedPreferences("EarthquakePrefs", Context.MODE_PRIVATE) with(sharedPref.edit()) { putString("last_earthquake_id", id) apply() } } // 获取上次存储的最新地震ID fun getLastEarthquakeId(context: Context): String? { val sharedPref = context.getSharedPreferences("EarthquakePrefs", Context.MODE_PRIVATE) return sharedPref.getString("last_earthquake_id", null) }
刷新数据后对比:
// 假设你已经从JSON解析得到了地震数据列表earthquakeList val lastId = getLastEarthquakeId(context) val latestEarthquake = earthquakeList.firstOrNull() if (latestEarthquake != null && latestEarthquake.id != lastId) { // 检测到新数据,触发通知 sendEarthquakeNotification(context, latestEarthquake) // 更新存储的最新ID saveLastEarthquakeId(context, latestEarthquake.id) }
二、创建系统通知的核心实现
1. 处理通知权限(Android 13+)
Android 13及以上需要申请POST_NOTIFICATIONS权限,先在Manifest里声明:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
然后在代码里动态申请(比如在App启动时或者第一次刷新前):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED ) { ActivityCompat.requestPermissions( activity, arrayOf(Manifest.permission.POST_NOTIFICATIONS), REQUEST_CODE_NOTIFICATION_PERMISSION ) } }
2. 创建通知渠道(Android 8.0+)
Android 8.0及以上必须创建通知渠道,否则通知无法显示:
private fun createNotificationChannel(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channelId = "earthquake_notification_channel" val channelName = "地震更新通知" val channelDescription = "有新地震数据时推送通知" val importance = NotificationManager.IMPORTANCE_DEFAULT val channel = NotificationChannel(channelId, channelName, importance).apply { description = channelDescription } val notificationManager = context.getSystemService(NotificationManager::class.java) notificationManager.createNotificationChannel(channel) } }
记得在App启动时调用这个方法,比如在Application的onCreate()里。
3. 构建并发送通知
用NotificationCompat来做版本兼容,确保在所有Android版本都能正常显示:
fun sendEarthquakeNotification(context: Context, earthquake: Earthquake) { val channelId = "earthquake_notification_channel" // 创建点击通知后跳转到应用的PendingIntent val intent = Intent(context, MainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } val pendingIntent = PendingIntent.getActivity( context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) // 构建通知内容 val notificationBuilder = NotificationCompat.Builder(context, channelId) .setSmallIcon(R.drawable.ic_earthquake) // 必须设置小图标,否则通知不显示 .setContentTitle("新地震预警") .setContentText("${earthquake.location}发生${earthquake.magnitude}级地震,时间:${earthquake.time}") .setPriority(NotificationCompat.PRIORITY_DEFAULT) .setContentIntent(pendingIntent) .setAutoCancel(true) // 点击通知后自动取消 // 发送通知 NotificationManagerCompat.from(context).notify(1, notificationBuilder.build()) }
这里的Earthquake是你的数据实体类,包含id、location、magnitude、time等字段,根据你的JSON结构调整即可。
三、结合定时刷新的注意点
如果你的定时刷新是在前台用Handler实现的,那上面的逻辑直接放在刷新回调里就行;如果是后台定时任务(比如用WorkManager),要注意后台限制:
- 后台任务中发送通知,同样需要权限和渠道
- 尽量用
WorkManager的PeriodicWorkRequest来实现可靠的定时刷新,避免被系统杀死
这样一套流程下来,就能在检测到新地震数据时自动弹出系统通知啦~
内容的提问来源于stack exchange,提问作者Airborne
相关产品推荐
相关产品推荐

