Android アプリから 360 度カメラ「RICOH THETA」に接続して写真を撮影する

こんにちは。ANDPAD の Android アプリを開発している 平池 です。

この記事は ANDPAD Advent Calendar 2025 の 13 日目の記事です。

この記事では、弊社が提供する Android 版の ANDPAD施工管理 (以下、施工管理アプリ) にて、360 度カメラ「RICOH THETA」と接続して写真を撮影する機能を提供しましたので、その実装過程や難しかったことなどを共有します。

この記事を通して、建築建設現場で利用する Android アプリの開発について、少しでもイメージを膨らませていただければ幸いです。

RICOH THETA とは

RICOH THETA(以下 THETA)は、ワンショットで 360 度の全天球画像や動画を撮影できる RICOH 社のカメラシリーズです。

www.ricoh360.com

360 度写真は建築建設現場での記録において非常に重宝しており、以前から THETA を利用しているお客様もいらっしゃいました。しかし ANDPAD と THETA の連携機能を提供する前は、THETA で撮影した画像をスマホに取り込んでから ANDPAD を開いて画像を送信するという手間が発生していました。

そんな現場での手間を解消するために、THETA と施工管理アプリの連携機能の開発に取り組み始めました。開発期間としては、2024 年 11 月に 「RICOH360プラットフォーム」事業との協業をプレスリリースで発表してから要件定義、デザイン検討を行い、2025 年 1 月に開発を開始。同年 4 月に THETA 連携機能のリリース、10 月に UI をよりリッチにわかりやすくした改善版をリリースしました。

andpad.co.jp

施工管理アプリを THETA に接続する

ここからは施工管理アプリと THETA を接続するために行なった実装について記載します。

Android アプリを THETA に接続するためには、RICOH 社が開発している theta-client という SDK を使います。

github.com

この記事では theta-client 1.13.1 を利用します。

また前提として、THETA との接続方式としては AP モード(アクセスポイントモード)と CL モード(クライアントモード)があります。

  • AP モード: スマホから THETA に無線 LAN 接続するモード
  • CL モード: THETA から無線ルーターに接続し、ネットワークを介してスマホと接続するモード

施工管理アプリではこの AP モードのみを対応しています(記事執筆時)。CL モードは建築建設現場で利用されないケースも多いため、AP モードの開発を優先してリリースしました。

そのため、AP モードで THETA に接続して写真を撮影するための実装手順を以下に記載します。

1. 近くの THETA を検索して接続する

THETA に接続するためには、近くにある THETA を検索する必要があります。THETA を検索する方法として、主に Wi-Fi アクセスポイントから探すか、Bluetooth 機器を探すという 2 種類の方法があります。

Wi-Fi アクセスポイントを探す方法については、Android 9 から Wi-Fi スキャンは 2 分間に 4 回までの制限が適用されており、今後制限が厳しくなる可能性があります。

developer.android.com

Wi-Fi の検索は電力コストが高く、Wi-Fi を検索する処理 WifiManager.startScan() も非推奨になっています。そのため、施工管理アプリでは Wi-Fi の検索ではなく Bluetooth 機器の検索を採用しました。

Android が提供する Bluetooth デバイス検索機能を用いて付近のデバイスを検索します。THETA の Bluetooth ID は数字 8 桁なので、条件を満たす Bluetooth デバイスだけ選択します。

developer.android.com

一方で THETA のモデル情報は Bluetooth からはわからないため、ユーザーに選択してもらう必要があります。THETA のモデルと端末のシリアルナンバーの規則性は以下のページにまとまっています。

theta-archive.ricoh360.com

8 桁の端末番号と THETA モデル情報があれば、THETA の Wi-Fi のアクセスポイントが特定できるため、Android の P2P 接続機能を利用して THETA に接続します。

developer.android.com

val specifier = WifiNetworkSpecifier.Builder()
    .setSsid("ssid") // 特定した THETA の Wi-Fi アクセスポイント名
    .setWpa2Passphrase("password") // THETA に設定されているパスワード
    .build()

val request = NetworkRequest.Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    .setNetworkSpecifier(specifier)
    .build()

ConnectivityManager.requestNetwork(request, networkCallback) // 接続成功・失敗時の処理を記載した networkCallback を渡す

2. THETA で写真を撮影して保存する

THETA と接続できたら ThetaRepository を初期化します。

THETA の撮影時の操作はこの ThetaRepository を介して行います。どのような設定ができるかは以下のドキュメントに詳しい記載があるので、こちらをご確認ください。

github.com

初期化時に渡す Config にて、言語と時刻の設定をしておくと操作がわかりやすくなります。時刻のフォーマットが YYYY:MM:DD HH:MM:SS+HH:MM となっているので、変換して渡す必要があります。

val config = ThetaRepository.Config().apply {
    language = when (Locale.getDefault().language) {
        Locale.JAPAN.language -> ThetaRepository.LanguageEnum.JA
        else -> ThetaRepository.LanguageEnum.EN_US
    }
    dateTime = DateTimeFormatter.ofPattern("yyyy:MM:dd HH:mm:ssxxx").format(ZonedDateTime.now())
}

THETA のカメラのプレビュー映像は ThetaRepository.getLivePreview() で映像データが Flow で返ってくるので、そのデータをアプリの画面に表示すればユーザーが THETA から見えている映像を確認できます。

THETA で写真を撮影した後は、登録した PhotoCapture.TakePictureCallback.onSuccess(fileUrl: String?) に THETA 内部に保存されている写真の URL が返ってくるので、その URL へアクセスして写真をダウンロードします。

撮影した写真を削除したい場合は、ThetaRepository.deleteFiles(fileUrls: List<String>) で削除したい URL を渡せば THETA 端末内から写真を削除できます。

撮影に関する実装については前述のドキュメントに必要なことがほとんど記載されているので、そちらを見ればだいたいのことができます。

難しかったこと

ドキュメントを参照すればおよそ問題なく実装できますが、それでも難しかった点がありました。

1. THETA のモデルごとの差異に対応する

THETA はモデルごとに進化を遂げており、新しい端末と古い端末で挙動が異なることがあります。

2022 年に発売された THETA X では、撮影中もプレビュー映像を表示し続けることができますが、2019 年に発売された THETA SC2 以前の端末では撮影中はプレビュー映像が途切れるため、そのままプレビューを表示しようとするとアプリがクラッシュしてしまいます。

また、端末ごとに対応している写真の解像度が大きく異なるため、対応していない解像度で撮影しないように注意が必要です。

記事執筆時点では、ストアに X と Z1 しか取り扱いが無く、それより古い端末を購入して動作確認するのが難しいです。

どの端末までサポートするのか、サポート外の THETA を接続したときにどのような表示をするのかは配慮が必要です。

2. THETA とアプリでセルフタイマーのタイミングがずれる

THETA でセルフタイマーを利用して撮影すると、PhotoCapture.TakePictureCallback.onCapturing(status: CapturingStatusEnum) にセルフタイマーのカウントダウンが始まったことが通知されるのですが、そのタイミングと実際に THETA でセルフタイマーが開始したタイミングにやや時差があり、アプリでのカウントダウンが終わる前に THETA の撮影が完了してしまうということがありました。

スマホと THETA の Wi-Fi 接続が不安定だと発生しやすいようで、SDK 側で例えばカウントダウンの開始だけでなく、残り秒数のデータも返すなどの対応があると改善できそうだなと期待しています。

まとめ

Android アプリを THETA に接続するというニッチな内容を記載しました。ただ、私たちが実装するときは資料が少なく、手探りで開発を進めなければならず時間がかかってしまったので、これから THETA を用いた開発をする方にこの記事が役立てば良いなと思います。

弊社では Android エンジニアを引き続き募集しております。興味を持っていただけましたら、ぜひ採用サイトもご覧ください。

hrmos.co