SimpleDateFormat

SimpleDateFormat は、日付のフォーマットと解析を、ロケールを考慮して行うための具象クラスです。これによって、フォーマット (日付 -> テキスト)、解析 (テキスト -> 日付)、および正規化を行うことができます。

SimpledateFormat()
デフォルトのロケール、パターン、日付フォーマット記号を持つ、オブジェクトを生成
SimpledateFormat(String)
指定されたパターン、デフォルトのロケール、日付フォーマット記号を持つ、オブジェクトを生成
SimpledateFormat(String, DateFormatSymbols)
指定されたパターン、日付フォーマット記号を持つ、オブジェクトを生成します。
SimpledateFormat(String, Locale)
指定されたパターン、ロケール、デフォルトの日付フォーマット記号を持つ、オブジェクトを生成

SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy/MM/dd");
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy/MM/dd", Locale.US);

sdfって何かと思ったら、simple date formatの略でしょうね。

import java.util.*;
import java.text.*;

class Playground {
    public static void main(String[ ] args) {
        Date date1 = new Date();
        
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy'/'MM'/'dd'?'");
        System.out.println(sdf1.format(date1));
        
        sdf1.applyPattern("yyyy/MM/dd");
        System.out.println(sdf1.format(date1));
    }
}

なるほど、その名の通り、dateformatですね。

runnble 2

class Playground {
    public static void main(String[ ] args) {
        SubThread sub = new SubThread();
        
        Thread thread = new Thread(sub)
        thread.start();
    }
}
    
    class SubSthread implement Runnable{
        public void run(){
            
        }
    }

うまく動きません。。

class Playground {
public static void main(String[ ] args) {
SubThread sub = new SubThread();

Thread thread = new Thread(sub);
thread.start();

for(int i = 0; i < 10; i++){ System.out.println("Lets go cletic"); try{ Thread.sleep(300); } catch(InterruptedException e){ } } } } class SubThread implements Runnable{ public void run(){ for(int i = 0; i < 10; i++){ System.out.println("cleveland"); try { Thread.sleep(500); } catch(InterruptedException e){ } } } } [/java] 500msごとに、他のclassで実行しています。 Lets go cletic cleveland Lets go cletic cleveland Lets go cletic Lets go cletic cleveland Lets go cletic cleveland Lets go cletic Lets go cletic cleveland Lets go cletic Lets go cletic cleveland Lets go cletic cleveland cleveland cleveland cleveland >Javaのクラスは1つのクラスの子クラスにしかなれない制約がある
これに関係していることか?

う~ん、これだと駄目ですね。。

class RacingCar implements Runnable {
private int number = 0;
private static int round = 5;
private static String[] printOffset = {“”, “\t\t\t”,”\t\t\t\t\t\t”};

public RacingCar(int number){
this.number = number;
}

public void run(){
for(int i = 1; i <= round; i++){ try { Thread.sleep((long)(Math.random()* 1000)); } catch(InterruptedException e){ e.printStackTrace(); } System.out.println(printOffset[number-1] + this.number+"号車"+i+"周目通過"); } System.out.println(printOffset[number-1]+ this.number + "号車GOAL!!"); } } [/java] プログラムの実行状態をスレッドといい、全てのプログラムはスレッドによって実行される。javaコマンドが実行されると、JVMは新しいスレッドを作成し、そのスレッドによって指定したクラスのmainメソッドが実行される。mainメソッドの実行が終了するとスレッドは消滅する。

runnable()

run();
オブジェクトが実装するインタフェース Runnable を使ってスレッドを作成し、そのスレッドを開始すると、独立して実行されるスレッド内で、オブジェクトの run メソッドが呼び出される。

class Playground {
private static class Thread {
@Override
public void run(){
for (int i = 0; i < 20; i++){ System.out.println(i + ":" + this.hashCode()); } } } public static void main(String[ ] args) { Thread t1 = new MyThread(); Thread t2 = new MyThread(); t1.start(); t2.start(); } } [/java]

stop watch

public class MainActivity extends AppCompatActivity {

    private long startTime;
    private long elapsedTime = 0l;

    private Handler handler = new Handler();
    private Runnable updateTimer;

    private Button startButton;
    private Button stopButton;
    private Button resetButton;
    private TextView timerLabel;

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

        startButton = (Button) findViewById(R.id.startButton);
        stopButton = (Button) findViewById(R.id.stopButton);
        resetButton = (Button) findViewById(R.id.resetButton);
        timerLabel = (TextView) findViewById(R.id.timerLabel);

        setButtonState(true,false,false);
    }

    public void setButtonState(boolean start, boolean stop, boolean reset){
        startButton.setEnabled(true);
        stopButton.setEnabled(false);
        resetButton.setEnabled(false);

    }

    public void startTimer(View view){
        // startTimeの取得
        startTime = SystemClock.elapsedRealtime(); // 起動してからの経過時間(ミリ秒)

        // 一定時間ごとに現在の経過時間を表示
        // handler -> Runnable(処理) -> UI
        updateTimer = new Runnable(){
            @Override
            public void run(){
                long t = SystemClock.elapsedRealtime() - startTime + elapsedTime;
                SimpleDateFormat sdf = new SimpleDateFormat("mm:ss.SSS", Locale.US);
                timerLabel.setText(sdf.format(t));
                handler.removeCallbacks(updateTimer);
                handler.postDelayed(updateTimer, 10);
            }
        };
        handler.postDelayed(updateTimer, 10);


        // ボタンの操作
        setButtonState(false, true, false);
    }

    public void stopTimer(View view){
        elapsedTime += SystemClock.elapsedRealtime() - startTime;
        handler.removeCallbacks(updateTimer);
        setButtonState(true,false, true);
    }

    public void resetTimer(View view){
        elapsedTime = 0;
        timerLabel.setText("00:00.000");
        setButtonState(true,false, false);
    }
}

runnable、SimpleDateFormat、removeCallbacks、handlerがよくわからんな。

SystemClock.elapsedRealtime();

SystemClock.elapsedRealtime();はdeveloperの公式ページに掲載されています。
https://developer.android.com/reference/android/os/SystemClock
elapsedRealtime() and elapsedRealtimeNanos() return the time since the system was booted, and include deep sleep. This clock is guaranteed to be monotonic, and continues to tick even when the CPU is in power saving modes, so is the recommend basis for general purpose interval timing.

public void startTimer(View view){
        // startTimeの取得
        startTime = SystemClock.elapsedRealtime(); // 起動してからの経過時間(ミリ秒)

        // 一定時間ごとに現在の経過時間を表示
        // handler -> Runnable(処理) -> UI
        updateTimer = new Runnable(){
            @Override
            public void run(){
                long t = SystemClock.elapsedRealtime() - startTime;
                SimpleDateFormat sdf = new SimpleDateFormat("mm:ss.SSS", Locale.US);
                timerLabel.setText(sdf.format(t));
                handler.removeCallbacks(updateTimer);
                handler.postDelayed(updateTimer, 10);
            }
        };
        handler.postDelayed(updateTimer, 10);


        // ボタンの操作
        setButtonState(false, true, false);
    }

setEabled(true)とsetEnabled(false)

setEnabledでtrueだとbuttonを押せる。

private Button startButton;
    private Button stopButton;
    private Button resetButton;

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

        startButton = (Button) findViewById(R.id.startButton);
        stopButton = (Button) findViewById(R.id.stopButton);
        resetButton = (Button) findViewById(R.id.resetButton);

        setButtonState(true,false,false);
    }

    public void setButtonState(boolean start, boolean stop, boolean reset){
        startButton.setEnabled(true);
        stopButton.setEnabled(false);
        resetButton.setEnabled(false);

    }

firstname, lastname, phone, emailをintentする

public void getScore(View view){


        // edittextを取得
        EditText fEditText = (EditText) findViewById(R.id.firstnEditText);
        EditText lEditText = (EditText) findViewById(R.id.lastnEditText);
        EditText pEditText = (EditText) findViewById(R.id.phoneEditText);
        EditText mEditText = (EditText) findViewById(R.id.mailEditText);
        // edittextの中身を取得
        String firstName = fEditText.getText().toString().trim();
        String lastName = lEditText.getText().toString().trim();
        String myPhone = pEditText.getText().toString().trim();
        String myMail = mEditText.getText().toString().trim();

        Pattern p = Pattern.compile("^[0-9\\-]+");
        Matcher m = p.matcher(myPhone);

        Pattern mp = Pattern.compile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$");
        Matcher mm = mp.matcher(myMail);

        // 中身を観て条件分岐
       if (firstName.equals("")){
             fEditText.setError("Please enter your first name!");
        } else if(lastName.equals("")){
           lEditText.setError("Please enter your last name!");
        } else if(myPhone.equals("") || m.find() == false){
           pEditText.setError("Please enter your phone number!");
        }else if(myMail.equals("") || mm.find() == false){
           mEditText.setError("Please enter your valid email");
        } else {
            Intent intent = new Intent(this, MyResult.class);
            intent.putExtra(EXTRA_MYFNAME, firstName);
           intent.putExtra(EXTRA_MYLNAME, lastName);
           intent.putExtra(EXTRA_MYPHONE, myPhone);
           intent.putExtra(EXTRA_MYMAIL, myMail);
            startActivity(intent);
        }
    }

入力すると

引き継がれる! EditTextは良さそうですね。

rfc5322 3.4.1. Addr-Spec Specification

メールアドレスの仕様
https://tools.ietf.org/html/rfc5322#page-17

以下抜粋
—-
An addr-spec is a specific Internet identifier that contains a
locally interpreted string followed by the at-sign character (“@”,
ASCII value 64) followed by an Internet domain. The locally
interpreted string is either a quoted-string or a dot-atom. If the
string can be represented as a dot-atom (that is, it contains no
characters other than atext characters or “.” surrounded by atext
characters), then the dot-atom form SHOULD be used and the quoted-
string form SHOULD NOT be used. Comments and folding white space
SHOULD NOT be used around the “@” in the addr-spec.

addr-spec = local-part “@” domain

local-part = dot-atom / quoted-string / obs-local-part

domain = dot-atom / domain-literal / obs-domain

domain-literal = [CFWS] “[” *([FWS] dtext) [FWS] “]” [CFWS]

dtext = %d33-90 / ; Printable US-ASCII
%d94-126 / ; characters not including
obs-dtext ; “[“, “]”, or “\”
——-
使えるのは、半角英数字か、「!#$%&’*+-/=?^_`{|}~」
で、正規表現で書くと、

^[\w!#%&'/=~`\*\+\?\{\}\^\$\-\|]+(\.[\w!#%&'/=~`\*\+\?\{\}\^\$\-\|]+)*@[\w!#%&'/=~`\*\+\?\{\}\^\$\-\|]+(\.[\w!#%&'/=~`\*\+\?\{\}\^\$\-\|]+)*$

実際に試してみる。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Playground {
    public static void main(String[ ] args) {
        
        String str = "hogehogehoge.jp";
        
        Pattern p = Pattern.compile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$");
        Matcher m = p.matcher(str);
        
        if(m.find() == true){
            System.out.println("OK");
        } else{
            System.out.println("NG");
        }
        
    }
}

NGとなる。

メールアドレスの判定をする。

public void getScore(View view){


        // edittextを取得
        EditText fEditText = (EditText) findViewById(R.id.firstnEditText);
        EditText lEditText = (EditText) findViewById(R.id.lastnEditText);
        EditText pEditText = (EditText) findViewById(R.id.phoneEditText);
        EditText mEditText = (EditText) findViewById(R.id.mailEditText);
        // edittextの中身を取得
        String firstName = fEditText.getText().toString().trim();
        String lastName = lEditText.getText().toString().trim();
        String myPhone = pEditText.getText().toString().trim();
        String myMail = mEditText.getText().toString().trim();

        Pattern p = Pattern.compile("^[0-9\\-]+");
        Matcher m = p.matcher(myPhone);

        Pattern mp = Pattern.compile("^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\\\.[a-zA-Z0-9-]+)*$");
        Matcher mm = mp.matcher(myMail);

        // 中身を観て条件分岐
       if (firstName.equals("")){
             fEditText.setError("Please enter your first name!");
        } else if(lastName.equals("")){
           lEditText.setError("Please enter your last name!");
        } else if(myPhone.equals("") || m.find() == false){
           pEditText.setError("Please enter your phone number!");
        }else if(myMail.equals("") || mm.find() == false){
           mEditText.setError("Please enter your valid email");
        } else {
            Intent intent = new Intent(this, MyResult.class);
            intent.putExtra(EXTRA_MYNAME, firstName);
            startActivity(intent);
        }
    }

EditTextがnullもしくは[0-9\\-]を判定する

MainActivity.javaで電話番号の判定
Pattern p = Pattern.compile(“^[0-9\\-]+”); として、EditTextが数字・ハイフンか正規表現を行う
javaのORは||なので、myPhone.equals(“”) || m.find() == false とする

public void getScore(View view){


        // edittextを取得
        EditText fEditText = (EditText) findViewById(R.id.firstnEditText);
        EditText lEditText = (EditText) findViewById(R.id.lastnEditText);
        EditText pEditText = (EditText) findViewById(R.id.phoneEditText);
        EditText mEditText = (EditText) findViewById(R.id.mailEditText);
        // edittextの中身を取得
        String firstName = fEditText.getText().toString().trim();
        String lastName = lEditText.getText().toString().trim();
        String myPhone = pEditText.getText().toString().trim();
        String myMail = mEditText.getText().toString().trim();

        Pattern p = Pattern.compile("^[0-9\\-]+");
        Matcher m = p.matcher(myPhone);

        // 中身を観て条件分岐
       if (firstName.equals("")){
             fEditText.setError("Please enter your first name!");
        } else if(lastName.equals("")){
           lEditText.setError("Please enter your last name!");
        } else if(myPhone.equals("") || m.find() == false){
           pEditText.setError("Please enter your phone number!");
        }else if(myMail.equals("")){
           mEditText.setError("Please enter your first name!");
        } else {
            Intent intent = new Intent(this, MyResult.class);
            intent.putExtra(EXTRA_MYNAME, firstName);
            startActivity(intent);
        }
    }

おお、Androidの開発の仕方が少しづつ掴めてきた。まずjavaで関数の挙動を確認して、studioで実機確認。php+vagrantとほぼ同じ。

続けてメールアドレスの判定も行いたい