2017年1月13日金曜日

Android上で、Dart x Flutter の platform service で、JavaとDartを連携させてみる

Dart x Flutter の platform service 機能を利用して、JavaとDartを連携させてみました。
公式のサンプルを読むだけだと、具体的に何をしているのかが、しっくりこなかったので、実際にプロジェクトをゼロから作ってみました。

試した結果は以下におきました
公式のサンプルを参考にして、プロジェクトの作成から試してみました。

https://github.com/kyorohiro/dart.flutter.platformservice
https://github.com/kyorohiro/dart.flutter.ibeacon




コード自体はとても少なく済んでいます。
また、AtomなどのIDEからもDartのプロジェクトとして実行できるので、
拡張したとしても、ストレスなく開発を続ける事ができます。

こんな順序で作業してみた



1. まずは、IntelliJ を利用して、Flutterプロジェクトを作る

まずは、Flutterのプロジェクトを作ってみました。
https://github.com/kyorohiro/dart.flutter.ibeacon/tree/8d7bfdc166f6027999c6ca57acfb6a7edfd0bc41



2. android配下を削除して、Android Stdioでプロジェクトを作る

https://github.com/kyorohiro/dart.flutter.ibeacon/tree/5bc3631a5a644753ddcfc8daf9062201248a4d10

https://github.com/kyorohiro/dart.flutter.ibeacon/tree/5ff7facd1a2b8c4f19791a68b754e83e07770fda


3. buildSrcをサンプルから、コピーして、各種設定をする。

GradleのFlutterプラグインを利用します。公式のサンプルコードからコピーしました。
https://github.com/kyorohiro/dart.flutter.ibeacon/tree/8496c634ebb15c7ee6a8855d250627eddcb012b8


3.1 android/app/build.gradleに追加

+apply plugin: 'flutter'

+

+
+flutter {
+ source '../..'
+}


3.2 local.propertiesにパスを追加

+ flutter.sdk=/Users/kyorohiro/tools/git/flutter


4. とりあえず、Dartのコードを動作させてみる

Dartを動作させる環境ができたので、上手く動作するか確認してみした。AndroidManifesrtとActivityを少し変更します。

https://github.com/kyorohiro/dart.flutter.ibeacon/tree/4d09df74bf678d4094c3e56a4f632564f7f0e81e

4.1 Application Name を Dart用に変更する
==

<manifest package="info.kyorohiro.ibeacontest" xmlns:android="http://schemas.android.com/apk/res/android">

    <application android:allowbackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:name="org.domokit.sky.shell.SkyApplication" android:supportsrtl="true" android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"></action>
                <category android:name="android.intent.category.LAUNCHER"></category>
            </intent-filter>
        </activity>

    </application>

</manifest>
==

4.2 Dartのコードを読み込むようにする
===

package info.kyorohiro.ibeacontest;

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

import io.flutter.view.FlutterMain;
import io.flutter.view.FlutterView;

/**
 * Created by kyorohiro on 2017/01/13.
 */

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FlutterMain.ensureInitializationComplete(this,null);
        LinearLayout rootLayout = new LinearLayout(this);
        this.setContentView(rootLayout);

        FlutterView flutterView = new FlutterView(this);
        rootLayout.addView(flutterView);

        flutterView.runFromBundle(FlutterMain.findAppBundlePath(getApplicationContext()), null);
    }
}
===



5 JavaとDart 間で通信するコードを追加する

実際にJavaとDartを連携させてみました。上手く動作した。

https://github.com/kyorohiro/dart.flutter.ibeacon/blob/5995b98e12850f49344bb5f306f0e3273874a805/android/app/src/main/java/info/kyorohiro/ibeacontest/MainActivity.java

====++

package info.kyorohiro.ibeacontest;

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

import io.flutter.view.FlutterMain;
import io.flutter.view.FlutterView;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * Created by kyorohiro on 2017/01/13.
 */

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FlutterMain.ensureInitializationComplete(this,null);
        LinearLayout rootLayout = new LinearLayout(this);
        this.setContentView(rootLayout);

        FlutterView flutterView = new FlutterView(this);
        rootLayout.addView(flutterView);

        flutterView.runFromBundle(FlutterMain.findAppBundlePath(getApplicationContext()), null);

        flutterView.addOnMessageListener("callback_sync", new FlutterView.OnMessageListener(){
            @Override
            public String onMessage(FlutterView flutterView, String message) {
                return "hi sync" + message;
            }
        });

        flutterView.addOnMessageListenerAsync("callback_async", new FlutterView.OnMessageListenerAsync() {
            @Override
            public void onMessage(FlutterView flutterView, String message, FlutterView.MessageResponse messageResponse) {
                messageResponse.send("hi async" + message);
            }
        });

        flutterView.addOnMessageListenerAsync("callback_proc", new FlutterView.OnMessageListenerAsync() {
            @Override
            public void onMessage(FlutterView flutterView, String message, final FlutterView.MessageResponse messageResponse) {
                JSONObject jsonMessage = new JSONObject();
                try {
                    jsonMessage.put("vvv", 100);
                } catch(JSONException e){
                }
                //jsonMessage.put("v",1);
                flutterView.sendToFlutter("hi", jsonMessage.toString(), new FlutterView.MessageReplyCallback() {
                    @Override
                    public void onReply(String s) {
                        messageResponse.send(s);
                    }
                });
            }
        });
    }
}
====++

https://github.com/kyorohiro/dart.flutter.ibeacon/blob/5995b98e12850f49344bb5f306f0e3273874a805/lib/main.dart

====

import 'package:flutter/material.dart';
import 'package:flutter/services.dart' as fsv;
import 'dart:typed_data';
import 'dart:convert';

void main() {
  runApp(new MyApp());

}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    fsv.PlatformMessages.setJSONMessageHandler("hi",(String v) async{
      return v;
    });
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  String message = "";

   _incrementCounter() async {
     //
    ByteData buffer0 = await fsv.PlatformMessages.sendBinary("callback_sync", new ByteData.view(
      new Uint8List.fromList([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]).buffer
    ));

    //
    String buffer1 = await fsv.PlatformMessages.sendString("callback_async", JSON.encode({"test":"hello"}));

    //
    String buffer2 = await fsv.PlatformMessages.sendString("callback_proc", "hello");


    //
    message = "${buffer0.buffer.asUint8List()} :: ${buffer1} :: ${buffer2}" ;
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(config.title),
      ),
      body: new Center(
        child: new Text(
          '${message} $_counter time${ _counter == 1 ? '' : 's' }.',
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ), // This trailing comma tells the Dart formatter to use
    );
  }
}
====




Dart x Flutter の platform-services機能で AndroidアプリにDartを埋め込んでみた。

platform-servicesの機能を利用すれば、AndroidアプリにFlutter x Dart を埋め込む事ができます。また、Dart側のコードと連携もできます。
この機能を利用すれば、Flutterにはまだ実装されてない機能も
ドンドン追加していけます。

1. 公式のサンプルコードは以下にあります。
https://github.com/flutter/flutter/tree/master/examples/hello_services

2. 具体的な解説は以下
https://flutter.io/platform-services/


## サンプルを実行してみた。
1. clone サンプルコードをダウンロードhttps://github.com/flutter/flutter/tree/master/examples/hello_services

2. android/local.propertiesを追加
```
flutter.sdk=/Users/kyorohiro/tools/git/fluttersdk.dir=/Users/kyorohiro/Library/Android/sdk
sdk.dir=/Users/kyorohiro/Library/Android/sdk
```

3. Android Studioで、androidを開けば、ビルドと実行ができます

※ サンプルのDartのコードを変更して、ビルドすると、直ぐに反映されます!!

### 軽い説明
このサンプルは、起動すると、
1. FlutterMainを呼び出して、初期化します。
2. その後、GetButtonNumberと書かれたボタンと、FlutterViewをActivityに貼り付けます。
3. /data/user/0/com.example.flutter/app_sky_shell/app.flx からコードを読み込みます。
4 GetRandinNumbeボタンを押すと、JavaからDart側のコードを呼び出します。
5. Get Locationを押すと、DartからJava側のコードを呼び出します。


### 補足
AtomとかからDartのコードをいじって、そのまま起動とかできるので、
開発もストレスなくできそう。






火の型 Scratchでプログラム入門 固定レイアウト版 1日目はFIXしたと見なす

気軽に書き始めたものも、完成させるとなると結構なエネルギーを消耗します。炎の型への入り口として、書き始めた火の型を完成させる事にしました。

ただ、完璧を目指すると終わりません。 既にネタはほとんど書き終わっているので、あとは構成とかを見直すだけです。
なので、構成を見直したところは、もう終わりとして見直さない宣言をする事にしました。

これで、終わらせられるかな。

火の型の1日目はFIXしたと見なします。

1日目 君は既にプログラマー!! Scratchを導入してみよう!!










以降は、以下を参照してください。
100pageくらいあります。





火の型 Scratchでプログラム入門 固定レイアウト版 0日目はFIXしたと見なす

気軽に書き始めたものも、完成させるとなると結構なエネルギーを消耗します。炎の型への入り口として、書き始めた火の型を完成させる事にしました。

ただ、完璧を目指すると終わりません。 既にネタはほとんど書き終わっているので、あとは構成とかを見直すだけです。
なので、構成を見直したところは、もう終わりとして見直さない宣言をする事にしました。

これで、終わらせられるかな。

火の型の第0日目はFIXしたと見なします。

0日目 火の型でプログラマーになろう!!

https://firebook.firefirestyle.net/

今..あなたは..世界一のプログラマーになりました。
ソフトウェアが動作する環境なら
あなたは、 なんでもできます。
思いのままです..
もうすぐ、あらゆる物で、ソフトウェアが動作するようになります。
つまり、あなたは あらゆる事ができます。
もう、何でもありです。
何を作ってみたいですか?
火の型の0巻では、7日間にわたって、Scratchを利用して、ミニゲームを作成
していきます。 ひとつの記事が5〜20分くらいのチュートリアルです。 
火の型を読むと、いろいろなゲームを作れるようになります。






以降は、以下を参照してください。
100pageくらいあります。






2017年1月10日火曜日

GitBookでカスタムドメインを設定してみた。

Gitbookでカスタムドメインを設定してみました。2017年1月の時点で、無料で登録できました。

以下の通り



登録方法

DNSとGitbookの設定が必要です。そんなに複雑ではないです。



(1) DNSの設定

ドメインを取得したレジストラー等でDNSを変更してください
cname firefirebook www.gitbooks.io.
cname firebook www.gitbooks.io.
cname firefiremanga00 www.gitbooks.io.



(2) GitBook側の設定

Gitbook側にの利用するカスタムドメインを設定します。
に移動後、各々の本の設定画面に移動する
  1. Settingをクリック
  2. Domainをクリックすると、Custom Domains のページが表示されるので、カスタムドメインを入力 
  firefirebook.firefirestyle.net と入力する。

 これで、登録ができました。


PS

Gitbookのユーザーページへの移動が、分かりにくくなるので、
誘導するリンクを追加した方が良いかも知れません

私はの場合、以下のページに誘導しにくくなった
印象を受けました。


炎の型 (漫画版) 第1巻 Scratchでプログラム入門 Tennis For Twoを作ってみよう!!

炎の型 (漫画版) 第1巻 Scratchでプログラム入門 Tennis For Twoを作ってみよう!!
https://www.gitbook.com/book/kyorohiro/firefirestyle_000/details

の作成を、再開しました。
以下、抜粋





PS

- 火の型 With Scratch (ゲームプログラム入門)

https://www.gitbook.com/book/kyorohiro/firestyle/details


-  炎の型 With Scratch (ゲームプログラム入門)

https://www.gitbook.com/book/kyorohiro/doc_scratch/details
Scratchを利用して、様々なゲームを作成していきます。 世界初のビデオゲームである「Tennise for two」、世界初のシューティングゲームである「Spacewar!」。アーケードでビデオゲームの地位を確立した「Pong」などのチュートリアルが収録されています


- 火の型 アドベント2016

http://qiita.com/advent-calendar/2016/firefirestyle-studio







2017年1月8日日曜日

ひとりAdventしてみた。ScratchとDartでゲームプログラム入門

ScratchとDartでゲームプログラム入門と題して、ひとりアドベントをしてみました。


- 炎の型工房 ScratchとDartでゲームプログラム入門 Advent Calendar 2016
http://qiita.com/advent-calendar/2016/firefirestyle-studio


以前、書いた炎の型が難解なので、はじめてScratchに触れる人との
間を埋めるものとして、以前から、書こうとしていたものです。

- 炎の型 With Scratch (ゲームプログラム入門)
https://www.gitbook.com/book/kyorohiro/doc_scratch/details
Scratchを利用して、様々なゲームを作成していきます。 世界初のビデオゲームである「Tennise for two」、世界初のシューティングゲームである「Spacewar!」。アーケードでビデオゲームの地位を確立した「Pong」などのチュートリアルが収録されています。


無事、25日間で書きりました。
しかし、後半の内容が荒れてしまったのと、PDF等で印刷できる形にしたかったので、以下に作り直したものを置きました。

随時更新しています。100pageくらいのボリュームです。

- 火の型 With Scratch (ゲームプログラム入門)
https://www.gitbook.com/book/kyorohiro/firestyle/details

















 
ではでは





PS

Advent 1日目: http://qiita.com/kyorohiro/items/e3cd8b39e7bb06f12a41
Advent 25日目: http://qiita.com/kyorohiro/items/c85d9299495912b72a5a


Game Boy の VGM から JavaScript への変換後に、 生成AIの補正が有効だった事について

Game Boy の VGM から JavaScript への変換後に、 生成AIの補正が有効だった事について Tetorica FM2612 Playground には GameBoy や Genesis の VGM ファイル から JavaScript へ変換する機能を持って...