AWS Amplifyを使用したAndroidアプリの構築

# AWS Amplifyを使用したAndroidアプリの構築（Kotlin版）

## 目次
1. [AWS Amplifyのセットアップ](#1-aws-amplifyのセットアップ)
2. [Amplifyプロジェクトの初期化](#2-amplifyプロジェクトの初期化)
3. [Amazon Cognitoでユーザー認証の構成](#3-amazon-cognitoでユーザー認証の構成)
4. [Amazon S3ストレージの構成](#4-amazon-s3ストレージの構成)
5. [Androidアプリの構築](#5-androidアプリの構築)
   - [a. Android Studioを開く](#a-android-studioを開く)
   - [b. build.gradleファイルの更新](#b-buildgradleファイルの更新)
   - [c. Amplifyの設定](#c-amplifyの設定)
   - [d. ユーザー認証の実装](#d-ユーザー認証の実装)
   - [e. S3へのファイルアップロード機能の実装](#e-s3へのファイルアップロード機能の実装)
6. [アプリのビルドと実行](#6-アプリのビルドと実行)
7. [注意事項](#7-注意事項)

## 1. AWS Amplifyのセットアップ

### a. AWSアカウントの作成
1. [AWS公式サイト](https://aws.amazon.com/console/)にアクセスし、「Create an AWS Account」をクリック。
2. 指示に従ってアカウントを作成します。

### b. Node.jsとnpmのインストール
1. [Node.js公式サイト](https://nodejs.org/)からNode.jsをインストールします。
2. コマンドプロンプトを開き、以下のコマンドでNode.jsとnpmが正しくインストールされていることを確認します。

   ```bash
   node -v
   npm -v
   ```

### c. Amplify CLIのインストール
1. コマンドプロンプトを開き、以下のコマンドを実行してAmplify CLIをインストールします。

   ```bash
   npm install -g @aws-amplify/cli
   ```

### d. Amplify CLIの設定
1. コマンドプロンプトで次のコマンドを入力してAmplifyを構成します。

   ```bash
   amplify configure
   ```

2. 指示に従い、以下のタスクを行います：
   - AWS管理コンソールで「IAM」を検索して選択します。
   - 左側のナビゲーションメニューから「Users」をクリックし、「Add user」をクリックします。
   - ユーザー名を設定（例: `amplify-user`）。
   - **Access type**で「Programmatic access」にチェック。
   - 次のステップで「Attach existing policies directly」を選択し、「AdministratorAccess」ポリシーを付与します。
   - ユーザーを作成し、表示された**Access Key ID**と**Secret Access Key**を必ずコピーします。
   - コマンドプロンプトに戻り、リージョンやコピーしたアクセスキーを入力します。

## 2. Amplifyプロジェクトの初期化

1. 新しいプロジェクト用のディレクトリを作成します。

   ```bash
   mkdir MyAmplifyApp
   cd MyAmplifyApp
   ```

2. Amplifyプロジェクトを初期化します。

   ```bash
   amplify init
   ```

3. プロンプトに従ってプロジェクトの設定を行います。

## 3. Amazon Cognitoでユーザー認証の構成

1. 次のコマンドを実行してCognitoを追加します。

   ```bash
   amplify add auth
   ```

2. 「Default configuration」を選択し、指示に従います。

3. 次に、設定をデプロイします。

   ```bash
   amplify push
   ```

## 4. Amazon S3ストレージの構成

1. 次のコマンドを実行してS3ストレージを追加します。

   ```bash
   amplify add storage
   ```

2. 「Content (Images, audio, video)」を選択し、指示に従います。

3. 設定をデプロイします。

   ```bash
   amplify push
   ```

## 5. Androidアプリの構築

### a. Android Studioを開く
1. **Android Studioを起動**します。
2. **「New Project」を選択**します。
3. **「Empty Activity」を選択**し、「Next」をクリックします。
4. プロジェクト名を設定（例: `MyAmplifyApp`）し、パッケージ名や保存先を設定します。
5. 「Finish」をクリックします。

### b. build.gradleファイルの更新
1. プロジェクトが作成されたら、**`app/build.gradle`**ファイルを開きます。
2. `dependencies`セクションに以下を追加します。

   ```groovy
   dependencies {
       implementation 'com.amplifyframework:core:1.28.1'
       implementation 'com.amplifyframework:aws-auth-cognito:1.28.1'
       implementation 'com.amplifyframework:aws-storage-s3:1.28.1'
   }
   ```

3. 「Sync Now」をクリックして依存関係を同期します。

### c. Amplifyの設定
1. **`MainActivity.kt`を開きます**。
2. 次のコードを追加してAmplifyを初期化します。

```kotlin
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.amplifyframework.AmplifyException
import com.amplifyframework.core.Amplify
import com.amplifyframework.auth.cognito.AWSCognitoAuthPlugin
import com.amplifyframework.storage.s3.AWSS3StoragePlugin

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        try {
            Amplify.addPlugin(AWSCognitoAuthPlugin())
            Amplify.addPlugin(AWSS3StoragePlugin())
            Amplify.configure(applicationContext)
            Log.i("MyAmplifyApp", "Initialized Amplify")
        } catch (e: AmplifyException) {
            Log.e("MyAmplifyApp", "Could not initialize Amplify", e)
        }
    }
}
```

### d. ユーザー認証の実装
1. **`activity_main.xml`**ファイルを開き、サインアップ用のUIを作成します。

```xml
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/usernameEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Username" />

    <EditText
        android:id="@+id/passwordEditText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Password"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/signupButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Sign Up" />
</LinearLayout>
```

2. `MainActivity.kt`にサインアップ機能のコードを追加します。

```kotlin
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.Toast

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val usernameEditText = findViewById<EditText>(R.id.usernameEditText)
        val passwordEditText = findViewById<EditText>(R.id.passwordEditText)
        val signupButton = findViewById<Button>(R.id.signupButton)

        signupButton.setOnClickListener {
            val username = usernameEditText.text.toString()
            val password = passwordEditText.text.toString()
            signUp(username, password)
        }
    }

    private fun signUp(username: String, password: String) {
        Amplify.Auth.signUp(username, password,
            { result ->
                Log.i("AuthQuickStart", "Successfully registered user: ${result.user.username}")
                runOnUiThread {
                    Toast.makeText(this, "Successfully registered!", Toast.LENGTH_SHORT).show()
                }
            },
            { error ->
                Log.e("AuthQuickStart", "Failed to register user", error)
                runOnUiThread {
                    Toast.makeText(this, "Failed to register!", Toast.LENGTH_SHORT).show()
                }
            }
        )
    }
}
```

### e. S3へのファイルアップロード機能の実装
1. UIを更新してファイルパスを入力するための`EditText`とファイルアップロード用の`Button`を追加します。

```xml
<EditText
    android:id="@+id/filePathEditText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="File Path" />

<Button
    android:id="@+id/uploadButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Upload File" />
```

2. `MainActivity.kt`にファイルアップロード機能のコードを追加します。

```kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val usernameEditText = findViewById<EditText>(R.id.usernameEditText)
        val passwordEditText = findViewById<EditText>(R.id.passwordEditText)
        val signupButton = findViewById<Button>(R.id.signupButton)
        val filePathEditText = findViewById<EditText>(R.id.filePathEditText)
        val uploadButton = findViewById<Button>(R.id.uploadButton)

        signupButton.setOnClickListener {
            val username = usernameEditText.text.toString()
            val password = passwordEditText.text.toString()
            signUp(username, password)
        }

        uploadButton.setOnClickListener {
            val filePath = filePathEditText.text.toString()
            uploadFile(filePath)
        }
    }

    private fun uploadFile(filePath: String) {
        val file = File(filePath)

        Amplify.Storage.uploadFile(
            file.name,
            file,
            { result -> Log.i("MyAmplifyApp", "Uploaded: ${result.key}") },
            { error -> Log.e("MyAmplifyApp", "Upload failed", error) }
        )
    }
}
```

## 6. アプリのビルドと実行

1. コードの追加が完了したら、Android Studioの「Run」ボタンをクリックしてアプリをビルドして実行します。
2. サインアップ機能を試してみてください。成功すると、ユーザーが登録されます。
3. 次に、指定したファイルをアップロードするために、ファイルパスを入力して「Upload File」ボタンをクリックします。
![image (24).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3998881/b9fc0047-f873-41a7-98de-c00c0bc12297.png)


## 7. 注意事項

- **ファイルパスの指定**: アップロードするファイルのパスを正しく指定してください（例えば `/storage/emulated/0/Download/example.txt` など）。
- **ストレージのパーミッション**: 必要に応じて、AndroidManifest.xmlファイルに権限を追加します。

```xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
```


---