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

安卓盲人应用运行时屏蔽外部振动的Java编程实现问询

Hey there! Let's tackle this problem of blocking all external vibrations when your Android app for visually impaired users is running. This is a crucial feature to keep your app's vibration patterns from being interrupted, so let's break down how to do it with Java.

First off, let's get the basics out of the way—Android's vibration system has a few moving parts: system notifications, third-party app vibrations, and your app's own vibration triggers. To lock down everything except your app, we'll cover two main approaches: global vibration control and targeted notification vibration blocking.

1. Required Permissions

First, you'll need to add the right permissions to your AndroidManifest.xml—these are non-negotiable for controlling vibration and accessing notifications:

<!-- Core permission to control vibration hardware -->
<uses-permission android:name="android.permission.VIBRATE" />
<!-- Android 13+ permission for notification-related actions -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- Permission to access and modify notification policies -->
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />

2. Method 1: Temporarily Disable Global Vibration

This approach is straightforward: we'll turn off the system's global vibration when your app is in the foreground, then switch it back when the user leaves. The bonus? Your app can still trigger vibrations even with global vibration disabled (thanks to the VIBRATE permission).

Step-by-Step Implementation

Create a reusable manager class to handle the vibration state:

import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
import android.os.Vibrator;
import android.os.VibratorManager;

public class VibrationController {
    private final AudioManager audioManager;
    private int originalRingerMode;
    private final Context appContext;

    public VibrationController(Context context) {
        appContext = context.getApplicationContext();
        audioManager = (AudioManager) appContext.getSystemService(Context.AUDIO_SERVICE);
    }

    // Call this when your app comes to the foreground
    public void blockExternalVibrations() {
        // Save the user's original ring/vibration mode to restore later
        originalRingerMode = audioManager.getRingerMode();
        // Switch to silent mode (no ring, no vibration for system/other apps)
        audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
    }

    // Call this when your app goes to the background
    public void restoreNormalVibrations() {
        audioManager.setRingerMode(originalRingerMode);
    }

    // Trigger your app's custom vibration
    public void triggerAppVibration(long durationMs) {
        Vibrator vibrator;
        // Handle Android 12+ API changes
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            VibratorManager vibratorManager = appContext.getSystemService(VibratorManager.class);
            vibrator = vibratorManager.getDefaultVibrator();
        } else {
            vibrator = (Vibrator) appContext.getSystemService(Context.VIBRATOR_SERVICE);
        }

        if (vibrator.hasVibrator()) {
            // On some devices, we might need a temporary mode switch to ensure vibration works
            int tempMode = audioManager.getRingerMode();
            audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
            
            vibrator.vibrate(durationMs);
            
            // Restore the silent mode after vibration ends
            vibrator.cancel();
            audioManager.setRingerMode(tempMode);
        }
    }
}

Hook this into your app's lifecycle (e.g., in your main Activity):

private VibrationController vibrationController;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    vibrationController = new VibrationController(this);
}

@Override
protected void onResume() {
    super.onResume();
    // Block external vibrations when app is visible
    vibrationController.blockExternalVibrations();
}

@Override
protected void onPause() {
    super.onPause();
    // Restore normal vibration when app is hidden
    vibrationController.restoreNormalVibrations();
}

3. Method 2: Precisely Block Notification Vibrations

If you don't want to disable all global vibration (maybe users still want their phone to vibrate for calls), you can instead intercept just notification vibrations from other apps using a NotificationListenerService. This lets you leave global vibration on but stop other apps' notifications from vibrating.

Step-by-Step Implementation

First, create the service class:

import android.app.Notification;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;

public class NotificationVibrationBlocker extends NotificationListenerService {
    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        super.onNotificationPosted(sbn);
        // Skip blocking vibrations for your own app's notifications
        if (!sbn.getPackageName().equals(getPackageName())) {
            // Modify the incoming notification to remove vibration
            Notification.Builder modifiedNotification = Notification.Builder.recoverBuilder(this, sbn.getNotification());
            modifiedNotification.setVibrate(null);
            
            // Update the notification with the vibration removed
            try {
                notify(sbn.getKey(), modifiedNotification.build());
            } catch (SecurityException e) {
                e.printStackTrace();
            }
        }
    }
}

Register the service in your AndroidManifest.xml:

<service
    android:name=".NotificationVibrationBlocker"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>

Important: Users have to manually grant your app "Notification Access" in system settings for this to work. Add a prompt to guide them:

// Trigger this when your app first launches or when the feature is enabled
Intent notificationAccessIntent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
startActivity(notificationAccessIntent);

4. Key Considerations

  • Compatibility: The code above handles Android 12+ API changes with VibratorManager and older versions with Vibrator.
  • User Trust: Disabling global vibration might make users miss important alerts—be transparent! Tell users what your app is doing, and add a toggle to let them turn this feature on/off if they want.
  • Permission Limitations: The notification access permission can't be granted automatically, so make sure your app clearly explains why it needs this access.
  • Background Restrictions: Android's background limits might kill the NotificationListenerService after a while. Avoid aggressive keep-alive tactics—instead, remind users to whitelist your app if they run into issues.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:43:32