はじめに
こんにちは、メロンパン大好きリコーの@meronpanです
THETA Vのプラグイン開発のハローワールド的なことをSDKを使って紹介したいと思います。
SDKをインストールする手順はこちらです。
最終的にピカピカ光るTHETAを作ります。
THETAプラグインをご存じない人はこちらの記事をご覧ください。
興味を持たれた方はtwitterのフォローと
THETAプラグイン開発コミュニティ(slack)への参加もよろしくおねがいします。
プラグインとは言いつつも、感覚的にはAndroidアプリを開発するイメージです。
ただし、通常のAndroidスマホと比べて以下のような点が異なり、若干の工夫が必要です。
- 360度の全天球カメラである(2つのカメラが同時に動く)
- 画面が無い
- いくつかのボタンとランプがある
- 4chのマイクがついている
これらのことから、主にCameraとAudio部分のAPIが追加変更となっています。
SDKにはpluginlibraryが含まれています。こちらは基本的に変更せずそのまま利用して、それ以外の部分を変更していきます。
目次
-
THETA Vのプラグインについて以下を説明したいと思います。
- THETAのボタンの基本的な使い方
- ランプの基本的な使い方
- 無線ランプの色が変化するプラグインの作成
- meronpanのつぶやき
ボタンの基本的な使い方
ここでは、ボタンの基礎学習と使い方の確認をします。
ボタンの基礎学習
ボタンを利用する上に覚えておきたいことが2つあります。
- ボタンの種類
- ボタン操作の種類
利用する際は、ご確認ください。
ボタンの種類
以下のようなボタンの種類があり、対応するキーコード定数を確認しましょう。
no | ボタン | キーコード定数 |
---|---|---|
4 | シャッターボタン | KeyReceiver.KEYCODE_CAMERA |
12 | 無線ボタン | KeyReceiver.KEYCODE_WLAN_ON_OFF |
13 | モードボタン | KeyReceiver.KEYCODE_MEDIA_RECORD |
ボタン操作の種類
ボタン操作に対し、以下のようなコールバック関数が用意されています。
ボタン操作 | コールバック関数 |
---|---|
ボタンを押す | onKeyDown |
ボタンから離す | onKeyUp |
モードボタンを長押しする | onKeyLongPress |
ボタンの使い方
基本的には、ボタンの基礎学習で登場したボタンとボタン操作の種類を掛け合わせて利用するイメージです。
では、SDKを用いて使い方を確認しましょう。
SDKを実行すると最初に呼ばれるのがMainActivity
ですが、以下ボタンの説明に絞って部分的に紹介します。
メロンパンでも召し上がりながら、ご覧ください
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
onCreate
はMainActivity
が実行されると最初の一回だけ呼び出されます。
@Override
public void onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyReceiver.KEYCODE_CAMERA) {
/*
* To take a static picture, use the takePicture method.
* You can receive a fileUrl of the static picture in the callback.
*/
new TakePictureTask(mTakePictureTaskCallback).execute();
}
}
onKeyDown
はボタンが押された時に実行されます。
中では押したボタンがKEYCODE_CAMERA
であればと場合分けをしており、new TakePictureTask
はシャッターボタンを押した時に実行されます。
@Override
public void onKeyUp(int keyCode, KeyEvent event) {
/**
* You can control the LED of the camera.
* It is possible to change the way of lighting, the cycle of blinking, the color of light emission.
* Light emitting color can be changed only LED3.
*/
notificationLedBlink(LedTarget.LED3, LedColor.BLUE, 1000);
}
@Override
public void onKeyLongPress(int keyCode, KeyEvent event) {
notificationError("");
}
同様にonKeyUp
はボタンを離した時に実行、 onKeyLongPress
はボタンを長押しした時に実行されます。
onKeyDown
の時のように場合分けしていないのでどのボタンを押しても実行されます。
ランプの基本的な使い方
ここでは、ランプの使い方を確認します。
結論から言うと以下3点を覚えてください。
- オン、オフ、点滅の3種類の制御ができる。
- 下部表のLED3〜8のランプを制御できる。
- 下部表のLED3のランプは色を変更できる。
no | 各部名称 | LED No |
---|---|---|
6 | 無線ランプ | LED3 |
7 | 撮影モードランプ | (カメラ)LED4, (動画)LED5, (Live)LED6 |
8 | 動画記録ランプ | LED7 |
9 | メモリー警告ランプ | LED8 |
SDKを使って使い方を確認しましょう。
SDKはこちらより
pluginlibrary
ではランプの制御について以下の関数が用意されています。
色を指定してLED3ランプをオンにする。
public void notificationLed3Show(@NonNull LedColor ledColor)
LED3〜8ランプを選択してランプをオンにする。
public void notificationLedShow(@NonNull LedTarget ledTarget)
ランプを点滅させる。
public void notificationLedBlink(@NonNull LedTarget ledTarget, LedColor ledColor, int period)
ランプをオフにする。
public void notificationLedHide(@NonNull LedTarget ledTarget)
-
LedTarget
enumで、LED3, LED4, ..., LED8のいずれかを指定します。
-
LedColor
enumで、RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW, WHITEのいずれかを指定します。
デフォルトは BLUEです。 -
period
点滅制御を利用した時、1サイクルの時間(ms)を250-2000の範囲で指定します。
250以下の値は250にセットされ、2000以上の値は2000にセットされます。
無線ランプの色が変化するプラグインの作成
以上学習してきたことを活かし、無線ランプの色がランダムに変化し、シャッターボタンで停止するプラグインを作りました。
記事の冒頭で紹介した動画です。
以下の2つについて変更を加えています。
MainActivity
AndroidManifest.xml
MainActivityの変更
MainActivity
を以下のように変更しました。
package com.theta360.pluginapplication;
import android.os.Bundle;
import android.view.KeyEvent;
import com.theta360.pluginapplication.task.TakePictureTask;
import com.theta360.pluginapplication.task.TakePictureTask.Callback;
import com.theta360.pluginlibrary.activity.PluginActivity;
import com.theta360.pluginlibrary.callback.KeyCallback;
import com.theta360.pluginlibrary.receiver.KeyReceiver;
import com.theta360.pluginlibrary.values.LedColor;
import com.theta360.pluginlibrary.values.LedTarget;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends PluginActivity {
//スケジュール時間間隔を定義
private static final int TIMER_INTERVAL_PERIOD = 250;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//一定時間間隔でランプの色を更新するために、Timerをセット
Timer timer = new Timer();
Random ledColorRand = new Random();
Random ledTargetRand = new Random();
Random ledHideRand = new Random();
//250msごとにrunが実行されるように設定
timer.schedule(new TimerTask() {
@Override
public void run() {
//ランプの色をランダムで選択
int ledColorNum = ledColorRand.nextInt(LedColor.values().length);
//点灯させるランプをランダムで選択
int ledTargetNum = ledTargetRand.nextInt(LedTarget.values().length);
//消灯させるランプをランダムで選択
int ledHideNum = ledHideRand.nextInt(LedTarget.values().length);
//ランダムで選んだ色で、LED3ランプを点灯させる
notificationLed3Show(LedColor.values()[ledColorNum]);
//ランダムで選んだランプを点灯させる
notificationLedShow(LedTarget.values()[ledTargetNum]);
//ランダムで選んだランプを消灯させる
notificationLedHide(LedTarget.values()[ledHideNum]);
}
}, 0, TIMER_INTERVAL_PERIOD);
// Set a callback when a button operation event is acquired.
setKeyCallback(new KeyCallback() {
@Override
public void onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyReceiver.KEYCODE_CAMERA) {
//Timerを終了させることで、一定間隔でランダムに色を点滅させる処理を終了
timer.cancel();
//ランプを消灯させる
notificationLedHide(LedTarget.LED3);
notificationLedHide(LedTarget.LED4);
notificationLedHide(LedTarget.LED5);
notificationLedHide(LedTarget.LED6);
notificationLedHide(LedTarget.LED7);
notificationLedHide(LedTarget.LED8);
}
}
@Override
public void onKeyUp(int keyCode, KeyEvent event) {
}
@Override
public void onKeyLongPress(int keyCode, KeyEvent event) {
//Timerを終了させることで、一定間隔でランダムに色を点滅させる処理を終了
timer.cancel();
//ランプを消灯させる
notificationLedHide(LedTarget.LED3);
notificationLedHide(LedTarget.LED4);
notificationLedHide(LedTarget.LED5);
notificationLedHide(LedTarget.LED6);
notificationLedHide(LedTarget.LED7);
notificationLedHide(LedTarget.LED8);
//正常にプラグインが終了した時の通知
notificationSuccess();
}
});
}
}
細かいところを見ていくと、、、
//250msごとにrunが実行されるように設定
timer.schedule(new TimerTask() {
@Override
public void run() {
//ランプの色をランダムで選択
int ledColorNum = ledColorRand.nextInt(LedColor.values().length);
//点灯させるランプをランダムで選択
int ledTargetNum = ledTargetRand.nextInt(LedTarget.values().length);
//消灯させるランプをランダムで選択
int ledHideNum = ledHideRand.nextInt(LedTarget.values().length);
//ランダムで選んだ色で、LED3ランプを点灯させる
notificationLed3Show(LedColor.values()[ledColorNum]);
//ランダムで選んだランプを点灯させる
notificationLedShow(LedTarget.values()[ledTargetNum]);
//ランダムで選んだランプを消灯させる
notificationLedHide(LedTarget.values()[ledHideNum]);
}
}, 0, TIMER_INTERVAL_PERIOD);
onCreate
内に記載したため、timer.schedule
は実行後1度だけ呼び出されます。
しかし、中身のrun
は定期的に呼ばれるようになります。
timer.schedule
でrun
が250ms毎に実行されるようにしました。
@Override
public void onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyReceiver.KEYCODE_CAMERA) {
//Timerを終了させることで、一定間隔でランダムに色を点滅させる処理を終了
timer.cancel();
//ランプを消灯させる
notificationLedHide(LedTarget.LED3);
notificationLedHide(LedTarget.LED4);
notificationLedHide(LedTarget.LED5);
notificationLedHide(LedTarget.LED6);
notificationLedHide(LedTarget.LED7);
notificationLedHide(LedTarget.LED8);
}
}
もともとはonKeyDown
の中でカメラ撮影するコードが書かれていましたが、ランプを消灯する処理に書き換えました。
timer.cancel
で定期的に実行されていたrun
が停止します。
これにより、ランプの更新が止まります。
最後にnotificationLedHide
よりランプをオフ!
@Override
public void onKeyLongPress(int keyCode, KeyEvent event) {
//Timerを終了させることで、一定間隔でランダムに色を点滅させる処理を終了
timer.cancel();
//ランプを消灯させる
notificationLedHide(LedTarget.LED3);
notificationLedHide(LedTarget.LED4);
notificationLedHide(LedTarget.LED5);
notificationLedHide(LedTarget.LED6);
notificationLedHide(LedTarget.LED7);
notificationLedHide(LedTarget.LED8);
//正常にプラグインが終了した時の通知
notificationSuccess();
}
onKeyLongPress
はモードボタンを長押しした時に呼ばれます。
onKeyLongPress
内ではプラグインを終了する処理が実行されます。
timer.cancel
とnotificationLedHide
はonKeyDown
と同じ目的の処理です。
最後に正常にプラグインが終了したことを知らせるためにnotificationSuccess
を実行します。
AndroidManifest.xmlの変更
画面を持たないTHETAにおいて以下の工夫をしました。
<activity android:name=".MainActivity"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
画面を固定させるためのandroid:screenOrientation="portrait"
の記載を加えました。
このコードがないと、THETAを傾ける度に画面が回転したと認識されonCreate
が実行されてしまいます。
Androidのライフサイクル上、画面が回転するとアプリが初期化されるためです。
meronpanのつぶやき
撮影ができず、ランプの点滅を楽しむカメラ、、、いかがでしょうか。
紹介したコードを使って、ボタンの種類、ボタンアクションの種類を変更して、オリジナルのLED点滅プラグインを作るだけでも結構面白いと思います。
これであなたもTHETAプラグインにメロメロン
THETAプラグイン開発に興味を持たれた方はぜひパートナープログラムにご登録ください!
なお、登録時に申請したシリアルナンバーのTHETAについてはメーカーサポート対象外になりますので、ご注意ください。