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

Android应用在后台/锁屏状态下如何实现自定义重复振动?

解决Android锁屏/后台状态下自定义振动不生效的问题

当应用处于后台或设备锁屏时,直接调用Vibrator的vibrate方法会被系统的后台限制策略拦截,只能触发系统默认通知振动。要实现锁屏/后台下的自定义振动,核心是将自定义振动与通知渠道绑定,让系统托管通知的振动逻辑,而非直接调用振动API。

具体解决方案步骤:

1. 声明必要权限

在AndroidManifest.xml中添加权限:

<!-- 振动权限 -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- Android 13+ 通知权限 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

2. 创建带自定义振动的通知渠道

Android 8.0(API 26)及以上,通知的行为由渠道控制。创建渠道时指定自定义振动波形:

private fun createNotificationChannel(context: Context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val channelId = "custom_vibration_channel"
        val channelName = "自定义振动通知"
        val channelDescription = "使用自定义振动模式的通知渠道"
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        
        // 定义自定义振动波形:[等待时间, 振动时长, 等待时间, 振动时长], 遵循你原代码的模式
        val vibrationPattern = longArrayOf(0L, 300L, 500L, 300L)
        
        val channel = NotificationChannel(channelId, channelName, importance).apply {
            description = channelDescription
            setVibrationPattern(vibrationPattern)
            enableVibration(true)
        }
        
        val notificationManager = context.getSystemService(NotificationManager::class.java)
        notificationManager.createNotificationChannel(channel)
    }
}

3. 发送关联该渠道的通知

当需要触发振动时,发送绑定了上述渠道的通知,系统会自动执行渠道设置的自定义振动,无论应用状态如何:

private fun sendCustomVibrationNotification(context: Context) {
    val channelId = "custom_vibration_channel"
    val notificationBuilder = NotificationCompat.Builder(context, channelId)
        .setSmallIcon(R.drawable.ic_notification)
        .setContentTitle("周期性通知")
        .setContentText("触发自定义振动")
        .setPriority(NotificationCompat.PRIORITY_DEFAULT)
        .setAutoCancel(true)

    val notificationManager = NotificationManagerCompat.from(context)
    // 检查Android 13+的通知权限
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
        ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED
    ) {
        return
    }
    notificationManager.notify(System.currentTimeMillis().toInt(), notificationBuilder.build())
}

4. 实现周期性触发

如果需要周期性发送通知,推荐使用WorkManager(适合长期周期性任务,不受系统重启影响):

// 设置周期性任务
private fun schedulePeriodicNotification(context: Context) {
    val periodicWorkRequest = PeriodicWorkRequestBuilder<NotificationWorker>(15, TimeUnit.MINUTES)
        .build()
    WorkManager.getInstance(context).enqueueUniquePeriodicWork(
        "periodic_custom_vibration",
        ExistingPeriodicWorkPolicy.REPLACE,
        periodicWorkRequest
    )
}

// 定义Worker类执行通知发送
class NotificationWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
    override fun doWork(): Result {
        sendCustomVibrationNotification(applicationContext)
        return Result.success()
    }
}

关键注意事项:

  • 振动模式的循环逻辑:setVibrationPattern会按你定义的数组循环,若需要重复振动,可调整数组或结合通知的重复逻辑实现。
  • 用户设备设置:需确保设备总振动开关开启,且对应通知渠道的振动未被手动关闭。
  • 版本适配:不同Android版本的权限、通知渠道逻辑有差异,务必做好版本判断。

内容的提问来源于stack exchange,提问作者Martim Gouveia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 16:10:28