0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Android壁紙自動変更アプリ「壁紙キリカエ」の開発記録 - Phase 0: 環境構築編

0
Last updated at Posted at 2026-07-26

はじめに

本記事は、Androidの壁紙を自動で切り替えるアプリ「壁紙キリカエ」の開発記録です。Next.js (TypeScript) + Kotlin のアーキテクチャを採用し、モダンで拡張性の高いアプリを目指します。

この記事では、Phase 0: 環境構築の過程で遭遇した問題と解決方法を記録しています。
筆者がフロントエンドの開発経験はありますがKotlinは初心者レベルです。
筆者のようなKotlin初心者にも理解しやすいように説明も加えています。(そのため記事が非常に長いです。。)

対象読者

  • Androidアプリ開発の初心者〜中級者
  • フロントエンド領域の開発経験のある方
  • AI アシスタント(Claude など)を活用した開発に興味がある方

開発環境

項目 バージョン
OS macOS
IDE Android Studio (最新版)
Kotlin 1.9+
TypeScript 5.0+
Next.js 14+
Android SDK 26+ (Android 8.0+)
補助ツール Claude, Claude Code

プロジェクト概要

アプリ開発の経緯

筆者が使っているAndroid OSのスマホには壁紙を自動で変更できる機能がデフォルトで備わってないので壁紙変更アプリを使っています。
その壁紙変更アプリを使うと、自動で複数の壁紙が変更されるようになります。
しかし使っている壁紙変更アプリは以下のデメリットがあり少々使いづらいものでした。

  • 英語表記でしかなく日本人フレンドリーではない
  • UIが良くなく慣れるまで使い辛い

なら自分好みのアプリを作ってしまおう。ついでに同じように思っている人たちに使ってもらおう。
と思い似た特徴を持つ自分好みのアプリを日本語版で開発することにしました。


技術選定の背景

なぜNext.js+ Kotlinのアーキテクチャなのか?

本アプリでは、Next.js (WebView) + Kotlin (Native) のアーキテクチャを採用しました。
筆者はNativeアプリ開発が初めてでKotlinは初心者レベルです。Kotlinでも十分にUIも開発できますが、Next.jsの方が使い慣れていたのでUIの開発にはNext.jsを採用しました。
ですがNext.jsだけではスマホの壁紙を設定するなどAndoroidのコアモジュールの接続ができません。そこでAndroidのコアモジュールへの接続にはKotlinを使っています。

Next.jsとKotlinの棲み分け

1. Next.jsでUI層の開発

  • Next.js + TypeScript で型安全な開発
  • shadcn/ui で手軽に綺麗なコンポーネントを使用

2. Kotlinでロジック層の開発

  • 壁紙変更、WorkManager、Room Database などは Kotlin で実装
  • Android の標準APIを直接使用できる
  • パフォーマンスが重要な部分はネイティブで

Phase 0: 環境構築の目標

Phase 0 では、開発を開始するための基盤を整えます。

完了条件

  • Android Studio プロジェクトの作成
  • Next.js プロジェクトの作成
  • 必要な依存関係のインストール
  • WebView で Next.js アプリを表示
  • エミュレータでアプリが起動する

タスク一覧

  1. Android プロジェクトの作成
  2. 依存関係の追加 (Hilt, Room, DataStore, WorkManager, Serialization)
  3. プロジェクト構造の作成
  4. Hilt (DI) の設定
  5. Next.js プロジェクトの作成
  6. Next.js のビルド設定
  7. WebView の統合
  8. 動作確認

実装手順

1. Android プロジェクトの作成

1-1. Android Studio で新規プロジェクト作成

Android StudioにあるEmpty Activityのテンプレートを使ってプロジェクトを作成しました。

設定値:

項目
Name 壁紙キリカエ
Package name com.kabegamikirikae.app
Language Kotlin
Minimum SDK API 26 (Android 8.0)

1-2. プロジェクト構造の確認

作成されたプロジェクト構造:

android/
├── app/
│   ├── src/main/
│   │   ├── java/com/kabegamikirikae/app/
│   │   │   └── MainActivity.kt
│   │   ├── res/
│   │   └── AndroidManifest.xml
│   └── build.gradle.kts
└── build.gradle.kts

2. 依存関係の追加

Android プロジェクトでは、build.gradle.kts というファイルで依存関係を管理します。Node.js の package.json に相当するものです。
プロジェクトレベルとアプリレベルでそれぞれに設定します。
Node.jsで言えば、モノレポのルートに設定するpackage.json(プロジェクト全体の設定を管理)と各パッケージに設定するpackage.json(アプリ固有の設定を管理)に分けるイメージです。

本プロジェクトでは、以下のプラグインとライブラリを追加しています。

追加するプラグイン一覧

プラグイン / ライブラリ 種別 目的
com.google.dagger.hilt.android Gradle プラグイン 依存性注入 (DI) フレームワーク。クラス間の依存関係を自動で解決し、テスト容易性と保守性を向上させる
org.jetbrains.kotlin.plugin.serialization Gradle プラグイン Kotlin の JSON シリアライズ/デシリアライズ をコンパイル時に生成。Next.jsとKotlin間を繋ぐBridge 通信でのデータ変換に使用
kotlin-kapt Gradle プラグイン Kotlin の アノテーションプロセッサ。Hilt や Room がコンパイル時にコードを自動生成するために必要

追加するライブラリ一覧

ライブラリ 目的
Hilt (hilt-android, hilt-compiler) DI コンテナ。@Inject@AndroidEntryPoint で依存関係を自動注入するために使用
Room (room-runtime, room-ktx, room-compiler) ローカルデータベース。壁紙の設定情報やフォルダ情報の永続化に使用
DataStore (datastore-preferences) ユーザーの 設定値(変更間隔、テーマなど)を非同期・型安全に保存する
WorkManager (work-runtime-ktx) バックグラウンドタスク のスケジューリング。壁紙の自動変更を確実に実行するために使用
Kotlinx Serialization (kotlinx-serialization-json) Kotlin オブジェクトと JSON の相互変換。WebView ↔ Kotlin の Bridge 通信 でデータをやり取りする際に使用
Coroutines (kotlinx-coroutines-android) Kotlin の 非同期処理 ライブラリ。Room や DataStore の操作、ネットワーク通信などを非同期で実行
AndroidX WebKit (webkit) WebView の拡張ライブラリ。標準 WebView よりも多くの機能(ダークモード対応、プロキシ設定など)を提供

2-1. プロジェクトレベルの build.gradle.kts

まず android/build.gradle.kts(プロジェクトレベル)に、Hilt と Kotlin Serialization のプラグインを apply false で宣言します。これはプラグインのバージョンを一元管理するためで、実際の適用は各モジュール側で行います。

2-2. アプリレベルの build.gradle.kts

次に android/app/build.gradle.kts(アプリレベル)で、プラグインの適用とライブラリの追加を行います。

コード中のキーワード:

  • implementation — アプリ実行時に使うライブラリ
  • kapt — コンパイル時にコードを自動生成するライブラリ(Hilt や Room が該当)
  • testImplementation — テスト時のみ使うライブラリ
android/app/build.gradle.kts
plugins {
    alias(libs.plugins.android.application)
    alias(libs.plugins.kotlin.android)
    id("kotlin-kapt")
    id("com.google.dagger.hilt.android")
    id("org.jetbrains.kotlin.plugin.serialization")
}

android {
    namespace = "com.kabegamikirikae.app"
    compileSdk = 36

    defaultConfig {
        applicationId = "com.kabegamikirikae.app"
        minSdk = 26
        targetSdk = 36
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildFeatures {
        buildConfig = true  // BuildConfig を有効化
    }

    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }

    kotlinOptions {
        jvmTarget = "17"
    }
}

dependencies {
    // AndroidX Core
    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.appcompat)
    implementation(libs.material)
    implementation(libs.androidx.activity)
    implementation(libs.androidx.constraintlayout)

    // Hilt (Dependency Injection)
    implementation("com.google.dagger:hilt-android:2.48")
    kapt("com.google.dagger:hilt-compiler:2.48")

    // Room (Database)
    implementation("androidx.room:room-runtime:2.6.1")
    implementation("androidx.room:room-ktx:2.6.1")
    kapt("androidx.room:room-compiler:2.6.1")

    // DataStore (Settings)
    implementation("androidx.datastore:datastore-preferences:1.0.0")

    // WorkManager (Background tasks)
    implementation("androidx.work:work-runtime-ktx:2.9.0")

    // Kotlinx Serialization (JSON)
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")

    // Coroutines
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")

    // WebView
    implementation("androidx.webkit:webkit:1.9.0")

    // Testing
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
}

3. プロジェクト構造の作成

3-1. パッケージ構造

以下のパッケージ構造を作成します。「UI」「ビジネスロジック」「データ操作」を分離します。

app/src/main/java/com/kabegamikirikae/app/
├── MainActivity.kt          … アプリの入口。WebViewを表示する画面
├── KabegamiApplication.kt   … アプリ全体の初期化処理(Hiltの起点)
│
├── bridge/                  … WebView(TypeScript) ↔ Kotlin の通信層
│   ├── BridgeInterface.kt       … JavaScriptから呼び出せる関数を定義
│   ├── EventEmitter.kt          … Kotlin → JavaScript へイベントを送る仕組み
│   └── WebViewBridge.kt         … 通信全体を管理するクラス
│
├── domain/                  … ビジネスロジック(アプリの「ルール」)
│   ├── model/                   … データの型定義(壁紙、フォルダなど)
│   ├── repository/              … データ操作のインターフェース(契約書)
│   └── usecase/                 … 具体的な処理(「壁紙を変更する」など)
│
├── data/                    … データの実際の保存・取得処理
│   ├── local/
│   │   ├── database/            … Room データベースの定義
│   │   ├── datastore/           … ユーザー設定の保存(変更間隔など)
│   │   └── dao/                 … DB へのクエリ(データの読み書き操作)
│   ├── repository/              … domain/repository の実装(実際の処理)
│   └── service/                 … 壁紙変更などの Android API を呼ぶ処理
│
├── worker/                  … バックグラウンド処理(WorkManager)
│                                  アプリを閉じても壁紙を自動変更する処理
│
└── di/                      … 依存性注入(Hilt)の設定
    ├── AppModule.kt             … アプリ全体で使う部品の登録
    ├── DatabaseModule.kt        … DB 関連の部品の登録
    └── RepositoryModule.kt      … Repository 関連の部品の登録

Node.js の一般的なプロジェクト構造に置き換えると、以下のような対応関係になります。

Android のディレクトリ Node.js で例えると
bridge/ API ルーター(Express の routes/
domain/model/ TypeScript の型定義(types/
domain/usecase/ サービス層(services/
domain/repository/ リポジトリのインターフェース
data/ 実際の DB 操作(Prisma、TypeORM など)
worker/ バックグラウンドジョブ(Bull、cron)
di/ DI コンテナの設定(NestJS の module

3-2. KabegamiApplication.kt の作成

Hilt(DI フレームワーク)を使うには、Application クラスに @HiltAndroidApp アノテーションを付ける必要があります。これがアプリ全体の DI の起点となり、各クラスへの依存性の自動注入が有効になります。

app/src/main/java/com/kabegamikirikae/app/KabegamiApplication.kt
package com.kabegamikirikae.app

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class KabegamiApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        // 初期化処理
    }
}

4. Hilt の設定

Hilt は Android 用の依存関係インジェクション ライブラリです。これを使うことで、プロジェクトで依存関係の注入(DI)を手動で行うためのボイラープレートが減ります。(参考

4-1. AndroidManifest.xml の更新

AndroidManifest.xml は、Android アプリの「設定ファイル」です。このファイルではアプリの基本情報や必要な権限、画面(Activity)の登録などを宣言します。

android/app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 権限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    <uses-permission android:name="android.permission.SET_WALLPAPER" />

    <application
        android:name=".KabegamiApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.壁紙キリカエ">

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

各権限の役割は以下の通りです。

権限 用途
INTERNET WebView で Next.js のアセットを読み込むため
READ_MEDIA_IMAGES ユーザーの端末から壁紙用の画像を読み取るため
POST_NOTIFICATIONS 壁紙変更の通知をユーザーに表示するため
SET_WALLPAPER 端末の壁紙を変更するため

ポイント:

  • android:name=".KabegamiApplication" — 3-2 で作成した Application クラスを指定。これがないと Hilt の DI が動作しない
  • android:exported="true" — ホーム画面のランチャーからアプリを起動可能にする設定
  • intent-filter 内の MAIN + LAUNCHER — この Activity がアプリの起動画面であることを OS に伝える

5. MainActivity の実装

5-1. WebView 統合

app/src/main/java/com/kabegamikirikae/app/MainActivity.kt
package com.kabegamikirikae.app

import android.os.Bundle
import android.webkit.WebView
import androidx.appcompat.app.AppCompatActivity
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    private lateinit var webView: WebView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        webView = WebView(this).apply {
            settings.apply {
                javaScriptEnabled = true
                domStorageEnabled = true
                allowFileAccess = true
                allowContentAccess = true
            }

            // デバッグ用
            if (BuildConfig.DEBUG) {
                WebView.setWebContentsDebuggingEnabled(true)
            }

            // アセットからHTMLを読み込み
            loadUrl("file:///android_asset/webapp/index.html")
        }

        setContentView(webView)
    }

    override fun onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack()
        } else {
            super.onBackPressed()
        }
    }
}

ポイント:

  • @AndroidEntryPoint で Hilt の DI を有効化
  • javaScriptEnabled = true で JavaScript を有効化
  • デバッグ時は Chrome DevTools でデバッグ可能
  • 戻るボタンで WebView の履歴を戻る

6. Next.js プロジェクトの作成

6-1. プロジェクトの初期化

UIライブラリにはAIフレンドリーなtailwind cssとshadcn-uiを採用します。

cd ~/Projects/kabegami-kirikae

# Next.js プロジェクトを作成
npx create-next-app@latest webapp \
  --typescript \
  --tailwind \
  --app \
  --no-src-dir \
  --import-alias "@/*"

cd webapp

# 追加パッケージのインストール
npm install zustand @tanstack/react-query lucide-react

# shadcn/ui のセットアップ
npx shadcn-ui@latest init -y

6-2. Next.js のビルド設定

webapp/next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  distDir: 'out',
  assetPrefix: './',
  images: {
    unoptimized: true,
  },
  trailingSlash: true,
}

module.exports = nextConfig

重要な設定:

  • output: 'export' で静的エクスポート
  • assetPrefix: './' で相対パス指定
  • images: { unoptimized: true } で画像最適化を無効化(WebView 用)

6-3. ビルドスクリプトの追加

webapp/package.jsonscripts セクションに追加します。

webapp/package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "build:android": "next build && node scripts/copy-to-android.js",
    "start": "next start",
    "lint": "next lint"
  }
}

6-4. Android へのコピースクリプト

Next.jsでビルドしたファイルをAndroidでWebview表示するために、ビルド後のファイルをAndoroidへコピーするスクリプトを用意しました。

webapp/scripts/copy-to-android.js
const fs = require('fs-extra');
const path = require('path');

const source = path.join(__dirname, '../out');
const dest = path.join(__dirname, '../../android/app/src/main/assets/webapp');

console.log('📦 Copying Next.js build to Android assets...');
console.log(`Source: ${source}`);
console.log(`Destination: ${dest}`);

try {
  // 既存のディレクトリを削除
  if (fs.existsSync(dest)) {
    fs.removeSync(dest);
    console.log('🗑️  Removed old webapp directory');
  }

  // コピー
  fs.copySync(source, dest);
  console.log('✅ Successfully copied Next.js build to Android assets!');
} catch (error) {
  console.error('❌ Error copying files:', error);
  process.exit(1);
}

7. Next.js の基本ページ作成

7-1. ホーム画面

webapp/app/page.tsx
export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-center p-8">
      <div className="text-center">
        <h1 className="text-4xl font-bold mb-4">
          壁紙キリカエ
        </h1>
        <p className="text-xl text-gray-600 mb-8">
          Kabegami Kirikae
        </p>
        <div className="bg-gradient-to-r from-indigo-500 to-purple-500 text-white px-6 py-3 rounded-lg">
          Phase 0: 環境構築完了!🎉
        </div>
      </div>
    </main>
  )
}

7-2. レイアウト

webapp/app/layout.tsx
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import './globals.css'

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
  title: '壁紙キリカエ',
  description: 'お気に入りの画像を自動で壁紙に',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="ja">
      <body className={inter.className}>{children}</body>
    </html>
  )
}

8. ビルドと実行

8-1. Next.js のビルド

ビルドからAndroidプロジェクト配下へのコピーまでを行うスクリプト(npm run build:android)を実行します。

cd ~/Projects/kabegami-kirikae/webapp
npm run build:android

8-2. Android アプリの実行

  1. Android Studio で Sync Project with Gradle Files
  2. Build > Rebuild Project
  3. エミュレータを起動

遭遇したエラーと解決方法

Phase 0 の実装中に遭遇したエラーとその解決方法を記載します。

エラー1: compileSdk のバージョン不一致

エラー内容

Dependency 'androidx.core:core:1.17.0' requires libraries and applications that
depend on it to compile against version 36 or later of the Android APIs.
:app is currently compiled against android-34.

原因

AndroidX の最新版(androidx.core 1.17.0)が Android API 36 を要求していたが、プロジェクトはバージョン違いの API 34 でコンパイルしていた。

解決方法

android/app/build.gradle.ktscompileSdktargetSdk を更新しました:

android/app/build.gradle.kts
android {
-   compileSdk = 34
+   compileSdk = 36
    
    defaultConfig {
-       targetSdk = 34
+       targetSdk = 36
    }
}

補足

項目 説明
compileSdk コンパイルに使用する Android API バージョン
targetSdk アプリが対象とする Android API バージョン
minSdk = 26 アプリがインストール可能な最低バージョン

compileSdk を上げても minSdk は変わらないため、古いデバイスでも動作します。


エラー2: Jetpack Compose のコンパイルエラー

エラー内容

e: Backend Internal error: Exception during IR lowering
File being compiled: .../ui/theme/Theme.kt
Caused by: java.lang.IllegalStateException: Unresolved annotation type: [Error type: Unresolved type for Composable]

原因

Android Studio の Empty Activity テンプレートが、デフォルトで Jetpack Compose のファイルを生成していた:

  • ui/theme/Theme.kt
  • ui/theme/Color.kt
  • ui/theme/Type.kt

しかし、このプロジェクトでは WebView を使用するため Compose は不要だったので削除することにします。

解決方法

Compose 関連ファイルを削除する。ついでにbuild.gradle.kts から Compose 設定を削除する
削除する項目:

buildFeatures {
    compose = true  // 削除
}

composeOptions {
    kotlinCompilerExtensionVersion = "1.5.1"  // 削除
}

// dependencies内のCompose関連も削除

エラー3: BuildConfig が見つからない

エラー内容

e: Unresolved reference 'BuildConfig'.

MainActivity.kt の以下の行でエラー:

if (BuildConfig.DEBUG) {
    WebView.setWebContentsDebuggingEnabled(true)
}

原因

Android Gradle Plugin 8.0 以降、BuildConfig はデフォルトで生成されなくなったにも関わらずBuildConfigを使おうとしていた

解決方法

android/app/build.gradle.ktsbuildFeatures を追加:

android/app/build.gradle.kts
android {
    // ...
    
    buildFeatures {
        buildConfig = true  // BuildConfig を有効化
    }
    
    // ...
}

補足

BuildConfig クラスは、ビルドタイプ(Debug/Release)やバージョン情報などを含む自動生成クラスになります。有効化することで:

  • BuildConfig.DEBUG: デバッグビルドかどうか
  • BuildConfig.VERSION_NAME: バージョン名
  • BuildConfig.APPLICATION_ID: パッケージ名

などが使用できます。


エラー4: AppCompat テーマエラー

エラー内容

java.lang.RuntimeException: Unable to start activity
Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

原因

MainActivityAppCompatActivity を継承しているのに、themes.xmlTheme.Material を使用していた。

元の themes.xml:

<style name="Theme.壁紙キリカエ" parent="android:Theme.Material.Light.NoActionBar" />

解決方法

android/app/src/main/res/values/themes.xml を修正してMaterialではなくAppCompatを使うようにする:

xml:android/app/src/main/res/values/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
-   <style name="Theme.壁紙キリカエ" parent="Theme.AppCompat.Light.NoActionBar">
+   <style name="Theme.壁紙キリカエ" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/purple_500</item>
        <item name="colorPrimaryDark">@color/purple_700</item>
        <item name="colorAccent">@color/teal_200</item>
    </style>
</resources>

AppCompatActivity を使う場合、テーマは Theme.AppCompat の派生である必要があります。


完成した構成

Phase 0 完了時のプロジェクト構造:

kabegami-kirikae/
├── android/
│   ├── app/
│   │   ├── src/main/
│   │   │   ├── java/com/kabegamikirikae/app/
│   │   │   │   ├── MainActivity.kt
│   │   │   │   ├── KabegamiApplication.kt
│   │   │   │   ├── bridge/
│   │   │   │   ├── di/
│   │   │   │   ├── domain/
│   │   │   │   ├── data/
│   │   │   │   └── worker/
│   │   │   ├── res/
│   │   │   │   ├── values/
│   │   │   │   │   ├── colors.xml
│   │   │   │   │   ├── strings.xml
│   │   │   │   │   └── themes.xml
│   │   │   │   └── mipmap/
│   │   │   ├── assets/
│   │   │   │   └── webapp/  ← Next.jsビルド成果物
│   │   │   └── AndroidManifest.xml
│   │   └── build.gradle.kts
│   └── build.gradle.kts
│
├── webapp/
│   ├── app/
│   │   ├── page.tsx
│   │   ├── layout.tsx
│   │   └── globals.css
│   ├── scripts/
│   │   └── copy-to-android.js
│   ├── next.config.js
│   └── package.json
│
└── docs/
    └── (設計ドキュメント)

動作確認

エミュレータでの表示

アプリを起動すると、以下の画面が表示されます。

Chrome DevTools でのデバッグ

WebView のデバッグもできます:

  1. Chromeで chrome://inspect を開く
  2. 接続されているデバイスに「壁紙キリカエ」が表示される
  3. inspect をクリック
  4. Chrome DevTools が開き、要素の検証やコンソール確認が可能

次のステップ

Phase 0 が完了したので、次は Phase 1: Bridge 実装 (作成中)に進みます。

Phase 1 の目標

  • TypeScript ↔ Kotlin 間の通信基盤を構築
  • JavascriptInterface の実装
  • Bridge Client の実装
  • 型安全な通信の確立

予定している機能

  • ping() メソッドで疎通確認
  • Kotlin から TypeScript へのイベント送信
  • エラーハンドリングの実装

学んだこと

Phase 0 を通じて学んだことをまとめます。

1. AI アシスタントの効果的な活用

今回はAndroidの開発内容を理解するために半分手動・半分自動で開発しました。Claudeを使って実装方法を検討して対話しながら仕様書を作成し、Claude Codeで開発しました。

Claude の使い方:

  • 設計段階での相談
  • エラーメッセージの診断
  • コードレビュー
  • ドキュメント作成

Claude Code の使い方:

  • プロジェクト構造の自動生成
  • 依存関係の一括設定
  • 複数ファイルの同時編集

ClaudeとClaude Codeを使い分ける利点:

  • 自動化できる部分は Claude Code に任せられる
  • 重要な判断はClaudeで相談しながら進められる
  • 効率と理解のバランスが取れる

エラーが見つかった場合も、Claude Codeで何となく解消するのではなく、Claudeと会話しながらエラーへの対処方法を検討しエラーの解消を行いました。
しかし、これらはすべてClaude Code側だけでできることなので、ClaudeとClaude Codeを使い分ける必要はないかなと思いました。

2. 設計ドキュメントの重要性

Phase 0 を始める前に詳細な設計ドキュメントを作成したことで:

  • 迷わず実装できた
  • エラーが出ても方針がブレなかった
  • Claude, Claude Codeへの指示が的確になった

まとめ

Phase 0 では、開発環境の構築と WebView での Next.js 表示までを完了しました。

達成したこと

  • ✅ Android プロジェクトの作成
  • ✅ 必要な依存関係のインストール
  • ✅ Hilt (DI) の設定
  • ✅ Next.js プロジェクトの作成
  • ✅ ビルドスクリプトの作成
  • ✅ WebView での表示確認
  • ✅ 各種エラーの解決

参考リンク


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?