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
を参考にしています。
<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」プロジェクトを参照設定します。
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 が生成できなくてエラーになりあます(かなりハマった)。
<?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 がチカチカとするのと同期して、画面のラベルの色が赤と白が交互に点滅します。