THETA PLUG-IN STOREへのプラグイン公開手順（リリースビルド編）

## はじめに
リコーの @KA-2 です。

弊社では[RICOH THETA](https://theta360.com/ja/)という全周囲360度撮れるカメラを出しています。
<B>RICOH THETA V</B>や<b>RICOH THETA Z1</b>は、OSに<B>Android</B>を採用しています。Androidアプリを作る感覚でTHETAをカスタマイズすることもでき、そのカスタマイズ機能を「プラグイン」と呼んでいます（詳細は本記事の末尾を参照）。

今回は、[THETA PLUG-IN STORE](https://pluginstore.theta360.com/)に皆様の成果物を公開する手順を２回に渡って解説していきます。

- THETA PLUG-IN STOREへのプラグイン公開手順（リリースビルド編）　※本記事です
- [THETA PLUG-IN STOREへのプラグイン公開手順（公開手続き編）](https://qiita.com/KA-2/items/784bfc9e54137fbe4dce) ※続きの記事です

![00_TOP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265455/518bacb6-1fcb-c9a3-faa8-5ac2033a6190.png)

基本的には、Android のスマートフォンアプリを Google Playに公開する手続きと差がありません（もう少し楽なはずですが、大枠の流れは同じという意図です）。とはいえ、「Google Playにスマホアプリを公開したことなんてないよ！」という方々が多いとおもいます。
そこで、ご自身で作成したプラグインのデバッグが終わった後、「THETA PLUG-IN STORE公開するにはどんな作業が必要になるのか」について順に説明します。


## リリースビルドの概要

私自身がAndroidのアプリケーション開発に疎いという状態ではありますが、「デバッグフラグの状態の違い」といったあたりまえの事や、「リリースビルドではデバッグビルドよりもapkが圧縮される」といった気の利いたことを除くと、最も大きな違いは「署名の有無」となるでしょう。
「誰が作成したアプリケーションなのか証明できる状態」になっていないと公の場に公開できないようになっています。
その他、オープンソースを利用したアプリケーションの場合ライセンスの明示が必要になったり、バージョンの管理といったことも必要になります。

こういった一般的なことに加え、THETA固有の事項としては「どの機種で動作するTHETAプラグインなのか示されている」といったことも必要になります。

これらの必要な事項をまとめると以下のようになります。

- パッケージ名称とプラグイン名称の確認
- AndroidManifest.xmlへの対応機種設定
- バージョン文字列のルール
- versionCodeの設定
- licenses.htmlの作成
- 署名

以降では、各項目について順を追って説明します。

## 事前設定

### パッケージ名称とプラグイン名称の確認
THETA PLUG-IN STOREに公開するには、どちらも64文字以内にする必要があります。このことは、[How to Developというドキュメント](https://github.com/ricohapi/theta-api-specs/blob/main/ricoh-theta-plugin/how-to-develop.md)の「Warnings When Developing Plug-ins」の中に、以下の一文で記されています。

```
Plug-in and package names cannot exceed 64 characters and an extension must use apk
```

他にも、Androidの世界における慣例にならう必要もありますので、以下で解説します。

#### パッケージ名称

THETA PLUG-IN STOREの中でユニークになる名前でなければなりません。
そこで、Androidの世界では、
「自身の持つドメイン名称をカンマ区切りで逆順に並べたあと、プラグイン固有の文字列を並べる」
というお作法にならうようです。

例えば、公式プラグインは以下のようにしています。

```
com.theta360.プラグイン固有文字列
```
パッケージ名称はTHETA PLUG-IN STOREの固有ページのURLにも含まれます。

![01_パッケージ名称.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265455/8f501390-4db4-f677-9de3-aae911a947e8.png)


私たち有志によるコミュニティは、固有のドメイン名をもっていません。個人ではそんな方も多いでしょう。
そこで、「プラグイン作成者を示す固有文字列.プラグイン固有の文字列」としています。
早い者勝ちになりますが、このようにパッケージ名を決めるのもありです。

![02_パッケージ名称2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265455/a100e4c9-eed3-b2ba-d6c4-699dd5534777.png)

パッケージ名称は、プロジェクトのフォルダ構成やGradle, AndroidManifest.xmlの設定値にも影響を与えます。THETA PLUG-IN STORE公開を見据えた場合、最初の段階からパッケージ名称を決めて作業することをお勧めします。

サンプルプログラムとして公開している[THETA Plug-in SDK](https://github.com/ricohapi/theta-plugin-sdk)のパッケージ名称やフォルダ構成などは、リコー公式プラグインのルールにのっとっていますので各自が変更してください。


#### プラグイン名称
パッケージ名称と比べると、ユーザーが利用するプラグインを選択するための表示に使われているだけですので、重複していてもインストールできてしまいます。しかし、ユーザーが同名の別プラグインを使ってしまうようなトラブルを避けるために、ユニークな名前にするべきでしょう。


### AndroidManifest.xmlへの対応機種設定

作成したプラグインが、どのTHETAで動作するのか設定しておく必要があります。
記述の仕方は[How to Developというドキュメント](https://github.com/ricohapi/theta-api-specs/blob/main/ricoh-theta-plugin/how-to-develop.md) の「Specify Camera Model Support」に記されています。

AndroidManifest.xmlに、以下のタグとともにtrue/falseを設定するだけです。

```AndroidManifest.xml
    <uses-feature android:name="com.theta360.receptor.v" android:required="false"/>
    <uses-feature android:name="com.theta360.receptor.z1" android:required="true"/>
```
この例のように設定にした場合、公開されたapkは RICOH THETA Vにインストールできず、RICOH THETA Z1にはインストールできる状態となります。


### バージョン文字列のルール

[How to Developというドキュメント](https://github.com/ricohapi/theta-api-specs/blob/main/ricoh-theta-plugin/how-to-develop.md) の「Version Information」にルールが示されています。
読んでいただければ直ぐわかることですが、念のため簡単な日本語で換言しておくと。

```
2つのカンマで区切られた3ブロックの数字文字列であり「2桁以下の数値.2桁以下の数値.4桁以下の数値」であること。
```

となります。

設定箇所は、build.gradleの設定項目の一つversionNameです。

```build.gradle
android {
    defaultConfig {
　　　　　～省略～
        versionName "1.0.0"
　　　　　～省略～
    }
}
```



### versionCodeの設定

build.gradleの設定項目の一つversionCodeの設定を確認してください。

```build.gradle
android {
    defaultConfig {
　　　　　～省略～
        versionCode 1
　　　　　～省略～
    }
}
```

バージョン文字列はただの表示用文字列であり、THETA PLUG-IN STOREでの実質的なバージョン管理はこの数値で行われていますのでより注意が必要です。

バージョンアップの公開をする時には、以前バージョンの数値より大きな数値を設定する必要があります。初回の値は問われていませんが、1としておくとその後の融通が利くでしょう。

サンプルプログラムとして公開している[THETA Plug-in SDK](https://github.com/ricohapi/theta-plugin-sdk)のversionCodeは、サンプルプログラムのversionCodeです。
ご自身でプラグインを作成するときには、改めてversionCodeを振ることをお勧めいたします。


### licenses.htmlの作成

オープンソースを利用した場合、ライセンスの明示は公の場にアプリケーションを公開するときに必要な作法となります。
ライセンスを明示するファイルの置き場所と、オープンソースを利用しなかった場合のHTMLファイルの記述例は[How to Developというドキュメント](https://github.com/ricohapi/theta-api-specs/blob/main/ricoh-theta-plugin/how-to-develop.md) の「Open Source Licenses」に記されています。

ライセンスの明示が必要な場合、一般的なAndroidアプリを作成/公開するときと同じ方法で作成していただければOKです。

licenses.htmlを作成する作業が、おそらくリリースで最も面倒な作業になると思います。
Android Studioにはその作成をサポートするツールが用意されています。
そして、さらにそれらを補助するツール（Gradleのプラグイン）を作られた方がいらっしゃいます。

以下のGitHubリポジトリを参照してください。[How To Use](https://github.com/cookpad/LicenseToolsPlugin#how-to-use)に使い方が記されています。
[https://github.com/cookpad/LicenseToolsPlugin](https://github.com/cookpad/LicenseToolsPlugin)

日本語での解説はこちらを元にたどるとよいと思います。
[https://techlife.cookpad.com/entry/2020/01/16/090000](https://techlife.cookpad.com/entry/2020/01/16/090000)

大雑把には
 - Gradleの checkLicenses というツールで ライブラリの抽出を行う→licenses.ymlが生成される
 - licenses.yml の不確定項目（#COPYRIGHT HOLDER#など）を埋める（＝自身でライセンスの元を調べる）
 - Gradleの generateLicensePage というツールで licenses.html を生成する
という流れになります。


### 署名

Androidの公式サイトでは、以下のドキュメントで署名についてまとめられています。
https://developer.android.com/studio/publish/app-signing?hl=ja
keystoreがないとリリースビルド自体ができませんのでご注意ください。

人に知られてはならない文字列やパスワードを別ファイルとして管理（誤ってGitHub等に公開してしまうミスを避けるなど便利なことがあります）するために、いくらかの方法があるようです。それについては、以下サイト（日本語）が参考になると思います。
[https://rightcode.co.jp/blog/information-technology/android-keystore-password-secure](https://rightcode.co.jp/blog/information-technology/android-keystore-password-secure)


例えば、私たちのプラグインでは、以下のように分離しています。
[https://github.com/theta-skunkworks/theta-plugin-tilt-ui/blob/main/app/build.gradle#L36-L45](https://github.com/theta-skunkworks/theta-plugin-tilt-ui/blob/main/app/build.gradle#L36-L45)

```build.gradle
    Properties properties = new Properties()
    properties.load(rootProject.file('local.properties').newDataInputStream())
    signingConfigs {
        release {
            storeFile rootProject.file('./skunkworks.keystore')
            storePassword properties.getProperty("android.keystore.password")
            keyAlias properties.getProperty("android.keystore.alias")
            keyPassword properties.getProperty("android.keystore.private_key_password")
        }
    }
```


## リリースビルド

「事前設定」で説明した事項を整えたあと、Android Studioで以下の操作（設定）を行うと、リリースビルドできる状態となります。

![03_リリースビルド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265455/5f8f6eba-32a4-8973-9687-5bcf42525c34.png)


1. 画面左下の「Build Variants」タブをクリック
2. 「Build Variants」の入力画面が表示される
3. 「Active Build Variant」をdebugからreleaseに変更する

あとは、通常通りビルド操作をすると、リリースビルドが行われます。

ここから先は、各自が作られたプラグイン次第で起こることが変わります。エラーチェックなどが厳しくなりますので１回ですんなりビルドが通ることは珍しいでしょう。Webには、Androidのリリースビルドに関わる情報がたくさんありますので、エラーの内容に合わせて検索するなどして解決していってください。

ご参考の１つでしかありませんが、無視してよいエラーを無視させる設定はbuild.gradleの以下ブロックとなります。
私は、わりとこの設定でリリースビルドを乗り切ることがおおいです。

```build.gradle
    lintOptions {
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }
```

## まとめ

細々とやるべきことが多いのですが、一度経験してしまえば流れ作業のようなことです。
プラグイン名称やパッケージ名称のようなところは、リリース直前にやるのではなく予め決めてからプロジェクトを作成するのがよいと思います。
ちょっと面倒なライセンスの明示の仕方は、[「公式プラグインでGitHubに公開されているプロジェクト」](https://github.com/ricohapi)や、[「私たちがGitHubに公開しているプロジェクトの中でストア公開しているもの」](https://github.com/theta-skunkworks)のlicenses.htmlを参考にすると、大抵の場合解決するのではないかと思います。

次回は、出来上がったリリース用apkをTHETA PLUG-IN STOREに公開するための準備や手続きについて解説します。



## RICOH THETAプラグインパートナープログラムについて

THETAプラグインをご存じない方は[こちら](https://github.com/ricohapi/theta-api-specs/blob/main/core/products/theta-plugin.md)をご覧ください。
パートナープログラムへの登録方法は[こちら](https://qiita.com/mShiiina/items/55d98f366e650ca42251)にもまとめてあります。
Qiitaの[RICOH THETAプラグイン開発者コミュニティ TOPページ「About」](https://qiita.com/organizations/theta-plugin)に便利な記事リンク集もあります。
興味を持たれた方は[Twitter](https://twitter.com/thetaplugin)のフォローと[THETAプラグイン開発者コミュニティ(Slack)](https://join.slack.com/t/thetadeveloper/shared_invite/enQtNzcxODI2MTk2ODg0LWY5YmU2ZTIxNGYwNzlmNWZjMWMyMWFlMzY3ZmQ3NGU3ZjZiZjI0Njk4MGIxMDU5NDJiMzQ4Y2FkNDEzYmFlNGU)への参加もよろしくおねがいします｡