[個人開発] 独学してAndroidアプリをリリースした話

#目次
[1.アプリ作成の背景](#1-アプリ作成の背景)
[2.何かを作る](#2-何かを作る)
[3.開発環境と主なライブラリ](#3-開発環境と主なライブラリ)
[4.アプリの機能](#4-アプリの機能)
[5.学習方法の概要](#5-学習方法の概要)
[6.アプリを作ってみた感想](#6-アプリを作ってみた感想)

#1. アプリ作成の背景
※半分くらいポエムです

---**とりあえず自分で何か作りたい**---
僕は電子機器のメーカーで働いています。何かものつくりがしたい、という動機で就職し、主に生産技術の仕事をしてきました。
生産ラインの改善ではロボットや搬送装置の動作変更が必要な場合があり、ソフトウェアのエンジニアと協力して改善をする機会が頻繁にありました。現状の製造装置の効率をもっと上げるための方法をソフトウェアのエンジニアに方に提案し、短期間かつ低コストで生産能力の向上させるアイデアを形にしてもらったことが何度もありました。ソフトウェアのエンジニアと仕事をする中で、自分もソフトウェアについての知識があった方が改善の相談がしやすくなるかもしれないと考えるようになり、プログラミングの学習を開始しました。


#2. 何かを作る
とりあえず生産現場ではJavaが使われていることが多ので、とりあえずJavaを学んでみることにしました。

ある程度慣れてきた頃、何か作ってみようと考えていろいろ調べてみると、Javaでスマホのアプリが作れることがわかりとりあえず何か作ってみて誰も使ってくれなくても自分でインストールして使えばよさそうだなー、と考えスマホのアプリを作ってみることにしました。

せっかく何か作るのであれば、自分が欲しいものを作ろうと思い、いろいろ考えたところ、読書系のアプリを作ることにしました。

---**何を作るか**---
僕は本をよく読むのですが、本の中には「これはいい言葉だな～」と思う名言がたまに出てきます。
そういう一文があるページは、長年ページを折り曲げてみたり、線を引いたりしていましたが、これらにはちょっと問題点があります。

**問題点1. 読み返したい文章がなかなか見つからない**
→折り目と線だけでは、読み返したい時になかなか見つけられない。

**問題点2. 読み返さない**
→線を引いたままでそのまま読み返さなくなることは案外多い。


これらの原因は**文章が整理されおらず、それを読み返す習慣がないこと**です。
この問題点を解決するアプリを開発することにしました。

主なコンセプトは以下の2つです。
* タイトルごとに文章を記録できる(整理）
* 記録した名言を自動的に通知して思い出させてくれる（習慣化）



**結果的にはこんなものを作りました↓**
[GooglePlay](https://play.google.com/store/apps/details?id=co.websarva.wings.android.myquotations)
名言をため込んでいくアプリなので、本を積読（つんどく）するのになぞらえて、「名言つんどく」としました。

![Google Play アプリ画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/355530c4-789d-15c8-f74e-c946decf1c6d.png)





#3. 開発環境と主なライブラリ

**開発環境**
・Java:11.0.10
・Android studio 4.1.3
・CompileSdkVersion:30
・MinSdkVersion:16
・TargetSdkVersion:30
・BuildToolsVersion:30.0.3

**使用した主なライブラリ**
・Room
・ViewModel
・LiveData
・RecyclerView
・Workmanager
・AsyncTask（非推奨ですが、なんやかんやあって使用）
・Notification
・AlertDialog
・Parcelable
・Navigation
#4. アプリの機能

##タイトルごとの文章記録
まず書籍のタイトルと著者名を入力して、書籍名のフォルダを作成します。
![タイトル作成.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/61076807-7fa9-4220-e151-9497eee6f738.gif)



作成した書籍のフォルダをタップして、その中に名言を作成します。
![名言の作成.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/ce4ee007-57e7-3b25-1b31-9613caaa789d.gif)

これで書籍と名言の2つのRecyclerViewが出来上がります。
書籍のRecyclerViewのHolderは、タイトル、著者名、作成日時を表示しており、
Holderをタップすると、名言のRecyclerViewへ遷移します。
![RecyclerView動作.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/4483761c-018f-d3e9-7bf1-bcd13d6e5c9e.gif)

###苦労したところ
書籍名のRecyclerViewをタップすると、名言のRecyclerViewのActivityへ遷移します。ただ、どの書籍のHolderをタップしても遷移先は名言のActivityだけです。なので、タップした書籍に応じて、表示させる名言のフォルダーの中身を切り替える必要がありました。
また、RecyclerViewのHolderは、必要に応じて作成、削除、順番の並び替えをするので、Holderのpositionで中身の固定ができません。

結果的に**ViewModelとLiveDataを使って、タップした書籍に応じた名言のデータの表示や、並び替えの結果をUIに反映させました。**
ViewModelはAndroidDeveroperのCodelabを参考にして実装しました。
[【Codelabs】Android Room とビュー](https://developer.android.com/codelabs/android-room-with-a-view#0)




##文章をランダムに通知する
この機能の動きは、
「通知してほしい名言のCheckBoxをON ➜ CheckBoxがONになっているHolderからランダムに名言を取得 ➜ 定期的に通知される」
というものです。各文章のCheckBoxをONすると、通知されるようになります。
![チェックボックスON.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/1cd2dc89-6e9c-b470-b95e-a8bdc768b852.gif)


チェックをONにした文章がランダムに選択され、1行目がタイトル、2行目が文章の通知が届きます。
文章の全文を確認する時は、届いた通知をタップするとアプリ内に飛んで全文が表示されます。
![通知タップ内容確認.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/5c1390c9-d21d-d623-2b87-0c770508eebc.gif)



通知履歴をタップしてもアプリに飛びます。
実際に使うときはほぼこっちになりそうです。
![通知履歴タップして内容確認.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/4b382c33-d4f5-c052-e521-eeea6743fec3.gif)


###苦労したところ
当初、どうやって実現すればいいかイメージが湧かなかったので、以下のように構成要素に分解して考えました。

・RecyclerViewにCheckBoxを持たせる（通知ON、OFFのトリガーとして使う）
・通知（Notificaion）の実装
・ランダムに名言を取得するメソッドの作成
・Workmanagerの実装（定期的なバックグラウンドでの処理）


➜これらを1つずつ実装し、その後それぞれをどう関連付けるかを考えて、最終的に1つの機能に落とし込みました。
最初から全体像を考えるのは僕にはできなかったので、とりあえずはこの方法で間違っていなかったかな、と思います。

##フォルダーの並び替え
タイトル、著者名、作成日順で並び替え（昇順、降順）ができます。
以下のgifはそれぞれ昇順から降順へ変更する様子です。
###タイトル順
![タイトル並び替え.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/b998dd19-8986-8b39-20ce-50c9334b2470.gif)
###著者名順
![著者名並び替え.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/554a612f-daee-0108-cc98-49911577cf18.gif)
###作成日時順
![作成日並び替え.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/6f10910d-b0df-ada0-3131-19e5a9372cfe.gif)

###苦労したところ
「一旦並び替えできても別画面に行って戻ってくると、並びが元に戻ってしまう」という問題にぶつかりました。
ViewModelのロジックが影響していたので、そもそものロジックが壊れないように、修正していき何とか動くものができました。
漢字の並びはデフォルトではUnicode順になってしまっていたので、音読み順になるように、修正しています。


##削除機能
削除モードをONにすると、表示が赤くなり、この状態の時だけ右スワイプでの削除ができます。
![ezgif.com-gif-maker (31) (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/d73f26db-8a66-3315-7c07-3e77f4245891.gif)

右スワイプでの削除はサクッと削除できるので取り入れましたが、一方で**操作ミスをすると間違って消してしまう危険がありました**。なので、削除モードを取り入れ、削除モードがONであることをはっきり示すために、画面の色を赤に変更する仕様にしました。

##苦労したところ
右スワイプのON、OFFの切り替えの方法をなかなか見つけられませんでした。
挙動が違うItemTouchHelperを2つ作って、切り替えるなどを試しましたがこれはダメで、
結果的には、 **isItemViewSwipeEnabled()**でスワイプのON、OFFが切り替えられると分かり、実装できました。

```java:TitleListActivity.java
private ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.RIGHT) {

//いろいろ記載省略...

//ボタンタップでmIsDeleteModeのtrue,falseを切り替える
@Override
        public boolean isItemViewSwipeEnabled() {
            return mIsDeleteMode;
        }
}
```

[参考にしたページ：Detach ItemTouchHelper from RecyclerView](https://stackoverflow.com/questions/35345520/detach-itemtouchhelper-from-recyclerview)

##「使い方」について
アプリ作製の参考にするために、Google Playでメモ帳系のアプリをいろいろダウンロードしてみると、どう使えばいいのかイメージがつかみにくいものがいくつかありました。

そこで、使い方の説明を探してみると、**使い方を説明しているアプリが思ったよりありません。**
使えば分かるように設計し、そもそも使い方の説明が不要なのがベストと思いますが、**使った人がどう感じるかは意外と分からないものなのだと思います。**
なので、**自分の中では「使えば分かる」と思う部分についても、一通り説明**するようにしました。

![使い方.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/cd492312-1098-a3bc-1813-fce0ee912aab.gif)

##その他の細かい機能
**タイトル重複の防止**
気づかずに同じタイトルを複数作ってしまうことを避けるため、
既存のタイトルと同じタイトルを作成しようとした場合、AlertDialogで作成不可のメッセージが出ます。
![アラートダイアローグ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/50b45904-2cb6-0084-a051-a8d53016daee.gif)

**タイトル変更不可を知らせるのトースト**
名言作成時にタイトル、著者名を変更すると、意図しない動作をしてしまうので、
トーストでふわっと注意します。
![トースト.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/84c2ec9c-82e1-37e0-f3c2-a01e74d2877f.gif)

**吹き出しっぽいTextview**
名言が表示されるTextview は吹き出しっぽくしました。この方が誰かが名言を言ってる感がちょっと増す気がするからです。
Textview の下に、45度回転させたViewを配置しています。
![吹き出し.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599060/398dc33c-6f84-59ec-7e12-c2ab547b2da3.png)


#5. 学習方法の概要
基本独学で学習をしました。
そもそもJavaでAndroid開発を教えているスクールが（たぶん）ありません。。。

**JavaとAndroidの入門書をとりあえず通読**
まず「すっきりわかるJava入門(インプレス社)」「Androidアプリ開発の教科書(翔泳社)」という書籍を通読しつつ、実際にプログラムを書いて、なんとなーく感触をつかみました（※つかんだ気分）。

ただ、最近のAndroidについての記事はKotlinで書かれている場合が多く、最初からAndroidアプリを作る目的ならKotlinを学んだ方がいいかもしれません。ちなみに、Javaはブログとか過去の記事自体は多いので、エラーの解決方法などの情報は（古いものも多いですが）豊富なように思いました。

###**Web上のコードを拾い読み**
その後は自分が作りたいものを実現できそうなコードを、Web上から拾ってプログラム全体の構造を理解する、ということをやってみました。今思うと読むだけではあまり良くなく、**何か実際に作りながら理解していく方がよかったと思います。**
英語のものだとかなりボリュームのあるチュートリアルの動画があり、Googleドキュメントに自動で文字起こしをして、それをGoogle翻訳で日本語にする、というよくわからん努力も途中してました。

###**作りながら覚える**
これは何かある程度の規模のものを作らないと覚えないなと思い、アプリ作製に着手しました。
後は実装したい機能を調べ、公式のドキュメントを読んだり、技術ブログや、書籍を参考にしてちょっとずつ作っていきました。

##**独学の良いところ**

独学は大変でしたが、良いところもあるので、
**以下に独学の良い点だと思うところを挙げます。**

###**・自分で調べて修正できるようになる**
まず、分からないことがあった場合、検索ワードをどうするか、検索期間をどうするか、などから考える必要があります。検索をした後、自分がやりたいことと関係ある記事かどうかを判別し、どこを参考にして、参考にしないのかも、判断する必要があります。

仮にエラーが出たときに、その都度誰かから答えを教えてもらった場合、解決は早いですが、この過程を飛ばすことになります。その結果、おそらく調べる力と、見つけるまで探す忍耐力が付きにくくなると思います。
「忍耐力」というと精神論っぽいかもしれませんが、かなり重要な要素な気がします。

なので個人的には、**できる限り（脳汁がでそうなくらい）自分で調べていろいろ修正してみて、それでもわからなければ、聞くのがいい気がします。**
もちろん仕事だといつまでも時間をかけられないとは思いますが、基本は一緒なのでは、と想像します。

###**・自力でエラーを解決できるとちょっと自信になる**
**「誰か助けてー！！」と夜な夜な泣き言を言いながらも、結局自分でエラーを解決できると、「ん？俺すごくね...？**」と勘違いすることができます笑

「これもう解決するの無理かもしれない」と思うエラーを何度か解決すると、次に変なエラーが出たときに「これも何とかなるのではないか」という感覚が芽生えていきました（大したエラーではないからかもですが。。。）
曖昧ですが、「なんとなく何とかなるかも」という根拠のない自信を得るには、自力でエラーを解決していくしかない、と思います。


#6. アプリを作ってみた感想
アプリ開発は基本的に以下の繰り返しでした。

実装したい機能➜　実装方法がわからない　➜調べる　➜見つからない　➜それっぽいものが見つかった、と思って実装したら動かない　➜解決方法調べる　➜見つけた気がするが、それで本当にいいのかが分からない（いやもうこれ無理かも。。。と思う）➜ウンウンうめきながらいろいろ試す。途中変なため息が出て手が止まりかける➜　動いた！！（鼻血が出そうになるくらい嬉しい）　➜最初に戻る

いろいろ大変でしたが、**当初妄想するだけだったアプリが、現実に作れた時の喜びは大変なものでした。**
世の中に出回っているものと比べると、全然大したレベルのものではないと思いますが、**とりあえずモノ作りは、まず自己満足が大事と考えてます笑**

Androidはライブラリがいろいろあって面白いことがたくさんできそうなので、
今後もいろいろ作ってみたいと思います。

めでたしめでたし。