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

如何在Android应用内通过编程控制通知振动的开启与关闭

应用内编程控制通知振动的实现方案

核心问题分析

你的现有代码已经在创建通知渠道时根据SharedPreferences设置了振动,但存在两个关键问题:

  • Android O+ 中,createNotificationChannel仅在渠道首次创建时生效,后续修改振动开关不会更新已存在的渠道配置
  • Android 7.1及以下版本,setDefaults(Notification.DEFAULT_ALL)会强制启用默认振动,没有根据开关控制

完整修复方案

1. 封装振动开关的更新逻辑(兼容全版本)

先实现一个统一处理通知渠道振动配置的方法,确保开关变更能实时生效:

// 更新Android O+通知渠道的振动设置
private void updateNotificationChannelVibration(boolean isVibrateEnabled) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationChannel channel = notificationManager.getNotificationChannel(CHANNEL_ID);
        if (channel != null) {
            channel.enableVibration(isVibrateEnabled);
            channel.setVibrationPattern(isVibrateEnabled ? new long[]{0, 1000, 500, 1000} : null);
            notificationManager.updateNotificationChannel(channel);
        }
    }
}

// 保存振动开关状态并同步更新配置
public void toggleNotificationVibration(boolean isEnabled) {
    SharePrefUtils.putBoolean(Constant_ad.IS_VIBRATE, isEnabled);
    updateNotificationChannelVibration(isEnabled);
}

2. 修改原通知创建方法

调整setNotification方法,适配全版本的振动控制逻辑:

private void setNotification(String reminderTitle, String reminderId) {
    int num = Integer.parseInt(SharePrefUtils.getString(Constant_ad.currentNotificationId, "0"));
    num++;
    SharePrefUtils.putString(Constant_ad.currentNotificationId, String.valueOf(num));

    NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
    NotificationCompat.Builder notificationBuilder;
    boolean isVibrateEnabled = SharePrefUtils.getBoolean(Constant_ad.IS_VIBRATE, false);
    Log.e("getVibrateStatus", isVibrateEnabled + "");

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        // 检查渠道是否存在,不存在则创建,存在则直接使用已更新的配置
        NotificationChannel notificationChannel = notificationManager.getNotificationChannel(CHANNEL_ID);
        if (notificationChannel == null) {
            notificationChannel = new NotificationChannel(CHANNEL_ID, getString(R.string.channel_name)
                    , NotificationManager.IMPORTANCE_HIGH);
            notificationChannel.setDescription(getString(R.string.channel_description));
            notificationChannel.enableLights(true);
            notificationChannel.setLightColor(Color.RED);
            notificationChannel.enableVibration(isVibrateEnabled);
            if (isVibrateEnabled) {
                notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
            }
            notificationManager.createNotificationChannel(notificationChannel);
        }
    }

    notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);

    // 低版本振动控制:替换DEFAULT_ALL,按需组合默认项
    int defaults = Notification.DEFAULT_LIGHTS; // 保留灯光默认
    if (isVibrateEnabled) {
        defaults |= Notification.DEFAULT_VIBRATE;
    }
    // 如需默认声音可添加:defaults |= Notification.DEFAULT_SOUND

    notificationBuilder.setAutoCancel(true)
            .setDefaults(defaults)
            .setWhen(System.currentTimeMillis())
            .setSmallIcon(R.mipmap.ic_launcher)
            .setPriority(Notification.PRIORITY_MAX)
            .setContentTitle(getString(R.string.notification_ctitle))
            .setContentText(reminderTitle);

    // PendingIntent逻辑保持不变
    Intent notifyIntent = new Intent(this, RemindersActivity.class);
    notifyIntent.putExtra("type", "notificationData");
    notifyIntent.putExtra("id", reminderId);
    notifyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

    int contentIntentFlags = PendingIntent.FLAG_CANCEL_CURRENT;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        contentIntentFlags |= PendingIntent.FLAG_IMMUTABLE;
    PendingIntent pendingIntent = PendingIntent.getActivity(this, num
            , notifyIntent, contentIntentFlags);
    notificationBuilder.setContentIntent(pendingIntent);

    notificationManager.notify(num, notificationBuilder.build());
}

3. 触发振动开关切换

在设置界面的开关控件中,调用toggleNotificationVibration即可完成开关切换:

// 示例:开关按钮的状态变更监听
vibrateSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
    toggleNotificationVibration(isChecked);
});

关键说明

  • Android O+ 渠道更新:必须使用updateNotificationChannel修改已存在的渠道配置,createNotificationChannel仅在首次创建时生效
  • 低版本振动控制:避免使用DEFAULT_ALL,手动组合需要的默认项,确保振动开关能精准控制
  • 实时生效:开关变更后,后续发出的通知会立即应用新的振动设置,已发出的通知不受影响

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 15:47:33