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ゲージを動かす。
 



以上
やましょうでした。

9 件のコメント:

  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;
    の使い方はまちがっていると思います。
    がんばってください。

    返信削除
  7. Manager : JPeripheralManagerClass;
    Manager := TJPeripheralManagerClass.Create; (???)

    返信削除