如何在安卓编程中通过程序使设备振动n次?

12

有人能告诉我如何让手机振动5次,每次振动的模式都与以下代码相同:

long[] pattern = { 0, 200, 500 };

我希望这个模式重复5次。

Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(pattern , 5);

好的,这段代码能正常工作吗?你试过了吗? - Vladimir Ivanov
9个回答

23

我找到了解决方案,非常简单:

long[] pattern = { 0, 100, 500, 100, 500, 100, 500, 100, 500, 100, 500};
vibrator.vibrate(pattern , -1);

看起来像是黑客 ^^ - Anis LOUNIS aka AnixPasBesoin
很棒的黑客技巧,不错 :) - Ramkesh Yadav
1
为什么这是一个hack?有一个模式参数和一个重复参数的数量。vibrate(...)方法的文档说:“要使模式重复,请传递到模式数组中开始重复的索引,或者传递-1以禁用重复”。一切都按照文档完成。 - Johnny Five

5

来自:Android Vibrator#vibrate(long[], int)

若要使模式重复,请传递模式数组中启动重复的索引,或传递-1以禁用重复。

您必须初始化索引0。

long[] pattern = { 0, 100, 500, 100, 500, 100, 500, 100, 500, 100, 500};
vibrator.vibrate(pattern , 0);

4
以下对我有效:
if(vibration_enabled) {
    final Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    if(v.hasVibrator()) {
        final long[] pattern = {0, 1000, 1000, 1000, 1000};
        new Thread(){
            @Override
            public void run() {
                for(int i = 0; i < 5; i++){ //repeat the pattern 5 times
                    v.vibrate(pattern, -1);
                    try {
                       Thread.sleep(4000); //the time, the complete pattern needs
                    } catch (InterruptedException e) {
                        e.printStackTrace();  
                    }
                }
            }
        }.start();
    }
}

vibrate方法只是启动了振动,但不会等待其执行。


看起来又是一个黑客攻击。vibrate()方法的第二个参数是用来做什么的? - Anis LOUNIS aka AnixPasBesoin
1
vibrate-method的文档,第二个参数:重复次数,-1表示不重复。 - rbs
不好的做法!不需要运行循环来实现振动器的重复。 - Mayank Sharma

3
您的代码应该可以解决问题。只需确保在AndroidManifest.xml文件中添加以下代码:<uses-permission android:name="android.permission.VIBRATE"/>。请注意不要修改HTML标签。

已经可以工作了,但我不知道如何让它振动n次,比如在运行时选择5次,那么它应该振动5次... - Gkapoor
1
for(int i = 0; i < n; i++) vibrator.vibrate(pattern, -1); - Gabriel Negut

2
除了上述提供的解决方案外,我创建了自己的振动模式,可以控制振动之间的持续时间大小。 startVibration() 会创建一个连续的正常振动模式,持续一分钟。
stopVibration() - 终止振动或暂停计数器计时器,从而暂停振动模式。
private time = 0;
private countDownTimer;

private void startVibration() {
    time = (int) System.currentTimeMillis();

    countDownTimer = new CountDownTimer(60000, 1000) {

        public void onTick(long millisUntilFinished) {

            time = (int) (millisUntilFinished / 1000);
            int[] timeLapse = {58, 55, 52, 49, 46, 43, 40, 37, 34, 31, 28, 25, 22, 19, 16, 13, 10, 7, 4, 1};
            for (int k = 0; k < timeLapse.length; k++) {
                if (time == timeLapse[k]) {
                    ((Vibrator) getSystemService(VIBRATOR_SERVICE)).vibrate(1000);
                }
            }
        }

        public void onFinish() {
        }
    }.start();
}

private void stopVibration() {
    if (countDownTimer != null) {
        countDownTimer.cancel();
    }
}

0
    long vibrationDuration = Arrays.stream(pattern).sum();
    new CountDownTimer(vibrationDuration*(repeat+1), vibrationDuration) {

        @Override
        public void onTick(long millisUntilFinished) {
            v.cancel();
            if (Build.VERSION.SDK_INT >= 26) {
                VibrationEffect vibrationEffect = VibrationEffect.createWaveform(pattern, -1);
                v.vibrate(vibrationEffect);
            } else {
                v.vibrate(pattern, -1);
            }
        }

        @Override
        public void onFinish() {
            v.cancel();
        }
    }.start();

这里括号和圆括号不平衡,对吧? - 1737973

0
这是我的做法。我根据调用者想要振动的次数动态生成时间数组。在循环中,从1开始以避免0%2在最后引起额外的无用延迟。
private void vibrate(int times)
{
    Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
    {
        ArrayList<Long> timings = new ArrayList();

        timings.add(0L);

        for(int i = 1; i <= times; i ++)
        {

            if(i%2==0)
                timings.add(0L);

            timings.add(250L);


        }

        long[] arrTimings = new long[timings.size()];

        for(int j = 0; j < timings.size(); j++)
        {
            arrTimings[j] = timings.get(j);
        }

        vibrator.vibrate(VibrationEffect.createWaveform(arrTimings, -1));
    }
}

0

你可以使用一个技巧,根据你想要的重复次数动态构建模式。

private long[] createVibrationPattern(long[] oneShotPattern, int repeat) {
    long[] repeatPattern = new long[oneShotPattern.length * repeat];
    System.arraycopy(oneShotPattern, 0, repeatPattern, 0, oneShotPattern.length);
    for (int count = 1; count < repeat; count++) {
        repeatPattern[oneShotPattern.length * count] = 500; // Delay in ms, change whatever you want for each repition
        System.arraycopy(oneShotPattern, 1, repeatPattern, oneShotPattern.length * count + 1, oneShotPattern.length - 1);
    }
    return repeatPattern;
}

然后像下面这样进行调用

long[] pattern = { 0, 200, 500 };
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(createVibrationPattern(pattern , 2);

输出 模式将变为0、200、500、500、0、200、500


0
在方法public void vibrate(long [] pattern, int repeat)中,long []模式遵循规则:long []模式= {pauseTime1,vibrationTime1,pauseTime2,vibrationTime2,pauseTime3,vibrationTime3,...}。如果结果是奇数个值,则不起作用。您必须以vibrationTime结束模式。偶数数量的值可以完成工作(至少4个值)。
long[] pattern = {0, 500, 200, 500}
Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(pattern , 5);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接