好,所以我有一个更大的应用程序,实际上我不会在这里发布。其中有一个振动事件,虽然从技术上讲它不是一个while循环(该事件应用户要求结束),但循环遍历,并且构成long[] pattern = {0,dot, gap, dash, gap, dot, gap, dot};的值在每次迭代时都会更改,因此设置不是一个选择。

我设置了另一个应用程序来测试有关Vibrator的某些信息。我发现运行静态模式会提供所需的输出,但是将vibrator.vibrate(pattern, 0);方法放入while循环中基本上会破坏任何识别信号的能力。我没有找到任何办法让系统知道手机当前是否在振动,只有它能够振动。因此,我决定将onVibrate嵌套在一个布尔值后面,该方法将最终控制该控件,并且该控件将是一个“暂停”超过模式占用长度的回调。最终看起来像这样:

public class MainActivity extends Activity {
Boolean im_vibrating;
CallBack mCallBack;
Vibrator vibrator;

interface MyCallBack {
    void offSet(Integer span);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mCallBack = new CallBack();
    vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    im_vibrating = false;

    while (true) {
        if (!im_vibrating) {
            im_vibrating = true;
            onVibrate();
        }
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

public void onVibrate () {
    int dot = 200;
    int dash = 500;
    int gap = 200;
    long[] pattern = {
            0,
            dot, gap, dash, gap, dot, gap, dot
    };

    vibrator.vibrate(pattern, -1);
    int span = dot + gap + dash + gap + dot + gap + dot + dot;
    mCallBack.offSet(span);
}

class CallBack implements MyCallBack {

    @Override
    public void offSet(Integer span) {
        final android.os.Handler handler = new android.os.Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                im_vibrating = false;
            }
        }, span);
    }
}


}

但是,尽管没有错误,但这仍然行不通,最终导致某些内容阻塞了布局的呈现,因此显示只是空白,它振动一次,然后再也不振动。尽管onVibrate自动完成mCallBack的事实,SDK仍突出显示offSet表示从未使用过。

最佳答案

在主线程中完成的每个操作(呈现视图并在其中调用活动的操作)必须尽可能地简单。如果不是这种情况,UI将被阻止。

鉴于此,实现所需目标的方法是使用Handler。此类允许您将消息调度到给定线程(在这种情况下为主线程),即使延迟也是如此。

解决方案的一种可能实现:

long[] pattern = new long[]{
            0,
            dot, gap, dash, gap, dot, gap, dot
};
final Handler handler = new Handler();
handler.postDelayed(new Runnable(){
    @Override
    public void run(){
        vibrator.vibrate();
        if(!endVibration){
            handler.postDelayed(this, timeToRun);
        }
    }
}, timeToRun);


这将生成一个循环,可以通过将endVibration变量设置为true来取消该循环,并且不会阻塞UI。

关于java - 如何在Android中循环动态振动模式?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33113737/

10-12 17:18