Google OR-ToolsのVisual Studio 2019 Community版で始めるをQiitaに投稿しました。
カテゴリー: 未分類
「Android」端末で「ビーコン」を受信
小さいエリアでの通信や端末同士の位置情報を利用したサービスに興味がある。
Androidの開発環境を用意したのでAndroid端末のBLEを利用した「ビーコン」について調べた。
BLEを利用した「ビーコン」は、Bluetooth機器のペアリング時使用していた、アドバタイジングパケットを利用した発信機なイメージ。
その信号をひろって「ビーコン」のIDや信号の強さなどの情報から位置情報サービスに利用するのだろうと思っている。
BLEを利用した「ビーコン」には、Appleの「iBeacon」とGoogleの「Eddystone」があるらしい。
今回は情報が多そうな「iBeacon」を対象とする。
1.テスト用のアプリのインストール
自分で書いたコードが正しく「iBeacon」の受発信を行えているかをテストするためアプリとして以下のものを使用させてもらった。
2.ビーコンライブラリの登録
サンプルコードが豊富なビーコンライブラリの「AltBeacon」を使用する。
ライブラリの登録は「プロジェクトの構造」画面で行う。
「Android Studio」を起動し、プロジェクト、「プロジェクトの構造」>「app」>「依存関係」タブの「+」ボタンを押下するとプロジェクトへライブラリの登録する画面が表示される。
「altbeacon」と入力して検索ボタンを押下すると「org.altbeacon:android-beacon-library」がヒットするので選択し登録する。
build.gradleファイルのdependenciesに次の行が追加されていることを確認。
1 | implementation 'org.altbeacon:android-beacon-library:2.13.1' |
3.BLE関連のPermissionの追加
BLEデバイスにアクセスできるように「app/src/main/AndroidManifest.xml」に次のような設定を追記。
1 2 3 4 5 6 7 8 9 | ... <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/> <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/> </manifest> |
4.「Android」端末側の設定
Bluetoothにアプリケーションがアクセスできるようにするため「Android」端末側の設定が要るようだ。まず、Bluetoothを有効にする。
一度アプリケーションをデプロイした後に、
「設定」>「端末管理」>「アプリケーション」>[デプロイしたアプリケーション]をタップする。「アプリ情報」の「許可」をタップすると「位置情報」の許可設定ができるようになっているので有効にする。(※)
※この許可をしていないと下のようなメッセージが出力されBluetoothにアクセスできない。
1 | D/BluetoothLeScanner: could not find callback wrapper |
5.ビーコン受信のJavaコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | public class MainActivity extends AppCompatActivity //{ implements BeaconConsumer { private static final String BEACON_FORMAT = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"; private static final String UUID = "48534442-4C45-4144-80C0-1800FFFFFFFF"; private BeaconManager beaconManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); beaconManager = BeaconManager.getInstanceForApplication(this); beaconManager.getBeaconParsers().add( new BeaconParser().setBeaconLayout(BEACON_FORMAT)); } @Override protected void onResume() { super.onResume(); beaconManager.bind(this); } @Override protected void onPause() { super.onPause(); beaconManager.unbind(this); } @Override public void onBeaconServiceConnect() { Identifier uuid = Identifier.parse(UUID); Region mRegion = new Region("beacon-test", uuid, null, null); beaconManager.addMonitorNotifier(new MonitorNotifier() { @Override public void didEnterRegion(Region region) { Log.d("beacon","入(EnterRegion)"); } @Override public void didExitRegion(Region region) { Log.d("beacon","出(ExitRegion)"); } @Override public void didDetermineStateForRegion(int i, Region region) { Log.d("beacon","変(DetermineStateForRegion)"); } }); try { beaconManager.startMonitoringBeaconsInRegion(mRegion); } catch (RemoteException ex) { Log.e("beacon","error",ex); } } } |
6.実行
上記のコード実行しiOS版の「Beacon入門」から「ビーコンの発信」を行うと以下のようなログが出力された。
動作しているようだ。
1 2 3 4 5 6 7 8 9 10 11 | D/BluetoothAdapter: STATE_ON D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=10 D/BluetoothAdapter: STATE_ON D/BluetoothAdapter: STATE_ON D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=10 D/beacon: 変(DetermineStateForRegion) 入(EnterRegion) I/ScanHelper: Non-distinct packets detected in a single scan. Restarting scans unecessary. D/beacon: 変(DetermineStateForRegion) D/beacon: 出(ExitRegion) I/BeaconService: unbinding |
次は発信(送信)を試そう。
Unity3DでDebugする
CUDLRによるデバッグ
CUDLR
CUDLR(Console for Unity Debugging and Loggin Remotely)
Unityアセットストアより無料で入手可能なアセット
ターゲットのデバイスに、簡易なWebサーバ(のような物)を稼働させ、Log等をブラウザから確認可能したり
幾つかの簡単なコマンドを実行可能にするツール
使用方法
デバッグオブジェクトの追加
CUDLRの機能を使用するには、GameObjectとして配置する必要があります。
プロジェクトを開き、HierachyウィンドよりEmptyObjectをシーンへ追加し
追加したGameObjectへ、コンポーネントとしてCUDLRのServerを追加します。
Assets/CUDLR/Script/Serverをコンポーネントとして、GameObjectへ登録する
確認の為に、下記のようなコンポーネントを登録します
1 2 3 4 5 6 7 8 9 10 11 | public class DebugPring : MonoBehaviour { // Use this for initialization void Start () { Debug.Log("Script start"); } // Update is called once per frame void Update () { } } |
ビルドし、Deviceにインストールし、アプリケーションを起動します
起動後、ブラウザでhttp://[DviceのIP]:55055/へアクセスすると、実行中のアプリログが確認できます。
DeviceのIPは事前に確認しておいてください。
サンプルで設定したコンポーネントのログが出力されていますね
注意点
リリースモジュールに含まれると、セキュリティー上のリスクとなります。
リリース時にはCUDLRオブジェクトの削除を忘れずに行いましょう
VSCodeによるデバッグ
次にVSCode上にブレークポイントを設定し、ステップ実行を行ってみます
テスト用のコードを少し改変し、ビルド、インストールを行います
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class DebugPring : MonoBehaviour { // Use this for initialization void Start () { Debug.Log("Script start"); StartCoroutine(PrintLog()); } // Update is called once per frame void Update () { } IEnumerator PrintLog(){ var i=0; while(true){ Debug.Log("Loop Start"); i++; Debug.Log(string.Format("count : {0}",i)); yield return new WaitForSeconds(5); Debug.Log("Loop End"); } } } |
アプリの起動後、CUDLRで確認します。
一定時間毎にログが出ていることが確認できます。
デバッグ対象をAndroidPlayerに変更し、再生(▶ボタン)を選択する
しばらく待つと、ブレークポイントで止まる事が確認できます。
変数の中も確認できました。
これで開発が進められそうです。
最後に
執筆時点で、2018.2.0b5がリリースされていたのですが、これはBetaリリースです。
こちらのバージョンはVSCodeからDeviceniにAttacheできませんでした。
xxxx.x.0fxと行ったバージョンが正式バージョンのようですので、利用する際は注意しましょう
「Android」端末で「Hello World」2
androidアプリを作りたい。
まずはお約束の「Hello World」を出力するまでのメモのその2。
実機の実行とデバッグについて触れる。
5.実機「Android」端末(Fujitsu Arrows M03)で実行する
まず、IDEを使ったデプロイ・デバッグができるように「Android」端末を開発者モードに切り替える。
「Android」端末の「アプリ一覧」画面から、「設定」>「端末管理」>「端末情報」と選び、「ビルド番号」を数回タップ。「これでデベロッパーになりました!」とメッセージが出力されたら「端末管理」に「開発者向けオプション」が表示されるようになる。
「開発者向けオプション」画面で「OFF」から「ON」に切り替え、「USBデバッグ」にチェックを入れる。
PCとAndroid端末をUSBでつなげるとUSBデバッグの許可を求めてくるので「OK」を押下する。
IDE(Android Studio)に戻り、再び「ツールバー」から「実行」ボタンを押すと「デプロイ対象の選択」画面に実機(FUJITSU ArrowsM03)が選択可能になった。
6.デバッグモードで起動しブレーク(停止)させる
ブレークポイントの置き方は他のIDEなどと同じ。ソースコードエディタの行番号の右隣をクリックすれば赤丸が表示され、その行でブレークできるようになる。
デバッグモードでデプロイ・起動するボタンはツールバーの「デバッグ」ボタン。
起動中のプロセスにアタッチしてデバッグしたい場合は、「Andoroidプロセスへデバッガー接続」ボタンを押下する。
「プロセスの選択」画面でアタッチするプロセスを選択する。
これで開発する準備ができた。
「Android」端末で「Hello World」1
Androidアプリを作りたい。
まずはお約束の「Hello World」を出力するまでのメモのその1。
エミュレータで「Hello World」を出力するまで起動するまで。
事前準備として次のものを用意した。
- 開発機:Windows 10
- スマホ:Android 6.0.1 (Fujitsu Arrows M03)
1.「Android Studio」をセットアップ
AndoridのIDEを「Android Studio」をセットアップする。
developer.android.comからインストーラ(.exe形式)のファイルをダウンロードし、インストールを実行した。
「Android Studio」にはOpenJDKが同梱されているのでOracleJDKを別にインストール必要はないようだ。
「次へ」を連打してインストール終了。
2.「Andorid Studioプロジェクト」を作成する
インストール直後に起動される「Android Studioへようこそ」画面で「新規Android Studioプロジェクトの開始」を選択。
「Android プロジェクトの作成」画面で、適当な「アプリケーション名」「会社ドメイン」「プロジェクトのロケーション」を設定する。
- アプリケーション名は、アプリケーションパッケージ名として使われるようだ。
- 会社ドメインは、ルートパッケージ名として使われるようだ。
- プロジェクトのロケーションは、ソースを配置する任意のディレクトリをセットする。
「ターゲット Android デバイス」画面で、「スマホおよびタブレット」にチェック、「API23: Android 6.0(Marshmallow)」を選択する。
「次へ」を押下するとプロジェクトが作成された。
3.プロジェクト作成後の画面でエラーが出力された。
プロジェクトの作成後、Gradleが実行されるようだが、イベントログに下記のエラーが出力された。
1 2 | 17:36 Gradle 同期が開始されました 17:36 Gradle 同期失敗: Please use JDK 8 or newer. (92ms) |
このプロジェクトが使用するJDKのパスの設定が正しくないようだ。メニューの「プロジェクト」>「SDKローケーション」>「JDKロケーション」で「埋め込みJDKを使用する」にチェックを入れると同期(ビルド)が正常に行われた。
1 2 3 4 5 6 7 | 17:36 Gradle 同期が開始されました 17:36 Gradle 同期失敗: Please use JDK 8 or newer. (92ms) 17:40 Gradle 同期が開始されました 17:40 Project setup started 17:40 Gradle sync finished in 24s 849ms 17:40 タスク実行中: [:app:generateDebugSources] 17:41 Gradle ビルドが完了しました 8s 478ms |
4.エミュレータ(AVD:Android Virtual Device)で実行する
作成された直後のプロジェクト(未だコードを加えていない)をとりあえず実行するために「Android Studio」に付属するエミュレーターを使用する。
エミュレータを管理するツール「AVDマネージャー」は、ツールバーの「AVDマネージャー」ボタンをクリックすると起動する。
「仮想デバイス」画面で「仮想デバイスの作成」ボタンを押下。
「ハードウェアの選択」画面では、一昔前のデバイスをということで「Nexus 6」を選択した。
「システム・イメージ」画面では、プロジェクト作成で指定したAPIレベルと同じ「Marshmallow(APIレベル:23,Android 6.0)」を選択した。
「Android仮想デバイス(AVD)」画面では、デフォルトの設定をそのまま使用する。「完了」を押下すると設定したデバイスのエミュレータが登録され使用できるようになる。
「ツールバー」の「実行」ボタンを押下するとアプリケーションのデプロイ先を選択できる「デプロイ対象の選択」画面が起動する。
作成した仮想デバイスを選択するとアプリケーションがデプロイされ起動した。
仮想デバイスで次のようにアプリケーション起動した。
うん?なにもコード書いていないのに「Hello World」と表示されている?(笑)もう少し手を加えよう。
「その2」続きます。