본문 바로가기

개발/Android

[손전등 어플 만들기 #3] 모스부호 변환하여 깜빡이기 (TreeMap, TextView 예제)

문자열을 입력받아 해당 문자열을 모스부호로 변경하고, 대시, 닷, 공백에 따라 깜빡임 속도를 조절해보았다.

우선 입력받을 문자를 키로, 해당되는 모스부호를 값으로 Map에 넣어준다.

  static {
        map = new TreeMap<Character, String>();
        map.put(' ', " ");
        map.put('A', ".-");
        map.put('B', "-...");
        map.put('C', "-.-.");
        map.put('D', "-..");
        map.put('E', ".");
        map.put('F', "..-.");
        map.put('G', "--.");
        map.put('H', "....");
        map.put('I', "..");
        map.put('J', ".---");
        map.put('K', "-.-");
        map.put('L', ".-..");
        map.put('M', "--");
        map.put('N', "-.");
        map.put('O', "---");
        map.put('P', ".--.");
        map.put('Q', "--.-");
        map.put('R', ".-.");
        map.put('S', "...");
        map.put('T', "-");
        map.put('U', "..-");
        map.put('V', "...-");
        map.put('W', ".--");
        map.put('X', "-..-");
        map.put('Y', "-.--");
        map.put('Z', "--..");
        map.put('1', ".----");
        map.put('2', "..---");
        map.put('3', "...--");
        map.put('4', "....-");
        map.put('5', ".....");
        map.put('6', "-....");
        map.put('7', "--...");
        map.put('8', "---..");
        map.put('9', "----.");
        map.put('0', "-----");
        map.put('.', ".-.-.-");
        map.put(',', "--..--");
        map.put('?', "..--..");
        map.put('!', "-.-.--");
        map.put('-', "-....-");
        map.put('/', "-..-.");
        map.put('@', ".--.-.");
    }

 

단, TextView 의 입력받을 문자로, 영어와 숫자만 입력하게 하였다.

        inputText.setFilters(new InputFilter[]{new InputFilter() {
            @Override
            public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                for (int i = start; i < end; i++) {
                    Pattern ps = Pattern.compile("^[a-zA-Z0-9]*$");
                    if (!ps.matcher(source).matches()) {
                        return "";
                    }
                }
                return null;
            }
        }});

 

TextView에 변환하고 싶은 문자열을 입력받은 뒤 convert 버튼을 눌러 모스부호로 변환하고, Blinck 버튼을 통해 깜빡임 제어를 해준다.

 

하기는 전체 소스 및 XML 

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputFilter;
import android.text.Spanned;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.TreeMap;
import java.util.regex.Pattern;

public class MorseActivity extends Activity {
    final static String TAG = "MORSE";
    private int morseDot = 200;
    MorseThread morseThread;
    private boolean convertButtonOn = false;

    String beforeMorse = "";
    String convertedMorse = "";
    final static String dash = "-";
    final static String dot = ".";
    final static String gap = " ";

    final static TreeMap<Character, String> map;

    static {
        map = new TreeMap<Character, String>();
        map.put(' ', " ");
        map.put('A', ".-");
        map.put('B', "-...");
        map.put('C', "-.-.");
        map.put('D', "-..");
        map.put('E', ".");
        map.put('F', "..-.");
        map.put('G', "--.");
        map.put('H', "....");
        map.put('I', "..");
        map.put('J', ".---");
        map.put('K', "-.-");
        map.put('L', ".-..");
        map.put('M', "--");
        map.put('N', "-.");
        map.put('O', "---");
        map.put('P', ".--.");
        map.put('Q', "--.-");
        map.put('R', ".-.");
        map.put('S', "...");
        map.put('T', "-");
        map.put('U', "..-");
        map.put('V', "...-");
        map.put('W', ".--");
        map.put('X', "-..-");
        map.put('Y', "-.--");
        map.put('Z', "--..");
        map.put('1', ".----");
        map.put('2', "..---");
        map.put('3', "...--");
        map.put('4', "....-");
        map.put('5', ".....");
        map.put('6', "-....");
        map.put('7', "--...");
        map.put('8', "---..");
        map.put('9', "----.");
        map.put('0', "-----");
        map.put('.', ".-.-.-");
        map.put(',', "--..--");
        map.put('?', "..--..");
        map.put('!', "-.-.--");
        map.put('-', "-....-");
        map.put('/', "-..-.");
        map.put('@', ".--.-.");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_morse);

        TextView inputText = (TextView) findViewById(R.id.inputText);
        final Button convertButton = (Button) findViewById(R.id.convert);
        Button blinkButton = (Button) findViewById(R.id.blink);
        final TextView morseText = (TextView) findViewById(R.id.morseText);

        inputText.setFilters(new InputFilter[]{new InputFilter() {
            @Override
            public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                for (int i = start; i < end; i++) {
                    Pattern ps = Pattern.compile("^[a-zA-Z0-9]*$");
                    if (!ps.matcher(source).matches()) {
                        return "";
                    }
                }
                return null;
            }
        }});

        inputText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                Log.v(TAG, "get text : " + s.toString());
                beforeMorse = s.toString().toUpperCase();
                Log.v(TAG, "get string : " + beforeMorse);
            }
        });


        convertButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                convertedMorse = "";
                for (int i = 0; i < beforeMorse.length(); i++) {
                    convertedMorse += map.get(beforeMorse.charAt(i)) + " ";
                }
                Log.v(TAG, "get text : " + convertedMorse);
                morseText.setText(convertedMorse);
            }
        });

        blinkButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (convertButtonOn == false) {
                    convertButtonOn = true;
                    morseThread = new MorseThread();
                    morseThread.start();
                } else {
                    if (morseThread != null) {
                        stopThread();
                    }
                }
            }
        });
    }

    @Override
    public void onBackPressed() {
        if (morseThread != null) {
            stopThread();
        }
        super.onBackPressed();
    }

    private void stopThread() {
        convertButtonOn = false;
        morseThread.interrupt();
        morseThread = null;
    }

    public class MorseThread extends Thread {
        private boolean runFlag = true;
        private int morseDot = 200;

        @Override
        public void run() {
            try {
                while (convertButtonOn) {
                    for (int j = 0; j < convertedMorse.length(); j++) {
                        if ((dot.compareTo(String.valueOf(convertedMorse.charAt(j)))) == 0) {
                            dotFlash();
                        } else if ((dash.compareTo(String.valueOf(convertedMorse.charAt(j)))) == 0) {
                            dashFlash();
                        } else {
                            gapFlash();
                        }
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public void setMorseRun() {
            this.runFlag = true;
        }

        public void setMorseStop() {
            this.runFlag = false;
        }

        private void dotFlash() throws InterruptedException {
            MainActivity.turnOn();
            Thread.sleep(morseDot);
            MainActivity.turnOff();
            Thread.sleep(morseDot);
        }

        private void dashFlash() throws InterruptedException {
            MainActivity.turnOn();
            Thread.sleep(morseDot * 3);
            MainActivity.turnOff();
            Thread.sleep(morseDot);
        }

        private void gapFlash() throws InterruptedException {
            MainActivity.turnOff();
            Thread.sleep(morseDot * 3);
        }
    }

}

 

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="false"
    tools:context=".MorseActivity">

    <Button
        android:id="@+id/convert"
        android:layout_width="130dp"
        android:layout_height="40dp"
        android:layout_marginTop="284dp"
        android:layout_marginEnd="60dp"
        android:layout_weight="0"
        android:baselineAligned="false"
        android:text="Convert"
        android:visibility="visible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/blink"
        android:layout_width="130dp"
        android:layout_height="40dp"
        android:layout_marginStart="76dp"
        android:layout_marginTop="284dp"
        android:text="Blink"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/morseText"
        android:layout_width="368dp"
        android:layout_height="87dp"
        android:layout_marginTop="68dp"
        android:text="TextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/inputText" />

    <android.support.design.widget.TextInputEditText
        android:id="@+id/inputText"
        android:layout_width="372dp"
        android:layout_height="41dp"
        android:layout_marginTop="68dp"
        android:hint="hint"
        android:maxLength="20"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>