2017年2月15日水曜日

Delphi でAndriod Thingsを使用してみる。

みなさん
おひさしぶりです。

やましょうです。

先日、日本Androidの会の勉強会に参加しまして、
Android Thingsと組込み用 のアンドロイドのプレビューが発表されている事を知りました。
どうもラップするだけで、ザマリンでも動く様ですので、Delphiからも簡単にアクセスできる筈
と思やってみました。


 1.System イメージの入手先です。
https://developer.android.com/things/preview/download.html

で入手できます。(私はラズパイ3で挑戦です。)

2.イメージの書込みツール入手

https://sourceforge.net/projects/win32diskimager/

3.イメージツールでSDCard 8Gにイメージを書込みます。

その後ラズパイに挿入、Lanケーブルを挿し、hdmi接続

4.ラズパイ電源起動


するとipアドレスが下の方に出てきますので、それをメモりましょう


5.adb コマンドでラズパイと接続します。
私の場合Android Studioも入っているので

C:\Users\me\AppData\Local\Android\sdk\platform-tools>adb connect ip Addresss
connected to  ip Address : 5555って返ってきます。


6.SDKを、Andorido Studioと同じフォルダーにする。

7.Android Things用のブリッジファイルを作る(サンプルファイルをダウンロード)
 Java2Op等で作成。なのですが、面倒なのでファイルをダウンロードしてください。
 

8.サンプルプログラム
 unit Main;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls
  ,Android.Things
  ,Androidapi.JNI.JavaTypes
  ,Androidapi.JNIBridge
  ,Androidapi.JNI.GraphicsContentViewText
  ,Androidapi.Helpers
  ,Androidapi.JNI.App
  ,Androidapi.JNI.Embarcadero;

type
  TForm37 = class(TForm)
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private 宣言 }
     FPortService    :   JPeripheralManagerService;
     FWDGpio : JGPIO;
     RVSGpio : JGPIO;
  public
    { public 宣言 }
  end;

var
  Form37: TForm37;


implementation

{$R *.fmx}


procedure TForm37.FormCreate(Sender: TObject);
begin
    FPortService := TJPeripheralManagerService.Create();
    FwdGpio := FPortService.openGpio(StringToJString('BCM6'));
    RvsGpio := FPortService.openGpio(StringToJString('BCM5'));
    FwdGpio.setDirection( TJGpio.JavaClass.DIRECTION_OUT_INITIALLY_LOW);
    RvsGpio.setDirection( TJGpio.JavaClass.DIRECTION_OUT_INITIALLY_LOW);
end;

procedure TForm37.Timer1Timer(Sender: TObject);
begin
     if  Timer1.Tag = 0 then
     begin
        Timer1.Tag := 1;
        FwdGpio.setValue(FALSE);
        RvsGpio.setValue(TRUE);
     end
     else
     begin
         Timer1.Tag := 0;
         FwdGpio.setValue(TRUE);
         RvsGpio.setValue(FALSE);
     end;
  end;
end.


9.AndroidManifestファイルの編集
         <uses-library android:name="com.google.android.things"/>
を追加したりいろいろする


10.コンパイル実行
(機種選択はiot_rpi3を選択してください。)

 実行すると

こんな感じで交互にLチカとなります。



ソースはここ、SourceFile 


Nゲージを動かす。
 



以上
やましょうでした。

8 件のコメント:

  1. このコメントは投稿者によって削除されました。

    返信削除
  2. sourceをダウンロードして実行しました。コンパイル・リンクは問題ありませんが実行時にエラーを吐き停止してしまいます。バージョン違いのために発生するのでしょうか?
    エラーは FPortService := TJPeripheralManagerService.Create(); 
    で発生します。

    プロジェクト Project1.apkは例外クラスAborted(6)を送出しました。
     PC側 Android SDK 25.2.5 32bit
      Delphi 10.3 Rio Community Edition
    RaspberryPi側
      RaspberryPi 3
     AndroidThings: Google iot_rpi3 1.0.7

    行き詰っているのでアドバイスいただけると嬉しいです。

    返信削除
    返信

    1. アンドロイドの対応バージョンが異なるので、
      java2opでラッパーを作り直してください。

      削除
  3. アンドロイドの対応バージョンが異なるので、
    java2opでラッパーを作り直してください。

    返信削除
  4. 昨年5月にAndroid Things 1.0がリリースされた際に
    PeripheralManagerServiceが廃止になり
    PeripheralManagerService.Create(); から
    PeripheralManager.getInstance(); になりました。

    これが原因でPreview版と互換性がなくなったようです。
    大変厚かましいお願いがあるのですが java2op でPascal変換する
    元のjava ソースコードを公開していただけませんでしょうか?
    (もしくは AndroidThings Ver1.0に対応した Pascalコードを公開して
    いただければ本当にうれしいです。)
    「Java2opのラッパー作り直してください」とのコメントいただいてから
    Android Studioをインストールした初心者なもので
    サンプルコードでLED点滅させるだけでも1週間もかかり苦労してます。
    ベースにするJavaソースの作り方がわかりません。
    宜しくお願いします。

    返信削除
    返信
    1. 間違えているかもしれませんが、たしか、
      javaのソースはラズパイ内のsdカードから取得したと思います。
      なのでsdカード内を検索してみてください

      削除
  5. コメントありがとうございます。
    jar fileはgoogleで見つかりました。
    コンパイルエラーを無くす所までできたのですが、まだ動きません。

    1.AndroidThings Ver1.0 jar file
    https://maven.google.com/com/google/android/things/androidthings/1.0/androidthings-1.0.jar

    2.java2op

    C:\java2op>java2op -jar androidthings-1.0.jar
    Embarcadero Java2OP バージョン 12.16581 ($Rev: 93119 $)
    Copyright(c) 2016-2017 Embarcadero Technologies, Inc.
    Parsing xml: C:\java2op\bootclasses.xml
    Parsing jar: androidthings-1.0.jar

    JavaInterfaces.pas issues:
    android.location.GnssClock: not found
    android.location.GnssMeasurement: not found
    android.location.GnssMeasurementsEvent: not found
    android.location.GnssStatus: not found
    android.os.LocaleList: not found
    Gnssが見つからないが使わないので無視。

    3. ソースコード
    unit Unit1;
    interface
    uses
    System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
    FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
    FMX.Controls.Presentation, FMX.StdCtrls

    ,JavaInterfaces // Java Bridge file
    ,Androidapi.JNI.JavaTypes
    ,Androidapi.JNIBridge
    ,Androidapi.JNI.GraphicsContentViewText
    ,Androidapi.Helpers
    ,Androidapi.JNI.App
    ,Androidapi.JNI.Embarcadero;
    type
    TForm1 = class(TForm)
    Timer1: TTimer;
    Label1: TLabel;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    private
    { private 宣言 }
    Manager : JPeripheralManagerClass;
    FWDGpio : JGpioClass;
    RVSGpio : JGpioClass;
    count : Integer;
    public
    { public 宣言 }
    end;

    var
    Form1: TForm1;

    implementation
    {$R *.fmx}
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    // https://qiita.com/sasakisan/items/93d4c7421ddc460cde34

    Manager:=JPeripheralManagerClass(TJPeripheralManager.Create);
    Manager.getInstance;

    FWDGpio:=JGpioClass(Manager.openGpio(StringToJstring('BCM6')));
    RVSGpio:=JGpioClass(Manager.openGpio(StringToJstring('BCM5')));
    FWDGpio.setDirection(TJGpio.JavaClass.DIRECTION_OUT_INITIALLY_LOW);
    RVSGpio.setDirection(TJGpio.JavaClass.DIRECTION_OUT_INITIALLY_LOW);
    end;

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    count:=count+1;
    Label1.Text:=IntToStr(count);
    if Timer1.Tag = 0 then
    begin
    Timer1.Tag := 1;
    FwdGpio.setValue(FALSE);
    RvsGpio.setValue(TRUE);
    end
    else
    begin
    Timer1.Tag := 0;
    FwdGpio.setValue(TRUE);
    RvsGpio.setValue(FALSE);
    end;
    end;
    end.

    4.実行結果
    コンパイルエラーは無くなったのですが、getInstance の実行で
    「Project1.apkは例外クラス Segmentation fault(11)を送出しました。」
    のエラーを出します。定義の内容が間違っているのでしょうか?

    返信削除
  6. ちょっと仕事が忙しくこちらで検証することはできません。
    >Manager:=JPeripheralManagerClass(TJPeripheralManager.Create);
    >Manager.getInstance;
    の使い方はまちがっていると思います。
    がんばってください。

    返信削除