Android Things 上で Xamarin.Android を使って Lチカする

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

を参考にしています。

[code lang=”xml”]
<metadata>
<remove-node
path="/api/package[@name=’com.google.android.things.pio’]/class[@name=’GpioDriver’]/method[@name=’close’ and count(parameter)=0]"
/>
</metadata>
[/code]

どうやら、Close メソッドがダブっているらしくそのままではビルドエラーになるんですよね。なので、このメソッドを無視するようにします。

本体のプロジェクトを作る

普通に Single-View App プロジェクトを作って、先の「GpioBinding」プロジェクトを参照設定します。

[code lang=”csharp”]
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;
}
}
[/code]

書き方は、Windows IoT Core と似ていますね。

  1. PeripheralManagerService で IoT のサービスを作成する。
  2. service.OpenGpio で指定ピンをオープンする。”BCM4″ は 4ピンのことです。ここの名前は https://developer.android.com/things/hardware/raspberrypi-io.html に定義されています。
  3. 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 が生成できなくてエラーになりあます(かなりハマった)。

[code lang=”xml”]
<?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>
[/code]

実行してみる

adb connect android.local で RPi 上の Android に接続して(WiFi経由で接続できます)、Visual Studio から実行すると次のように Lチカができます。

LED がチカチカとするのと同期して、画面のラベルの色が赤と白が交互に点滅します。

カテゴリー: Android, Xamarin パーマリンク