javaandroidandroid-camera2flashlightmorse-code

replay morsecode with flashlight?


I'm trying to build a Morse-Code App which can replay Morse with the built in Flashlight. So I tried a few things, one of them slightly worked, but not how it should.

So essentially I type in a Message, let's say "hello". It translates to

.... . .-.. .-.. ---

Then I want to replay that by tapping a Button. I've tried out different things. This was my first attempt:

 public void onPlayflash(View view) throws InterruptedException, CameraAccessException {
    if (result == null) {
        output.setText("ERROR");
    } else {
        currentposition = 0;
        if (currentposition < result.length()) {
            String c = String.valueOf(result.charAt(0));
            if (c.equals("-")) {
                //timeinmillis = 1000;
                //setTimer();
                flash.setTorchMode(flash.getCameraIdList()[0], true);
                Thread.sleep(2000);
                flash.setTorchMode(flash.getCameraIdList()[0], false);
            } else if (c.equals(".")) {
                //timeinmillis = 500;
                //setTimer();
                flash.setTorchMode(flash.getCameraIdList()[0], true);
                Thread.sleep(1000);
                flash.setTorchMode(flash.getCameraIdList()[0], false);
            } else {
                Thread.sleep(2000);
            }
            currentposition += 1;
        }
    }
}

This didn't work. It just said:

I/Choreographer: Skipped (*always a random number over 1000 here*) frames!  The application may be doing too much work on its main thread.

Then I tried

public void onPlayflash(View view) throws InterruptedException, CameraAccessException {
    if (result == null) {
        output.setText("ERROR");
    } else {
        for (int i = 0; i < result.length(); i++) {
            String c = String.valueOf(result.charAt(i));
            if (c.equals("_")) {
                flash.setTorchMode(flash.getCameraIdList()[0], true);
                Thread.sleep(2000);
                flash.setTorchMode(flash.getCameraIdList()[0], false);
                Thread.sleep(500);
            } else if (c.equals(".")) {
                flash.setTorchMode(flash.getCameraIdList()[0], true);
                Thread.sleep(1000);
                flash.setTorchMode(flash.getCameraIdList()[0], false);
                Thread.sleep(500);

            } else {
                Thread.sleep(1500);
            }
        }
    }
}

This kinda worked, but it still says

I/Choreographer: Skipped (*always a random number over 1000 here*) frames!  The application may be doing too much work on its main thread.

Actually the replay starts fine, but then it starts to struggle and skips parts of the iteration.

As you can see, I also experimented with android.os.CountDownTimer, but that didn't work out aswell. I only got one flash and then it stopped.

As you might see, I'm not that experienced yet '^^ Hope you can help me. Thanks in advance!


Solution

  • try again with CountDownTimer, but using recursion and passing a list of time to wait

    private void test(List<Integer> resultTimeList, Integer count) {
        flash.setTorchMode(flash.getCameraIdList()[0], true);
        new CountDownTimer(resultTimeList.get(count), 500) {
            public void onTick(long millisUntilFinished) {
            }
    
            public void onFinish() {
                new CountDownTimer(500, 500) {
                    public void onTick(long millisUntilFinished) {
                    }
    
                    public void onFinish() {
                        flash.setTorchMode(flash.getCameraIdList()[0], false);
                        test(resultTimeList, count++);
                    }
                }.start();
    
            }
        }.start();
    }