Collect Proverbというandroidアプリ作った話

# はじめに

3/24-4/4の期間に[アンデックス株式会社](https://and-ex.co.jp/)でインターンをしていました。
そこで`Collect Proverb`というandroidアプリを作ったので、紹介したいと思います。

https://github.com/Saku0512/Collect-Proverb

# 概要

頑張って疲れている人に元気を与えようというコンセプトで、いくつかの質問に答えてもらい、その結果に応じて偉人等の格言を表示するアプリ。
格言は一日一つまでとし、振り返ることも可能

# 開発の流れ

## Day1 (3/24)

- **[AndroidStudio](https://developer.android.com/studio?hl=ja)のインストール**
少し時間がかかりましたが、マニュアル通り問題なくインストールでしました。
- **アプリの要件定義**
    ```md
    ## 概要

    ユーザーを励ますアプリ。
    ユーザーがいくつかの質問に答え、それに沿って偉人等の格言を表示するアプリ。
    格言は記録され、いつでも参照できる。

    ## 必要な機能

    - 質問機能
    - 質問に対して指標を持たせる機能
    - 指標から適切な格言を選ぶ機能
    - 格言を表示する機能
    - 格言を記録しておく機能 (格言をバッジとして保存する機能)
    - 記録から格言を取り出す機能  
    ```
    要件定義のやり方分からなかったんで、簡単に概要と必要な機能を書きました。
- **ワイヤーフレーム作成**
    [figma](https://www.figma.com/)でワイヤーフレームを作りました。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936581/4bbc8744-0db3-4c1c-beb6-7c48ea0af327.png)

## Day2 (3/27)

3/25-26はJNSAのイベントでCTFをしていたので、インターンはお休みさせていただきました

https://qiita.com/Saku0512/items/8d870be2061b2f56fa0a

- **ワイヤーフレームをもとに実際に開発開始**
    今日はメインページのUIをいちから作りました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936581/50e3cae2-a58c-43f6-b9d8-03b02d1d9ff9.png)
未開放の格言のバッジのUIを考えるのが一番時間かかりましたが、シンプルなものにしました。
また格言を受け取るボタンを押したら、簡単なポップアップがでるようにJavaコードを書き始めました。

## Day3 (3/28)
今日は処理を書きました。
実装した処理
- **格言を受け取るボタンを押したら、質問ポップアップ表示**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936581/55eb4e97-f943-4470-b179-66a1854e431f.png)

- **Yes,Noボタンを押したら次の質問を表示**
- **最後に格言を表示**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936581/e3c325e1-e036-44b6-bdd1-fd5f452329b2.png)
- **格言をトップに表示して、その日はもうボタンを押せなくする**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936581/3dbdc950-9720-46e7-8188-0a5dbbf327cc.png)

フロントで処理を書いているので、次回はバックエンドに処理を移したい。
あと、格言のバッジも実装したい。

## Day3.5 (3/29-30)

- **格言のバッジを12個全て描いた**
全て一から書いたわけではなく、フリー素材をふんだんに使ってぽいバッジにした。

- **フロントで書いていた処理をDBで管理できるよううにした**
格言の初期化処理や、ボタンの有効化・無効化の処理をDBで管理するように書いた。
PHPでのバックエンド処理は書いたことがあったら、Javaは初めてだったので色々調べながら行った。
今回使ったのは`SQLite`という軽量なRDBMS(リレーショナルデータベース管理システム)を用いて行った。
普段使っているMysqlやMariaDBとは違い、組み込み型のデータベースということで新鮮だった。

## Day4 (3/31)

- **DB移行**
アプリ起動時に、既に取得している格言をバッジを表示する処理をDBで管理するようにした。

- **バッジクリック時のポップアップ定義**
バッジをクリックした時のポップアップのレイアウトを定義した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936581/4d447153-b5fa-473e-ac55-db5521e05d8c.png)

- **バッジポップアップの処理を定義**
バッジがクリックされた時の処理を書いた。
以下の流れで処理させることにした。  
1. バッジをクリック
2. クリックされたバッジのIDを取得
3. テーブルをバッジIDで検索
4. バッジが無効化されていれば処理を中断
5. バッジが有効化されていれば、データを取得
6. 取得したデータに基づいて、バッジのsrc,それぞれのテキスト内容を構築
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936581/8a3556f3-6691-4b30-b843-2d7bd2b167e5.png)

## Day5 (4/1)

- **前日のデバッグ**
前日追加した有効化されたバッジをクリックしたらそれのポップアップを表示する機能にバグというか書き忘れがあった。
その日に取得したバッジをクリックしても、ポップアップが表示されないといもの。
コードを書き足して解消した。
- **取得回数を表示**
ある程度長くアプリを使っていると、格言が被ってしまうという懸念があった。
そこで、取得回数を管理して一種のステータスにしてもらおうという発想で取得回数を表示する機能を実装。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3936581/4bde7f2a-0d95-4222-ab07-ccbf42fcf925.png)
- **簡単なアニメーションをつけた**
格言取得時に対象のバッジを拡大して縮小するアニメーションを追加
以下のxmlファイルで定義してJavaで動かした。
    ```xml
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:fromXScale="1.0"
        android:toXScale="1.2"
        android:fromYScale="1.0"
        android:toYScale="1.2"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="500"
        android:repeatMode="reverse"
        android:repeatCount="1" />
    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0.5"
        android:duration="500"
        android:repeatMode="reverse"
        android:repeatCount="1" />
    </set>
    ```
- **アプリ起動時に格言とボタンのBool値がリセットされるバグを解消**
アプリ起動時にその日のうちに取得した格言等がリセットされてしまっていた。
日ごとの格言を管理するテーブルを新しく作り、アプリ起動時に参照して表示するような処理に変更した

## Day6 (4/2)
- **DB暗号化**
アプリ自体は昨日完成したので、DBの暗号化を行いました。  
といってもDBに個人情報等は入れていないので、暗号化する意味あるか？と思ったのですが、暗号化しておいて損はないと思い暗号化しました。  
当初[SQLCipher](https://github.com/sqlcipher/sqlcipher-android)を用いて暗号化を行おうとしていたのですが、最近の資料がなく実装の仕方を見つけられなかったので、AES+base64にしました。
AESで文字列をバイナリに変えて、base64で扱いやすくしました。

## Day7 (4/3)

リファクタリングと発表資料作成を行いました。

<script async class="docswell-embed" src="https://www.docswell.com/assets/libs/docswell-embed/docswell-embed.min.js" data-src="https://www.docswell.com/slide/KXEN6M/embed?key=2025-04-03-175250" data-aspect="0.5625"></script><div class="docswell-link"><a href="https://www.docswell.com/s/Saku0512/KXEN6M-2025-04-03-175250">Collect Proverb by @Saku0512</a></div>

## Day8 (4/4)

- ロカール通知機能実装
ローカル通知を実装してなかったと思い、急いで実装。
実装は以下の記事を参考にして行いました。

https://appdev-room.com/android-notify

# おわりに
今回初めてAndroidStudioやJavaを触ったが、なんとか動くものができて良かった。
これからもいろんなものを作っていきたい。
アプリ自体の公開は６月初旬を予定しています。
ぜひ楽しみにお待ちいただければと思います。