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

を参考にしています。

<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 と似ていますね。

  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 が生成できなくてエラーになりあます(かなりハマった)。

<?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 がチカチカとするのと同期して、画面のラベルの色が赤と白が交互に点滅します。

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