KotlinとJavaのソースファイルが混じっているAndroidプロジェクトを複数人で開発する時の注意

某コンテストに参加しており、1人はJavaでもう1人はKotlinで、コンテストに出すAndroidアプリを開発していて、その時に片方ではエラーと出て片方では何も出ていなくて2人ともビルドや実行はできるという状況に陥ったけど解決した話。

 

# 開発環境

Windows 10

Mac OSX Sierra

AndroidStudio 2.3.3

Java8

Kotlin 1.1.50

 

# 状況

- gitでバージョン管理をしていて、Kotlinで書いている人(以下K)とJavaで書いている人(以下J)がdevelopから生やしたブランチでそれぞれ作業をしており、Kがmergeした後のdevelopブランチにJがmergeした後に急に出てきたらしい(当人ではないので詳しくは分からず)。

- KとJはそれぞれ別フォルダにそれぞれの言語のコードを保存していました。(main.java.srcDirs += 'src/main/kotlin')

- AndroidStudioに「cannot resolve symbol」と言われ赤波線を引かれてエラー扱い。

- ビルドや実行はでき、「Message」ではエラーと出ない。

- ビルドや実行はできるがエラー表示され、他のエラーに気づけなくなる可能性があるためどうにかしたい。

- Kの方ではエラー出されていない。

- エラーが吐かれたファイルはMainActivity.java

- エラーが吐かれた部分は全部、Kotlinで作成したクラスのインスタンス化だったり宣言をしているところ。

- Kotlinが入っているフォルダをAndroidStudioが見つけられていないっぽい...?

 

# 解決方法

ここまで読んできて、詳しい人なら気付いていると思いますが、

J側のAndroidStudioにKotlinのプラグインをインストールしたら解決しました。

これでAndroidStudioが.ktファイルを認識するようになったみたい。

そのあとは同じ状況にならずに済んでいる。

 

# 感想

エラーというか要注意扱いなのかと考えたけど「cannot resolve symbol」と言われたらね...

当然と言われればそうかもしれないけど、全く考慮できていなかった。

最初、全部Javaに書き直そうかと思って、少しJavaで書き直したところでめんどくさくなって解決方法を考えてみたけど成功してよかった。

今の所、これ以外でJavaとKotlinの混じった開発に支障はなくて安心。

進捗(´・ω・`)

AndroidStudioのプロジェクト作成方法

AndroidStudioを使ってAndroidアプリを作成する時に最も大切と言っても過言ではないであろうプロジェクト作成についての記事を書きます。

環境

AndroidStudio 2.3
MacOS Sierra

本題

まず初めに、「Start a new Android Studio project」を選択します。 f:id:mitoavadn:20170929124945j:plain

次に「プロジェクト名」、「ドメイン名」、「パッケージ名」、「プロジェクトの保存場所」を決めます。 f:id:mitoavadn:20170312221341j:plain

プロジェクト名等を決めたら、次は作るアプリの対象とするAndroidOSの最低バージョンを決めます。 f:id:mitoavadn:20170312222114j:plain

その次に、デフォルトとなるアクティビティを追加することができます。
ここで「Add No Activity」を選択して追加しなくても後で追加できます。 f:id:mitoavadn:20170312222931j:plain

最後に、追加したアクティビティの名前やもう少し詳しい設定をしたりします。
(ここでは「Empty Activity」を選択しているので名前だけです)
f:id:mitoavadn:20170312223412j:plain

そして、「Finish」を押すとプロジェクトが作成されます。

mito.

テキストボックスに入力した文字列を取得して表示する

タイトル通りなんですが、入力した文字を取得して表示させます。
表示のさせ方はトースト(朝食じゃないです)やダイアログ、テキストビューで出します。

開発環境

AndroidStudio2.3
MacOS Sierra

プロジェクト作成

mitoavadn.hatenablog.com

Project : Get_String_Textbox
MinimumSDK : API19(KitKat)

レイアウト作成

今回のレイアウトでは

  • テキストボックス
  • ボタン
  • テキストビュー

をそれぞれ一つずつ配置します。
android:id="+id/hoge" のようにして、それぞれにidを設定してください。(後で使います)

コード例
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.mito.get_string_textbox.MainActivity">


    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="156dp"
        android:ems="13"
        android:inputType="textPersonName"
        android:hint="Please Input Text"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="90dp"
        android:text="No Input" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:text="GET"
        android:id="@+id/button"/>
</RelativeLayout>

処理を書く

まず、テキストボックスやボタン、テキストビューの変数を用意します。

private EditText editText;
private Button button;
private TextView textView;

これらのインスタンスをonCreate内で生成します。

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

        //変数 = (キャスト)findViewById(使いたいウィジェットのid)
        editText = (EditText) findViewById(R.id.editText);
        button = (Button) findViewById(R.id.button);
        textView = (TextView) findViewById(R.id.textView);
}

ボタンにリスナー(その動作、今回で言えばボタンが押された時に呼ばれるやつ)を設定します。

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        //ここに押された時の処理を記述
    }
});

押されたら、テキストボックスから文字列を取得してそれをテキストビューにセットします。
onClick内に記述

String text = editText.getText().toString();    //EditText(テキストボックス)から文字列を取得
if (!text.equals("")){
    textView.setText(text);    //TextViewに文字列をセット
    editText.setText("");
}

setText() で文字列のセット、 getText() で文字列を取得できます。

今度は入力された文字列をトーストで表示してみましょう。

//Toast.makeText(コンテキスト, 表示したい文字列, どれぐらい(時間)表示させたいか(LONG or SHORT)).show();
Toast.makeText(view.getContext(), text, Toast.LENGTH_LONG).show();

最後にshow()しないと表示されません。(mitoは忘れていて悩んでました)
コンテキストについては今は詳しく知らなくてもいいです。(thisや上のコードのようにすると良さげ)
これでトースト表示まではできたはずです。
最後に、ダイアログで表示させます。

new AlertDialog.Builder(view.getContext())
            .setTitle("ダイアログ")    //タイトル
            .setMessage(text)    //本文
            .setPositiveButton("OK", null)    //押したら閉じるボタンみたいなやつのテキスト(第一引数)
            .show();

ダイアログはこちらからコピペで使えます。
Fragmentを作った方がいいと書いてありますが、今回は書いていません。

おまけ

ついでにボタンを押した時に何も入力されていなかったらトーストを表示されるようにしてみましょう。

if (!text.equals("")){
    ...
    ...
}
else {
    Toast.makeText(view.getContext(), "入力してください", Toast.LENGTH_SHORT).show();
}

最終的なコード

MainActivity.java

package com.example.mito.get_string_textbox;

import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private EditText editText;
    private Button button;
    private TextView textView;

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

        editText = (EditText) findViewById(R.id.editText);
        button = (Button) findViewById(R.id.button);
        textView = (TextView) findViewById(R.id.textView);


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String text = editText.getText().toString();
                if (!text.equals("")){
                    textView.setText(text);
                    editText.setText("");
                    Toast.makeText(view.getContext(), text, Toast.LENGTH_SHORT).show();
                    new AlertDialog.Builder(view.getContext())
                            .setTitle("ダイアログ")
                            .setMessage(text)
                            .setPositiveButton("close", null)
                            .show();
                }
                else {
                    Toast.makeText(view.getContext(), "入力してください", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.mito.get_string_textbox.MainActivity">


    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="156dp"
        android:ems="13"
        android:inputType="textPersonName"
        android:hint="Please Input Text"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="90dp"
        android:text="No Input" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:text="GET"
        android:id="@+id/button"/>
</RelativeLayout>

mito.

3/11 追記
githubにて今回のプロジェクトを公開しました。
リンク(https://github.com/mitohato/AndroidTutorial)

Beacon検知

「ふぁみここ」を作成する際に、ビーコンの情報を取得しないといけない時にやり方が調べてもよくわからず、先輩に話を聞いたりして作成したので、そのやり方

engineer.recruit-lifestyle.co.jp

こちらのサイトを参考にさせていただきました。

やりたいこと

ボタンを押すとビーコンの検知を開始して、もう一度押すと終了するアプリ。
検知したビーコンの情報はログに出す。

開発環境

MacOS sierra
AndroidStudio 2.2.3
java8

準備

まずプロジェクトを作成します。
プロジェクト名「GetBeacon」
API 21:Android5.0 Lollipop
Empty Activity

ボタン配置

デフォルトで入っているTextVIewを削除して、Buttonを追加します。
自分は、真ん中に配置しました。

<!--省略-->
<Button
    android:text="Button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"
    android:id="@+id/button" />
<!--省略-->

ボタンを押した時のリスナー用意

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

     Button btn = (Button)findViewById(R.id.button);
     btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

        }
    });
 }

ビーコン検知する

パーミッションを追加

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

をmanifests(app/src/main/AndroidManifest.xml)フォルダ内の<applicationと同じ高さに追加します。
このアプリが動作する端末をBLEが利用可能な端末のみにするには
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
も追加します

ビーコンを検知した時に呼ばれるCallBackを用意

新しくJavaClassを作成して、その名前をIbeaconScanCallBackにします。
このコールバックの中身は後で記述します。

BLE受信開始するためのコードを用意

BluetoothLeScanner mBLEScanner;
IbeaconScanCallback scanCallback;

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

    // Bluetoothの生成(ここは5.0以前も一緒)
    final BluetoothManager bManager = (BluetoothManager)getSystemService(BLUETOOTH_SERVICE);
    final BluetoothAdapter bAdapter = bManager.getAdapter();

    // Bluetoothサポートチェック
    final boolean isBluetoothSupported = bAdapter != null;
    if (!isBluetoothSupported) {
        // 非サポート時の処理を書く
        return;
    }

     // Bluetoothオンかチェック
     if (!bAdapter.isEnabled()) {
         // オフ時の処理を書く
         return;
     }


    mBLEScanner = bAdapter.getBluetoothLeScanner();
    scanCallback = new IbeaconScanCallback();

    Button btn = (Button)findViewById(R.id.button);
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

         }
     });
}

2つほどエラーが出ていると思いますが今は気にしないでください。

IbeaconScanCallbackの内容を記述していく

public class IbeaconScanCallback extends ScanCallback{
    final String TAG = "Beacon";

    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        super.onScanResult(callbackType, result);
        // スキャン結果が返ってきます
        // このメソッドかonBatchScanResultsのいずれかが呼び出されます。
        // 通常はこちらが呼び出されます。
        //スキャン結果からビーコンの情報を取得する
        BluetoothDevice bDevice = result.getDevice();
        //情報からアドレスをログに出す
        Log.d(TAG, bDevice.getAddress());
    }


    @Override
    public void onScanFailed(int errorCode) {
        super.onScanFailed(errorCode);
        // エラーが発生するとこちらが呼び出されます
        String errorMessage = "";
        switch (errorCode) {
            case SCAN_FAILED_ALREADY_STARTED:
                errorMessage = "既にBLEスキャンを実行中です";
                break;
            case SCAN_FAILED_APPLICATION_REGISTRATION_FAILED:
                errorMessage = "BLEスキャンを開始できませんでした";
                break;
            case SCAN_FAILED_FEATURE_UNSUPPORTED:
                errorMessage = "BLEの検索をサポートしていません。";
                break;
            case SCAN_FAILED_INTERNAL_ERROR:
                errorMessage = "内部エラーが発生しました";
                break;
        }
        Log.d("ERROR", errorMessage);
    }
}

BluetoothScanを開始

スキャンが開始しているかのためにflag変数を用意します。
その後、ボタンのリスナー内にスキャンを開始させるためのコードを記述します。

btn.setOnClickListener(new View.OnClickListener() {
    @Override
     public void onClick(View view) {
         if (flag) {
             //スキャン開始
             mBLEScanner.startScan(scanCallback);
         }
         else {
             //スキャン停止
             mBLEScanner.stopScan(scanCallback);
         }
         flag = !flag;
    }
});

以上でボタンを押したらビーコンの検知を開始、もう一度押すと停止。
これで検知したビーコンのアドレスをログに出すことができたと思います。
詳しい説明等は参考元を見てみてください。
参考元と変わっている部分が多々あるので気をつけてください。

参考元

http://engineer.recruit-lifestyle.co.jp/techblog/2015-01-15-using-ibeacon-on-android5/

mito.

2/23 追記
Githubにて今回説明したアプリのプロジェクトファイルを公開しました。
https://github.com/mitohato/GetBeacon

2/23 追記 ↑のGithubリポジトリにてkotlinで書いた同アプリのプロジェクトを作成・公開しました。

2018/11/9 追記
Android 6.0からはパーミッションに以下のいずれかを追加しないといけなくなりました。
android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION

スライドでタブを切り替えられるUI作成

※この記事はAndroid開発初心者が模索しながら開発した時に、行ったことを書いた(or 説明した)記事なので、誤り等が多々とあると思います。ですので誤り等があったら優しく指摘してくれることを願っています。

イメージ

イメージとしてはTwiiterやLINEみたいな感じ。画面に複数のタブがあり、タブタップとスワイプによってタブを切り替えるUIを作成したい。

イメージ

f:id:mitoavadn:20161231021629p:plain

 

これを実装しようとした時に調べていたら、なんか難しそうな記事ばかり出てきて自分みたいなFragmentもわかっていない(今もなんとなくだけど)完全な初心者にとっては優しくなかったです。

よく見かけるUIだから簡単にできるのではと思い、そういえばAndroid Studioに元々用意されているActivityを全く見ていなかったなと思い見てみるとありました。

だから簡潔に言ってしまえばデフォルトで用意されているテンプレートみたいなの使えば終わりです。

 

見よう見まねですが説明させていただきます。

 

環境

Android Studio Version 2.2.3

java バージョン8

macOS Sierra バージョン10.12.2

 

手順

まずAndroid Studioを起動して、「Start a new Android Studio project」を選択します。

f:id:mitoavadn:20161231002801p:plain

 

次に、プロジェクト名やプロジェクトの保存先を決めて、右下にあるNextボタンを押します。

f:id:mitoavadn:20161231004102p:plain

 

押したら、次の画面に移ると思います。ここでAPIを13以上に設定します。そうしないと今回紹介する方法では出来ません(理由等は未調査)。APIを設定したら先ほどと同じくNextボタンをクリックします。

f:id:mitoavadn:20161231005454p:plain

 

次は下のような画面になると思います。ここでテンプレのActivityを選択することができます。(Activityに関してはこちら)

f:id:mitoavadn:20161231011549p:plain

 

その中から一番下にあるTabbed Activityを選択してNextを押します。

f:id:mitoavadn:20161231011606p:plain

 

そうすると、次のような画面になります。この画面の真ん中あたりにある「Navigation Style」を変更するとタブを切り替えるUIのタイプを変更できます。

f:id:mitoavadn:20161231011623p:plain

 

ここで変更できるタイプは3種類ありますが、今回はスライドでタブを切り替えられるUI作成なのでAction Bar Tabs (with ViewPager)だけにさせていただきます。

f:id:mitoavadn:20161231021434p:plain

 選択するとプロジェクトが作成されます。

 

作成されたプロジェクトをビルドするとこのようになると思います。

 

f:id:mitoavadn:20161231022035p:plain

 これでスワイプでタブを切り替えられるUIの作成が完了しました。

 

カスタマイズ(?)

スワイプでタブを切り替えられるUIを作成したとはいえ、タブの名前や数を変えたい、タブごとに対応した画面を表示したいなどあると思います。

 

・タブの名前を変える

MainActivity.javaの下の方にあるgetPageTitleを変更します。

ここで引数のpositionは、今見ている(表示されている?)タブの番号で、左から順に0,1,2...です。このposition変数に合わせて変更したいタブの名前を戻り値として返してあげればその名前になります。

f:id:mitoavadn:20161231022625p:plain

 

・タブの数を変える

getPageTitleの上の方にある(であろう)getCountを変更します。

ここでタブの数を戻り値として返してあげればその数タブができます。

デフォルトは3が戻り値となっており、この場合タブは3つです。

f:id:mitoavadn:20161231023300p:plain

 

タブごとに対応した画面を表示する

getCountの上にある(であろう)getItemを変更します。

ここでもgetPageTitleと同じようにpositionに対応したFragmentを戻り値として渡してあげれば良いです。(Fragmentについてはこちら)

f:id:mitoavadn:20161231024038p:plain

 

これで一通りの説明を終わらせていただきます。

最初の方にも書いた通り、詳しく分かっていないところだらけなので間違い等がございましたら指摘お願いいたします。

また疑問に思ったことなどもよろしくお願いします。

 

順序が逆になってしまいましたが次はAndorid Studioでプロジェクト作成する方法をまとめてみます。

 

mito.

今年のまとめ

※この記事はICT Advent Calender19日の記事です。

 

こんにちは、今日でICT12th女子の学校の成績が一気に心配になったmito(mitohato14)です。

昨日は眠人と1年生のroy-i、Shoでした。

nemu-sou.hatenablog.com 眠人

tip36.hatenablog.com Sho

 

roy-l.hatenablog.com roy-l

 

一年生にはこれからも頑張って欲しいです。

 

知っている人が多いとは思いますが、このmito、12月6日をもってICT委員会の副委員長となりました。

どうぞよろしくお願いします。

 

今年の出来事(覚えている限り)

Unity入門した

新しいパソコンを得た

イデア出し

愛媛大学工学部情報工学プログラミングコンテスト参加(大会名間違っていたらごめんなさい)

PCKプログラミングコンテスト予選参加

Androidアプリ開発

JOI予選参加

うちな〜ICTビジネスプラン発表会参加

 

取った賞や成績

愛媛大学工学部情報工学プログラミングコンテスト:優秀賞(多分)

パソコン甲子園プログラミング部門(予選):4か5完(よく覚えていない)

もう一つの本戦:不参加なので分からず(きしもんがやったらしい)

 パソコン甲子園モバイル部門:ベストデザイン賞

JOI予選:320点(Bランク)

うちな〜ICTビジネスプラン発表会:フロム沖縄理事長賞

 

 感想(羅列)

去年と比べ、いろいろな経験や仕事をしたと思う。

パソコン甲子園本戦に行って、賞を取ったのが一番嬉しかったし、悔しかった。

自己贔屓と言われたらそこまでだけど、グランプリ取れてもおかしくなかった内容だったと思うから、グランプリ取れなくて悔しかった(もちろん、ベストデザイン賞も嬉しいです)

大会等で賞を頂いたのがこれが実質初めてなので嬉しかった。

ご飯美味しかった。

温泉素晴らしい。

秋葉原にまた行きたい(一人でも)

パソコン甲子園があるから高専祭の準備等ではほとんど仕事しないと決めていたのに気づいたら結構仕事していた

JOIで手計算で出した簡単なテストケースを間違えて、Aランクに届かなかったのが悔しい

競プロの精進

先輩たちの技術を吸収せねば

受賞の代わりに成績が落ちてゆく

 

来年やりたいこと

kotlin

開発

C#

プレゼンを今年よりも練習(負けたので)

情報技術者試験の勉強

 

まとめ

このまま書いていってもグダる可能性しかないのでここらでまとめを

 

まだ意識たかそう

来年もパソコン甲子園の方に出るつもりなので次はグランプリ取りたいです。

高専のプロ各位と会ってみたい

ぱんぷきんたるとは復活するのか

@12th、来年は自分たちが入学した頃のコーヤ先輩達の学年ですよ?

来年は今年よりも仕事が増える(確定)

また、メディア上位陣と並べるように学校の勉強も頑張る

体調大事

 

 

明日はICT委員会スポンサーの某社の某さんです。

front.hatenablog.jp

 

mito.

Android開発初心者が開発して詰まった話

JOI予選まであと一週間しかないけど、競プロのやる気が起きないのでJOI終わった後に書こうと思っていた記事を書く

(この記事は開発初心者がAndroid開発をした時に、詰まったところやわからなかったことが主ですので注意ください。間違ってるところとかあれば指摘お願いしたいです。)

 

PCK2016モバイル部門に参加時にAndroid開発(実質初めて)をしました。

開発自体は去年、Unityやらvisualstudioでやったことあったんですが、ほとんど本読みながら「なるほどね〜」って感じでやってました。

 

・開発環境

Android Studio ver 2.X

java ver8

 

・詰まったところ

ライフサイクルって何

ライフサイクルがわからないからどこから呼ばれるのかがわからない(main関数みたいなのがあると思ってた)

ActivityとFragment

サーバとの通信ってどうやるの

UI操作しようとしたらアプリが落ちるんだけど

スワイプで画面遷移って難しすぎでは

ソフトキーボード消えてくれない

トークアプリを作ってやり方を記事にしている人って案外少ない(検索力不足の可能性)

テンプレートの存在(というより種類か)

 

 

これらの原因とか理由、やり方は理解しました(完全になんて言えない)

(Qiita、stackoverflow、google先生、Estimote communityの方、ict委員会の先輩方に圧倒的感謝)

 

・今回開発してみて思ったこと

やってみるのが早いは正しい(ただし、一応ある程度知ってないと死ぬ)

学校推奨パソコンのままでやってたらアプリ動かせるまでできてない気がする

英語は大切

進捗管理も大切

バックアップも大切

体調管理も大切

やる気が起きない時はやっても特に進捗生えない

 

・まとめ

特にAndroid開発はほぼ初めてで分からないことだらけだったけど調べながらやったらなんとかなる

聞くの大切

英語大切

やってみると分かる(いろいろと)

開発はつらい

開発は楽しい

開発は楽しい

 

楽しい

 

開発はつらい時が多いけど楽しい(一応言っておくとM気質はありません)

 

次はkotlinで開発やってみたいなと思ってます。

 

mito.

 

---------------------

同日、17:10追記

解決法や今回の開発で使った技術については後日にちゃんと書きます