スキルアップ

Android開発の初心者がアプリ公開するまでの流れ・実況|1日目~18日目

こんな方におすすめ

  • Android開発をやってみたい方
  • Androidアプリをゼロから公開するまでの流れを知りたい方

[toc]

アラフォーの私、急にAndroidのアプリを作ってみたくなりました。

IT系の会社に企画職として勤めていますが、アプリ実装の経験はゼロ。

途中で諦めるかもしれませんが、非エンジニアがアプリ開発をゼロから行ったらどうなるのか記録として残したいと思います。

もくじ
  1. 開発の流れをざっくり理解
  2.  Androidアプリ開発の手順
    1.  Android Studioをインストールする(1日目)
    2.  Android Studioでプロジェクト作成(1日目)
    3.  Android Studioの画面を理解(2日目)
    4. Android Studioのエミュレータを動かしてみる(3日目)
    5. Android StudioのText ViewのAlignを理解する(4日目)
    6. Android StudioのText Viewのスタイルを変更してみる(5日目)
    7. Android Studioのエラーを確認してみる(5日目)
    8. Android Studioのエラーに はまる(6日目)
    9. Android Studioのディレクトリ構成、読み方(7日目)
    10. AndroidのActivity、概念について(11日目)
    11. Android のUI関連(12日目)
    12. Android ViewGroup(13日目)
    13. Android開発のバージョン管理「Git」とは(14日目)
    14. Google Play consoleの「サービスとAPI」「ライセンスとアプリ内課金」はどこへ行った?(15日目)
    15. Android アプリ開発手順(16日目)
    16. Android アプリ内課金、GooglePlay決済 導入手順(17日目)
    17. Android アプリ内課金のサンプルコード(18日目)
  3. Google Cloud(GCP)について
    1.  主なサービス|GCP

開発の流れをざっくり理解

まず最初に公式マニュアルを閲覧してみました。

https://developer.android.com/?hl=ja

パッと見、何から始めたら良いか分かりにくいし、深いところは英語で記載されているので別の手段を探すことにしました。

今の時代、動画で学習した方が効率がよさそうなので、Youtubeで検索してみましたが自分に合いそうな動画が見つからない。

いろいろ探して、動画学習サイト「ドットインストール」に行き着きました。

ドットインストール「Androidアプリ開発入門」 

こちらで流れを理解しながら、必要な準備を進めていきます。

 Androidアプリ開発の手順

 Android Studioをインストールする(1日目)

Android開発環境である「Android Studio」をダウンロードします。

https://developer.android.com/studio?hl=ja

ダウンロードが終わったら、起動して画面に従いインストールします。

インストールのオプションであるvirtual deviceなどもOnにした2.7GBも使用したみたいです。

 Android Studioでプロジェクト作成(1日目)

起動するとWelcome画面が表示されますので、New Projectを選択。

テンプレートを選択する画面が表示されたので、ひとまずPhone and Tabletの項目の「Bottom Navigation Activity」を選択。

プロジェクト名を適当につけて、開発言語、最低対象OSVerを指定します。今回は言語「Kotlin(ことりん)」、最小OSVer「API 26」としました。

英語ばっかりで良くわからない。日本語に切り替えたい。

 Android Studioの画面を理解(2日目)

左側のツールウィンドウをポチポチしてみる。

フォルダ構成などは後から理解しよう。

とりあえず、触っている感が欲しいのでlayoutフォルダでアプリ画面をいじってみる。

activity_main.xmlなるファイルがアプリ画面のUIをつかさどるようだ。

画像、スイッチ、アイコンを並べてみる。

なんか楽しい。

Android Studioのエミュレータを動かしてみる(3日目)

layoutでtext Viewにて「Hello World」と真ん中に配置。

さらにPixel5のエミュレータで表示してみました。

なぜか左に寄っている。

バランスよく配置する方法はまた次回勉強しよう。

とにかくに今は触って慣れていくことが大切。

Android StudioのText ViewのAlignを理解する(4日目)

「Hello World」をバランスよく配置するにはAlignで制約を付ける必要があるみたいです。

TextView選択時の上部メニューに階段みたいなアイコンが現れるのでそちらから、Horizontally、Verticallyを選択するとバネ状の紐が出てきます。

いろいろ触って挙動を理解したいと思います。

 

Android StudioのText Viewのスタイルを変更してみる(5日目)

TextView選択時の右サイドメニューに虫眼鏡アイコンがあるので、そちらからTextSizeやTextStyleが変更でします。

少し理解できてきた。

Android Studioのエラーを確認してみる(5日目)

layoutを調整中に、エラーが発生した際に右上にマークが表示されるようだ。

こちらのマークをクリックすると画面下部にエラー原因の詳細が表示される。よく確認してみたいと思う。

Android Studioのエラーに はまる(6日目)

TextViewの宣言部分でエラーが表示され、どうしても解決できない。

Unresolved reference: messageTextView

Variable expected

Parameter 'view' is never used

いろいろ調べても解決に至らない。

Android Studioのディレクトリ構成、読み方(7日目)

TextViewの宣言部分でエラーが解決できないので、基本に立ち戻ることにした。

本日はディレクトリ構成やそもそもの読み方などを理解する。

最初に覚えたいディレクト構成、ファイルをまとめておく。

Project
|
|-- app/src/main/res(アップ/ソース/メイン/リソース)
| ※画像、図形、テキストなどリソースを入れる場所
|
|-- app/src/main/java([省略]/ジャバ)
| ※JavaやKotlinのコードを入れる場所
|
|-- app/build.gradle([省略]/ビルドグレードル)
| ※SDKVer、外部ライブラリなど ビルドに必要な情報を示すファイル
|
|-- app/src/main/AndroidManifest.xml([省略]/アンドロイドマニフェスト.エックスエムエル)
※アプリの構成情報を示すファイル

リソースディレクトリ(8日目)

リソースディレクトリ「app/src/main/res」は画像、図形、テキストなどリソースを入れる場所。

主要なファイルについてまとめる。

values/strings.xml

アプリ内のUIで表示する文字列を定義。

※Kotlinのコード上に文字列を直接書くことはしない。言語設定によって切り替えるため。

values/colors.xml

アプリ内の利用する色コードを定義。

values/themes.xml

UIパーツの見た目の変更を定義。

ビルドグレードル(9日目)

ビルドグレードル「app/build.gradle」はSDKVer、外部ライブラリなど ビルドに必要な情報を示すファイル。

こちらに記載されている主要なワードについてまとめる。

アプリバージョン:versionCode、versionName

アプリのバージョンを定義。

app/build.gradleファイルのandroid関数にあるdefaultConfig部分で記載されている。

ユーザには見えない内部バージョン「versionCode」と、ユーザに見えるバージョン「versionName」で定義する。

それぞれの形式は以下の通り。

versionCode:1~2100000000の整数

versionName: x.yと整数とピリオドの形式。xはメジャーバージョン、y以降はマイナーバージョン。3桁の場合はx.y.zとなりzはバグ修正バージョンで扱われることが多い。

ビルドバージョン:compileSdk

どのAndroid SDKバージョンでビルドするかの定義。

APIレベルで指定する。

AndroidOS 9は28を指定。以降、OS10は29、OS11は30、OS12は31となる。

最低バージョン:minSdk

動作可能な最低Androidバージョンを指定する。APIレベルで指定する。

パッケージ名:applicationId

アプリを特定する一意なID。

例えばGoogleマップだったら「com.google.android.apps.maps」

外部依存ライブラリ:dependencies

外部のライブラリの依存関係を宣言する場所。

アンドロイドマニフェスト(10日目)

アンドロイドマニフェスト「app/src/main/AndroidManifest.xml」はアプリの構成情報を示すファイル。

画面構成:activity

アプリにどのような画面があるのかを記載。

サービス:service

アプリにどのようなサービスを持つのかを記載。

サービス例:バックグラウンド処理、プッシュ通知

アプリ名、アイコン:label、icon

アプリ名やアプリアイコンを記載。

別アプリからの起動方法:intent-filter

別アプリで共有を押した際の自アプリの起動方法を記載。

AndroidのActivity、概念について(11日目)

Activityという機能を利用して1枚の画面を実装。

実際はAndroidバージョン間の互換性を維持するクラスであるAppCompatActivityを使う。

このActivityを起点に処理が展開していく。

Activityのライフサイクル(11日目)

画面のステートによって呼ばれるメソッドとその順序。

ステート例:画面開く、画面を閉じる、バックグラウンドに遷移

メソッド例:onCreate(初期化)、onStart(開始)、onResume(直前呼び出し、履歴イメージ)、onDestroy(終了)

Android のUI関連(12日目)

大事なUI概念をまとめる。

 View

Viewとは画面上に表示するためのコンポーネント(TextView、ImageView、Button)。Viewはlayout XMLで記述。

 layout XMLとコードの関係

layout XMLをViewインスタンスに変換することでプログラム上で利用できる。

XMLはViewの束をViewBindingでまとめる。

 TextView

文字列を表示するためのView。IDとか色、サイズを指定。

 Button

ボタンを表示するためのView。IDとか色、サイズを指定。

サイズ単位

解像度に依存するpx単位は利用できない。

基本的なサイズ指定はピクセル密度を考慮したdpを使用。

テキストのサイズ指定はピクセル密度とOSを考慮したspを使用。

Android ViewGroup(13日目)

TextView、Buttonなどを並べるコンポーネントをViewGroupという。

ViewGroupの例。

 FrameLayout(フレームレイアウト)

Viewを上にどんどん重ねて表示

 

 LinearLayout(リニアレイアウト)

Viewを縦方向、横方向に並べて表示。

ConstraintLayout(コンストレントレイアウト)

View同士の並べ方を定義して表示

ScrollView(スクロールビュー)

画面をはみ出る大きなViewをスクロール可能にする

RecyclerView(リサイクラービュー)

スクロール可能な表示領域のみViewを配置。

Android開発のバージョン管理「Git」とは(14日目)

プログラム開発を行っていると急に不具合が発生して、まったく動かなくなることがある。

直前で行った修正が影響しているのだが、どこの修正だったのか覚えていない。

正常に動いていたバージョンに戻すこともできない。

改めて、プログラムのバージョン管理が必要であると思い知らされる。

Android開発のバージョン管理は「Git」が用いられる。読み方ギット

Gitとは分散型バージョン管理システム

Gitではリポジトリと呼ばれる「ファイルと履歴情報を保有する領域」で管理される。

個人が開発する際は、ローカルストレージにリポジトリをコピー(プル)して作業する。

これは「ローカルリポジトリ」という。

作業した成果物はサーバー上の「リモートリポジトリ」に集約(プッシュ)する。

GitとGitHubの違い

Gitはバージョン管理の仕組みなのに対して、GitHub(ギットハブ)はその仕組みをインターネット上で管理して複数人で作業できるホスティングサービスの一つ。

類似サービスに「Bitbucket(ビットバケット)」などがある。

Gitの初期設定

こちらのサイトを参考にした。

tech-blog.rakus

Google Play consoleの「サービスとAPI」「ライセンスとアプリ内課金」はどこへ行った?(15日目)

アプリ内課金を実装するにあたりライセンスが必要になった。

ネット上に記事をみる限りでは「サービスとAPI」という項目の下部にあるらしいのだが、その項目自体が見当たらない。

2020年末にUI変更になったのでその影響で表示場所が変わったようだ。新しい場所は以下の通り。

「ライセンス」は「収益化のセットアップ」に移動

(それぞれのアプリ)>「収益化のセットアップ」>(Google Play 請求サービス)「ライセンス

同じ階層に「リアルタイムデベロッパー通知」もあるので、ここでトピック名を指定できる。

 

Android アプリ開発手順(16日目)

アプリ開発の手順は以下の流れになる。

step
1
プロジェクト作成

step
2
strings.xmlに表示内容を記載

step
3
layout.xmlに画面構成を記載

step
4
MainActivity.ktに処理内容を記載

step
5
動作確認・修正

さらに公開を踏まえると

step
6
ファイル書き出し

step
7
GooglePlayconsoleにアップ・審査

step
8
アプリ公開

Android アプリ内課金、GooglePlay決済 導入手順(17日目)

GooglePlay決済の導入手順についてまとめておく。

 Google Play Billing Libraryを追加

アプリ内課金を実装するためのライブラリ「Google Play Billing Library」をアプリに追加する。

現在のライブラリーの最新バージョンは5.0.x。最新情報は公式サイトを参照。

https://developer.android.com/google/play/billing/release-notes

 Google Play Consoleで各種設定を行う

Google Play ConsoleでGooglePlay Developer APIアクセス許可。

課金アイテム作成。

GCPで各種設定を行う

定期購入アイテム(サブスクリプション)の場合は定期的に状態が変化をとらえるためGoogle Cloud Platform(通称 GCP)登録。

Pub/Subでトピックを作成。

PlayConsoleのリアルタイムデベロッパー通知欄にGCPのトピック名を設定。

定期購入アイテム(サブスクリプション)の状態確認

Google Play Developer APIのPurchases.subscriptions:getをからサブスクの状態を取得する。

GET https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}

packageName:アプリのパッケージ名(applicationId)。Googleマップだったら「com.google.android.apps.maps」

subscriptionId:サブスクリプションのID。Play Consoleで作成した定期購入アイテムのID。例「premium_course01」

token:PurchaseToken。サブスク購入時に発行されるトークン。定期購入が切れるまでは同一トークン。解約、再購入したら別トークンになると思われる。例「xxxxxx」

 

Android アプリ内課金のサンプルコード(18日目)

GooglePlay決済のサンプルコード例をchatGPTに確認してみました。

build.gradle|アプリ内課金

まず、build.gradleファイルに以下の依存関係を追加する。

 build.gradle
dependencies {
...
implementation 'com.android.billingclient:billing:5.0.0'
...
}

Activity|アプリ内課金

次に、アプリで課金を行うためのActivityを追記します。

このActivityでは、Google Play Billing Libraryを使用して、商品情報を取得し、購入をつづけて行います。

 Activity
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingClientStateListener;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.SkuDetails;
import com.android.billingclient.api.SkuDetailsParams;
import com.android.billingclient.api.SkuDetailsResponseListener;
import java.util.ArrayList;
import java.util.List;
public class BillingActivity extends AppCompatActivity implements PurchasesUpdatedListener {
private BillingClient billingClient;
private Button purchaseButton;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_billing);
purchaseButton = findViewById(R.id.purchase_button);
purchaseButton.setEnabled(false);
billingClient = BillingClient.newBuilder(this)
.setListener(this)
.enablePendingPurchases()
.build();
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(@NonNull BillingResult billingResult) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
purchaseButton.setEnabled(true);
}
}
@Override
public void onBillingServiceDisconnected() {
// Retry connection
}
});
purchaseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
List skuList = new ArrayList<>();
skuList.add("product_id");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(@NonNull BillingResult billingResult, @Nullable List skuDetailsList) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && skuDetailsList != null) {
for (SkuDetails skuDetails : skuDetailsList) {
if (skuDetails.getSku().equals("product_id")) {
BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
billingClient.launchBillingFlow(BillingActivity.this, billingFlowParams);
break;
}
}
}
}
});
}
});
}
@Override
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List purchases) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && purchases != null) {
for (Purchase purchase : purchases) {
if (purchase.getSku().equals("product_id")) {
// Handle successful purchase
}
}
}
}
}

レイアウトXML|アプリ内課金

最後に、ActivityのレイアウトXMLファイルの例です。

 レイアウトXML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test Product"
android:textSize="24sp"
android:textStyle="bold" />
<Button
android:id="@+id/purchase_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Purchase" />
</LinearLayout>

上記の例では、商品IDとして "product_id" を使用しています。

実際のアプリケーションでは、Google Play Consoleで設定した商品IDを使用する必要があります。

また、このサンプルコードでは、購入が成功した場合には "Handle successful purchase" の部分で適切な処理を行う必要があります。

例えば、プレミアムコンテンツをアクティブにするためのフラグを設定したり、購入済みの商品の一覧を更新したりすることができます。

Google Cloud(GCP)について

Google Cloudは「Google Cloud Platform」や「GCP」と呼ばれるクラウドサービスの一つです。

 

類似のサービスで有名なものとしてAmazonAWS(Amazon Web Service)、MicrosoftAzure

あります。

 主なサービス|GCP

GCPの主なサービスを3つ紹介します。

Google App Engine(GAE)|GCP

サーバ環境でアプリケーションを公開できるプラットフォームサービス。

 

GAEの主な特長として、アクセス集中時に自動でサーバー台数を増強し、サーバーダウンを防ぐ点にあります。そしてアクセスが落ち着くと、適切なサーバー台数に戻し、運用コストも抑えられます。

BigQuery(ビッグクエリ)|GCP

ビッグデータの解析サービスです。

数TB級のビッグデータを瞬時に解析処理することができます。

Cloud Storage |GCP

ストレージサービスです。

保存データ量は無制限、かつ自動バックアップ、安全で耐久性の高いのが特長といえます。

Web上に公開することもできます。

Cloud Pub/Sub|GCP

非同期メッセージサービスです。

データを非同期で受信、送信することができます。

Googleサービスとの連携がしやすいのも特長の一つ。

この仕組みを使って、GooglePlayのアプリケーションのサブスク状態管理ができます。

Pub/Sub用語

Publisher:メッセージを作成してトピックに送信するアプリケーション(データの送り手)
Topic:パブリッシャーによるメッセージの送信先となるリソース
Subscription:サブスクライバーに送信するメッセージの設定
Subscriber:メッセージを受信するアプリケーション(データの受け手)
Ack(確認応答):サブスクライバーがメッセージを受信したら、確認情報をサブスクリプションに返す


本日はここまで。

続く

(本ページは順次 追記していきます)

---- 当サイトのPRをさせてください ----

当サイトは「社会人に役立つ仕事術、生活術、スキルアップ術」を発信しております。また来ていただけたらたいへん嬉しいです。

ぜひブックマークをお願いします。

iPhoneの方:
ブラウザ下部の[↑]ボタン > [ホーム画面に追加]もしくは[ブックマーク追加]

Androidの方:
ブラウザ右上の [︙]ボタン > [ホーム画面に追加(アプリをインストール)] もしくは[☆タップ]

PCの方:
ブラウザ 右上の[☆]ボタン、もしくはキーボード[Ctrl]+[D]

またのお越しをお待ちしております。

\面白かったらシェアお願いします/

-スキルアップ
-,