ここで使える Android の部品です。パッケージ宣言と import は要りません(省略できます)。
DJI Mobile SDK V5(同じ形の API + 飛行モデル)
本物の SDK は動きません。MSDK V5(com.dji:dji-sdk-v5-aircraft:5.15.0)は 6664 個のコンパイル済みクラスと
242MB の ARM ネイティブ・ライブラリでできていて、実機と USB / Wi-Fi でつながることが前提です。ソースを解釈するこの処理系では実行できません。
そこで API の形だけを実物の .class から取り出して合わせ、中身を DJI 自身のシミュレータに相当する飛行モデル
(DJI Mini 3 の実諸元:最大 16 m/s・上昇 5 m/s・高度制限 120 m・飛行 38 分)に置きかえてあります。
サンプル「DJI Mini 3」がその使用例です。
| SDKManager | getInstance().init(Context, SDKManagerCallback) / registerApp / isRegistered / getSDKVersion。コールバックは onInitProcess / onRegisterSuccess / onProductConnect / onProductDisconnect |
| SimulatorManager | enableSimulator(InitializationSettings.createInstance(LocationCoordinate2D, 衛星数), CompletionCallback) / disableSimulator / isSimulatorEnabled |
| KeyManager | getValue(key) / getValue(key, cb) / setValue / listen(key, holder, KeyListener) / cancelListen / performAction / isKeySupported |
| KeyTools | createKey(keyInfo)。キーには create() get() set() action(成功, 失敗) listen(holder, cb) も生えています(DJI 公式サンプルと同じ書き方) |
| FlightControllerKey | KeyStartTakeoff / KeyStartAutoLanding / KeyStartGoHome / KeyStopGoHome / KeyAircraftLocation3D / KeyAircraftAttitude / KeyAircraftVelocity / KeyAltitude / KeyIsFlying / KeyIsMotorOn / KeyGPSSatelliteCount / KeyFlightMode / KeyHomeLocation / KeyDistanceToHome / KeyWindSpeed |
| BatteryKey / ProductKey | KeyChargeRemainingInPercent / KeyVoltage / KeyBatteryTemperature、KeyProductType / KeyConnection / KeyFirmwareVersion |
| CameraKey / GimbalKey | KeyStartShootPhoto / KeyStartRecord / KeyStopRecord / KeyPhotoCount / KeyIsRecording、KeyRotateByAngle / KeyGimbalAttitude |
| VirtualStickManager | enableVirtualStick(cb) / disableVirtualStick / setVirtualStickAdvancedModeEnabled / sendVirtualStickAdvancedParam(VirtualStickFlightControlParam) / getLeftStick() / getRightStick() / setSpeedLevel |
| IStick | setVerticalPosition(int) / setHorizontalPosition(int)(-660〜660) |
| 値 | LocationCoordinate3D / LocationCoordinate2D / Attitude / Velocity3D / IDJIError / EmptyMsg / ProductType.DJI_MINI_3 |
| SimDrone(この場だけ) | 本物には無い補助。getDistance / getSpeed / getVerticalSpeed / getTrailCount / getTrailLat(i) / getTrailLon(i) / getHomeLatitude / setWind(速さ, 向き) |
実機で飛ばすには本物の MSDK V5・DJI の App Key・Android 実機・RC-N1 が要ります
(Mini 3 は MSDK V5 の対応機体 ProductType.DJI_MINI_3 です)。ここで書いたコードの
キーや呼び出しの形はそのままですが、そのまま実機で飛ぶ保証はありません。
Kotlin で書く
タブごとに言語を選べます(上の Java / Kotlin)。Kotlin も同じ実行系の上で動き、
Android の部品はまったく同じものが使えます。new は要りません(Paint() と書きます)。
| クラス | class GameView(c: Context) : View(c)、init { }、companion object { const val N = 3 } |
| 関数 | fun f(a: Int, b: Int = 2): Int { }、式本体 fun g() = a + b、既定引数 |
| 変数 | val / var、型は省略可(val n = 3) |
| 文字列 | テンプレート "得点 $score"・"${'${a + b}'}" |
| ラムダ | button.setOnClickListener { ... }、暗黙の it、末尾ラムダ |
| 無名オブジェクト | object : Runnable { override fun run() { } } |
| null 安全 | var v: View? = null、v?.invalidate()、a ?: 0、v!! |
| 分岐 | when (x) { 1, 2 -> ...; is String -> ...; else -> ... }、式としての if / when |
| くり返し | for (i in 0 until n)、1..n、n downTo 1、for (v in list) |
| 型と変換 | Int Float Double Boolean Char String、x as Activity、x is View、n.toInt() s.toInt() |
| 入れもの | IntArray(n)、intArrayOf(...)、arrayOf(...)、mutableListOf(...)、a.size、list[i] |
| プロパティ | tv.text = "..." は setText、e.action は getAction() を呼びます |
未対応: コルーチン、拡張関数の受け手(this)、委譲(by)、シールドクラス、
分解宣言、局所関数、演算子の多重定義、型検査。
Activity(アプリの入口)
| onCreate(Bundle) | 起動時に呼ばれる。ここで画面を組み立てる |
| onResume() / onPause() / onDestroy() | 起動・停止のときに呼ばれる |
| onBackPressed() | ◁ を押したとき(未定義ならホームに戻る) |
| setContentView(View) | 画面に置く |
| getSharedPreferences(String, int) | 得点などの保存(ブラウザに残る) |
| finish() | アプリを終わる |
View・部品
| TextView | setText / setTextSize / setTextColor / setGravity / setTypeface |
| Button | TextView と同じ+ setOnClickListener |
| EditText | getText() / setText / setHint |
| CheckBox | isChecked() / setChecked |
| LinearLayout | setOrientation(VERTICAL / HORIZONTAL) / addView / setGravity |
| FrameLayout, ScrollView | 重ねる/縦にスクロールする入れ物 |
| LinearLayout.LayoutParams | new LayoutParams(幅, 高さ, 重み)、MATCH_PARENT(-1) / WRAP_CONTENT(-2)、setMargins |
| View 共通 | setBackgroundColor / setPadding / setVisibility / setEnabled / invalidate / getWidth / getHeight / setId / post / postDelayed |
自分で描く View(ゲーム向き)
class GameView extends View を作り、onDraw(Canvas c) を書くと、その View は canvas になります。
onTouchEvent(MotionEvent e) を書けば指の動きが取れ、onSizeChanged(int w,int h,int ow,int oh) で大きさが決まった時に呼ばれます。
invalidate() で描き直します。
| Canvas | drawColor / drawRect / drawRoundRect / drawCircle / drawOval / drawArc / drawLine / drawText / save / restore / translate / rotate / scale / clipRect / getWidth / getHeight |
| Paint | setColor / setStyle(Paint.Style.FILL, STROKE) / setStrokeWidth / setTextSize / setTextAlign(Paint.Align.CENTER) / measureText |
| Color | WHITE, BLACK, RED, … / rgb(r,g,b) / argb / parseColor("#3ddc84") |
| MotionEvent | getAction() と ACTION_DOWN / ACTION_MOVE / ACTION_UP、getX() / getY() |
| Gravity | CENTER / CENTER_HORIZONTAL / LEFT / RIGHT / TOP / BOTTOM |
時間・入出力
| Handler | post(Runnable) / postDelayed(Runnable, ミリ秒) / removeCallbacks(Runnable) |
| Toast | Toast.makeText(this, "文字", Toast.LENGTH_SHORT).show() |
| Log | Log.d/i/w/e("タグ", "文字") → 下の Logcat に出ます |
| SharedPreferences | getInt/getString/getBoolean、edit().putInt(...).apply() |
java.lang / java.util
| Math | abs max min sqrt pow floor ceil round random sin cos tan atan2 hypot PI … |
| Random | nextInt(n) / nextDouble() / nextBoolean() |
| String | length charAt substring indexOf equals split replace contains trim toUpperCase …、String.format("%d 点", n) |
| Integer / Double / Boolean / Character | parseInt / parseDouble / valueOf / toString … |
| ArrayList / HashMap / Arrays | add get set size remove contains / put get containsKey keySet |
| System | currentTimeMillis() / out.println(...) / arraycopy |
使い方
- 上のタブでアプリを選び、コードを書きかえて ▶ 実行(Ctrl/⌘ + Enter)。右の端末で動きます。
- 言語は Java と Kotlin のどちらでも。左上の選択で切り替わります(アプリごとに覚えます)。
- + で新しいアプリを作れます。書いたものはこのブラウザに保存され、次に来ても残ります。
- 端末の ◁ は戻る、◯ はホーム。ホームのアイコンをタップしても起動します。
- エラーは Logcat に行番号つきで出ます。その行は左の行番号が赤くなります。
しくみ
このページは Android SDK も JVM も使っていません。すべてブラウザの中で動きます。
js/java.js— Java サブセットの字句解析・構文解析・木を辿る実行系。クラス、継承、インタフェース、 無名クラス(new View.OnClickListener(){...})、ラムダ、配列、例外、switch などに対応。js/dji.js— DJI MSDK V5 と同じ形の API と、Mini 3 の飛行モデル(20Hz)。 クラス名・引数は 5.15.0 のバイトコードをjavapで読んで合わせてあります。js/kotlin.js— Kotlin サブセットの前段。Kotlin を読んで java.js と同じ構文木に落とすので、 実行系と Android の部品はそのまま共有されます(Kotlin 用の別の処理系は作っていません)。js/android.js— Activity・View・Canvas・Paint・Handler などを DOM と <canvas> の上に実装。onDrawを書いた View は自動的に canvas になり、invalidate()で再描画されます。js/ide.js— ホーム画面、ナビゲーションバー、Logcat、色つきエディタ。
本物と違うところ(正直なところ)
- レイアウト XML と
R.idはありません。画面は Java / Kotlin のコードで組み立てます。 - スレッドはありません。
Thread.sleepは何もしません。時間の処理はHandler.postDelayedを使ってください。 - 整数と小数の区別は、宣言した型から判断しています(
int a=7, b=2;ならa/bは 3)。 割り算で小数がほしいときは(float)を付けてください。 - 総称型(
<String>など)は書けますが、型検査はしません。 - 無限ループになると 4 秒ほどで「応答がありません」として止めます。