Newer
Older
CitrusClient / app / src / main / java / com / example / citrusclient / views / LoginActivity.java
package com.example.citrusclient.views;

import android.content.Intent;
import android.os.Bundle; //
import android.os.Handler;
import android.view.View;
import android.widget.Button;

import android.widget.EditText;
import android.widget.TextView;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity; //
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.example.citrusclient.Citrus;
import com.example.citrusclient.R;
import com.example.citrusclient.rest.AccountsRest;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;

public class LoginActivity extends AppCompatActivity {
    private Retrofit retrofit;  // サーバーと通信するためのRetrofitオブジェクト
    private AccountsRest accountsRest;  // APIエンドポイント(サーバーと通信するためのURL)を呼び出すためのインターフェース
    private Citrus citrus; // アプリ全体を管理するオブジェクト

    // 画面起動時に呼び出されるonCreateメソッド
    @Override
    // Androidのアクティビティは、Activity クラス(提供されている)を継承して作成される。Activity クラスは、すべてのアクティビティに共通の基本機能を提供します。そのため、アクティビティを作成する際には、Activity クラスのメソッドをoverrideしてカスタマイズすることが一般的です。
    // 具体的には、onCreate メソッドは Activity クラスの一部であり、アクティビティが作成される際に呼び出される重要なメソッドです。アクティビティが初めて起動されるときには必ずこのメソッドが呼ばれます。onCreate メソッドでは、アクティビティの初期化、レイアウトの設定、リソースの読み込み、UIの構築などの処理が行われます。
    protected void onCreate(Bundle savedInstanceState) {  //すべてのアクティビティで実装する必要があるコールバックメソッド OnCreateメソッド 画面表示させたかったら、必ず皆かく
        super.onCreate(savedInstanceState);  // 最初に親クラスの onCreate メソッドを呼び出しています。これにより、親クラスで行われる初期化処理が実行されます。savedInstanceState パラメータは、アクティビティが再作成された場合に前回の状態を復元するために使用されます。
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_login);  // setContentViewで レイアウトを設定し、画面の初期化
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });


    // アプリケーション全体の状態を管理する Citrus オブジェクトを取得 初期化
        citrus = (Citrus) this.getApplication();

    // サーバーと通信するためのRetrofitインスタンスの作成、初期化
        this.retrofit = new Retrofit.Builder()  // retrofitのビルダーを作成
            .baseUrl("http://nitta-lab-www.is.konan-u.ac.jp/citrus/")  // サーバーのベースURLを設定
            .addConverterFactory(JacksonConverterFactory.create())  // レスポンス(通信の返信)をパース(解析、変換)するためのコンバーター(変換ツール)を追加します。この場合はJacksonを使用
            .build();
        this.accountsRest = retrofit.create(AccountsRest.class);


    // ボタンをクリックすると...
        // loginButtonというIDを持つボタンを取得し、
        Button loginButton = (Button)findViewById(R.id.loginButton);
        // そのボタンにクリックリスナーを設定
        loginButton.setOnClickListener(new View.OnClickListener(){

            public void onClick(View v){  // View.OnClickListener インターフェースに属するメソッド


                //テキスト入力を文字列で認識、取得
                EditText editid = (EditText) findViewById(R.id.username);
                String id = editid.getText().toString().trim();
                EditText editpw = (EditText) findViewById(R.id.password);
                String pw = editpw.getText().toString().trim();
                // Androidでスレッド間の通信を簡単に行うために使用される Handler クラスのインスタンスを作成しています
                final Handler handler = new Handler();

                //入力欄が空欄の時
                if(id.isEmpty() && pw.isEmpty() && id.trim().isEmpty() && pw.trim().isEmpty()){
                    System.out.println("不適切入力");
                    // textView_responseっていう名前をactivity_login.xmlでつけた
                    ((TextView)findViewById(R.id.textView_response)).setText("適切に入力してください");

                // Intent intent = new Intent(LoginActivity.this,MainActivity.class);
                // startActivity(intent);

                // 入力欄が適切に入力されたとき
                }else if(!id.isEmpty() && !pw.isEmpty() && !id.trim().isEmpty() && !pw.trim().isEmpty() ){
                    // accountsRest.login(id,pw)は、Retrofit のインターフェースを使って定義されたメソッドで、サーバーに対してログイン情報を送信
                    Call<String> call = accountsRest.login(id,pw);
                    call.enqueue(new Callback<String>() {
                        @Override
                        public void onResponse(Call<String> call, Response<String> response) {  // Retrofit の Response クラスで提供されているもので、HTTPリクエストの結果を表すクラス
                            if (response.isSuccessful()){
                                if (!response.body().equals("null")) {
                                    System.out.println("通信成功");
                                    //端末にtoken.id登録
                                    String token = response.body();
                                    citrus.setToken(token);
                                    citrus.setAccountId(id);

                                    // 画面遷移 handlerここで使われてる
                                    handler.post(new Runnable() {
                                        @Override
                                        // ログイン成功後に MainActivity へ遷移する処理
                                        public void run() {
                                            Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                                            startActivity(intent);
                                        }
                                    });
                                }else{
                                    ((TextView)findViewById(R.id.textView_response)).setText(("パスワードが間違っています"));

                                }

                            }else{
                                //通信可能(ただしエラーが発生した場合)
                                //404がPW入力されてないときだけど、前で定義しているからいらないよね..?
                                System.out.println("通信可能");
                                if(response.code()==404){
                                    ((TextView)findViewById(R.id.textView_response)).setText(("IDが間違っています"));
                                }
                            }
                        }
                        //通信失敗
                        @Override
                        public void onFailure(Call<String> call, Throwable t) {
                            System.out.println("通信失敗");
                            System.out.println(t);
                        }
                    });
                }
            }
        });
        Button newButton = (Button)findViewById(R.id.newAccount);
        newButton.setOnClickListener(new View.OnClickListener(){

            public void onClick(View v){
                Intent intent = new Intent(LoginActivity.this,SignUpActivity.class);
                startActivity(intent);
            }
        });
    }
}

// キーボード
// Insertでちかちかするやつの位置変わる

// onCreate
// すべてのアクティビティで実装する必要があるコールバックメソッド
// onClick
// View.OnClickListener インターフェースに属するメソッド
// onFailure
// Callback インターフェースのメソッド Retrofitなどのライブラリで使用される非同期通信の際に、通信が失敗した場合に呼び出されるコールバック
// Response
// Retrofit の Response クラスで提供されているもので、HTTPリクエストの結果を表すクラス