You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

检测到在线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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:20:03