Android Things 上で Xamarin.Android を動かして F# を使う | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/8451
ここから暫く経ってしまいましたが、Android Things + Xamarin.Android の組み合わせでLチカ(GPIO制御)まで出来たので、サンプルを流しておきます。
サンプルコード
android-things-samples/GpioAndroid at master ・ moonmile/android-things-samples
https://github.com/moonmile/android-things-samples/tree/master/GpioAndroid
バインディングプロジェクトを作る
プロジェクトは本体の「GpioAndroid」とバインディングプロジェクトの「GpioBinding」に分かれています。バインディングプロジェクトは、JarをラップするC#コードを自動生成してくれるプロジェクトですね。OpenCV for Android を Xamarin で使うときにも使います。
「Binding Library(Android)」でプロジェクトを作成すると、Jars フォルダなどが作成されます。
この Jars フォルダにバインドしたい Jar ファイルを入れます。ここでは、Android Things のバインドファイルの「androidthings-0.1-devpreview.jar」を入れておきます。このファイルは、Android Studio で Android Things プロジェクトを作るときにダウンロードしてきたものを使うのですが、サンプルコードにも入っているのでそのまま使ってください。
バインドするクラスやメソッドを調節するために、Metadata.xml ファイルに記述します。このあたりは、
jonpryor/SimpleAndroidThingsBinding
https://github.com/jonpryor/SimpleAndroidThingsBinding
を参考にしています。
1 2 3 4 5 | < metadata > < remove-node path = "/api/package[@name='com.google.android.things.pio']/class[@name='GpioDriver']/method[@name='close' and count(parameter)=0]" /> </ metadata > |
どうやら、Close メソッドがダブっているらしくそのままではビルドエラーになるんですよね。なので、このメソッドを無視するようにします。
本体のプロジェクトを作る
普通に Single-View App プロジェクトを作って、先の「GpioBinding」プロジェクトを参照設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | using Com.Google.Android.Things.Pio; using System.Threading.Tasks; public class MainActivity : Activity { TextView text1; Gpio mLedGpio; protected override void OnCreate(Bundle bundle) { base .OnCreate(bundle); // Set our view from the "main" layout resource SetContentView(Resource.Layout.Main); // Get our button from the layout resource, // and attach an event to it Button button = FindViewById<Button>(Resource.Id.MyButton); button.Click += Button_Click; text1 = FindViewById<TextView>(Resource.Id.textView1); PeripheralManagerService service = new PeripheralManagerService(); try { var pinName = "BCM4" ; // RPi3 // String pinName = BoardDefaults.getGPIOForLED(); mLedGpio = service.OpenGpio(pinName); mLedGpio.SetDirection(Gpio.DirectionOutInitiallyLow); } catch { } var task = new Task( async () => { while ( true ) { await Task.Delay(1000); mLedGpio.Value = !mLedGpio.Value; System.Diagnostics.Debug.WriteLine( "led: {0}" , mLedGpio.Value); RunOnUiThread(() => { if (mLedGpio.Value) { text1.SetBackgroundColor(Android.Graphics.Color.LightPink); } else { text1.SetBackgroundColor(Android.Graphics.Color.White); } }); } }); task.Start(); } private void Button_Click( object sender, EventArgs e) { mLedGpio.Value = !mLedGpio.Value; } } |
書き方は、Windows IoT Core と似ていますね。
- PeripheralManagerService で IoT のサービスを作成する。
- service.OpenGpio で指定ピンをオープンする。”BCM4″ は 4ピンのことです。ここの名前は https://developer.android.com/things/hardware/raspberrypi-io.html に定義されています。
- GPIO の値は Value プロパティで設定します。
基本は、
Interact with Peripherals | Android Things
https://developer.android.com/things/training/first-device/peripherals.html
と動きを合わせちて、ループは.NETらしくTaskを使っています。画面に表示するときは、RunOnUiThreadを使うことを忘れずに。
バインドする androidthings-0.1-devpreview.jar ファイルですが、これはスタブファイルなので中身は空っぽです。実行時には、com.google.android.things が使われるように、Properties/AndroidManifest.xml に uses-library を追加しておきます。これをしないと実行時に PeripheralManagerService が生成できなくてエラーになりあます(かなりハマった)。
1 2 3 4 5 6 7 | <? xml version = "1.0" encoding = "utf-8" ?> < manifest xmlns:android = "http://schemas.android.com/apk/res/android" package = "GpioAndroid.GpioAndroid" android:versionCode = "1" android:versionName = "1.0" android:installLocation = "auto" > < uses-sdk android:minSdkVersion = "24" /> < application android:label = "GpioAndroid" android:icon = "@drawable/Icon" > < uses-library android:name = "com.google.android.things" /> </ application > </ manifest > |
実行してみる
adb connect android.local で RPi 上の Android に接続して(WiFi経由で接続できます)、Visual Studio から実行すると次のように Lチカができます。
LED がチカチカとするのと同期して、画面のラベルの色が赤と白が交互に点滅します。