LoginSignup
6

More than 3 years have passed since last update.

Nordic UART 通信する Andorid BLE アプリをつくる (Android-nRF-UART編)

Last updated at Posted at 2019-05-10

BLEアプリ(2)

Nordic UART Service に接続するAndroidアプリとして、

nRF UART 2.0
https://play.google.com/store/apps/details?id=com.nordicsemi.nrfUARTv2&hl=ja

があります。このソースはこちら

Android-nRF-UART
https://github.com/NordicPlayground/Android-nRF-UART

にあります。

ライセンスは3条項BSDライセンスなので、このアプリを基にして自分のアプリ作成もできますね。

準備

ダウロードしたZIPファイルを解凍し、自分のアプリの名前にディレクトリ名を変更します。


$ unzip Android-nRF-UART-master.zip
$ mv Android-nRF-UART-master Android-nRF-UART-test

旧い環境の設定が残っていてめんどくさいことになるので、競合しそうなファイルを削除します。


$ cd Android-nRF-UART-test/
$ ls
LICENSE  README.md  app  build.gradle  gradle  gradlew  gradlew.bat  import-summary.txt  local.properties  nRFUART_GoogleAPI_Android4.3+.iml  settings.gradle
$ rm -rf build.gradle gladle gradlew gradlew.bat import-summary.txt local.properties nRFUART_GoogleAPI_Android4.3+.iml settings.gradle gradle

プロジェクトフォルダ内は以下のものだけにします。


$ ls 
LICENSE  README.md  app

Android Studio を起動し、File-OpenでAndroid-nRF-UART-test/appを選びます。

image.png
OKを押して進めます。
エラー出ますが対処は後として、先にアプリ名を設定しておきます。
app - src - res - values - strings.xml をクリックして該当箇所を書き換えます。

image.png

Gradle関連バージョンの調整

旧い環境のプロジェクトを引き継ぐ場合は、GradleやAndroid Pluginのバージョンなどを適切に設定します。

cf., 僕たちはいつまでこんな楽しいAndroid Studio設定をし続けるのか? Android Studio 3.x時代の設定不足解消メモ
https://qiita.com/riversun/items/78353cb2b3a8c7aa97a5

File- Project Structure - Project を押すと、以下のようになっています。
image.png

以下を参照し、
https://developer.android.com/studio/releases/gradle-plugin.html
https://developer.android.com/studio/releases/build-tools

Gradle バージョン 4.6 + Android Plugin バージョン 3.2.1 + SDK Build Tools バージョン 28.0.3 + compileSdkVersion 26 の組み合わせでいくととにします。

なお、どの表記がどういう意味を持っているかについては
「夜でもアッサム AndroidのcompileSdkVersionとかbuildToolsVersionとか」
を読んで判断の助けにしました。
http://assam-at-night.blogspot.com/2015/05/androidcompilesdkversionbuildtoolsversi.html

以下のように設定します。

image.png


Supplied String module notation '3.2.1' is invalid. Example notations: 'org.gradle:gradle-core:2.2', 'org.mockito:mockito-core:1.9.5:javadoc'.
Open File

というエラーが出ているので、
「Open File」を押して、

build.gradleを表示します。以下のようになっています。


apply plugin: 'com.android.application'
android {
    compileSdkVersion 18
    buildToolsVersion "23.0.0"

    defaultConfig {
        applicationId "com.nordicsemi.nrfUARTv2"
        minSdkVersion 18
        targetSdkVersion 18
    }


    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    compile 'com.android.support:support-v4:23.0.0'
}
buildscript {
    dependencies {
        classpath '3.2.1'
    }
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }
    }
}
allprojects {
    repositories {
        jcenter()
    }
}

以下のように変更します。


buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
    }

また、
compileSdkVersion や targetSdkVersion , minSdkVersion が 18 となっています。これは

image.png

によると該当は Android4.3 で、相当旧いですね。当初の予定どおり、compileSdkVersion 26 とします。また、buildToolsVersion "28.0.3"にするために以下のように変更します。


android {
    compileSdkVersion 26
    buildToolsVersion "28.0.3"

build.gradle の修正

allprojectsについても変更します。
AAPT2 (Android Asset Packaging Tool 2) ツールが Google's Maven repository で配布されるようになったことに伴っての変更です。

allprojects {
    repositories {
        google()
        jcenter()
    }
}

Build - Make Projectします。


Lint found fatal errors while assembling a release target.

To proceed, either fix the issues identified by lint, or modify your build script as follows:
...
android {
    lintOptions {
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }
}
...

と出ます。lint はコード検査ツールですが、今回はメッセージ通り、lint エラーを無視するように build.gradle に追記します。

android {
   lintOptions {
        checkReleaseBuilds false
        abortOnError false
    }
・・・

更に Build- Make Project とすると、


Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'.

と出ます。GradleのJavaプラグインにて「compile」の依存関係は廃止となることを受けてのことだそうです。implementationに変更するのが良いそうです。

build.gradle の


dependencies {
    compile 'com.android.support:support-v4:23.0.0'
}


dependencies {
    implementation 'com.android.support:support-v4:23.0.0'
}

とする。

結果、build.gradle は最終的にこうなりました。


apply plugin: 'com.android.application'
android {
    lintOptions {
        checkReleaseBuilds false
        abortOnError false
    }
    compileSdkVersion 26
    buildToolsVersion "28.0.3"

    defaultConfig {
        applicationId "com.nordicsemi.nrfUARTv2"
        minSdkVersion 18
        targetSdkVersion 18
    }


    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
    implementation 'com.android.support:support-v4:23.0.0'
}
buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
    }
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }
    }
}
allprojects {
    repositories {
        google()
        jcenter()
    }
}

AndroidManifest.xml の修正

Build - Make Project とすると、


The minSdk version should not be declared in the android manifest file. You can move the version from the manifest to the defaultConfig in the build.gradle file.

と出るので
app-manifests-AndroidManifest.xmlを開き、

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.nordicsemi.nrfUARTv2"
    android:versionCode="43"
    android:versionName="2.0" >

    <uses-sdk
        android:minSdkVersion="18"
        android:targetSdkVersion="18" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
・・・

を以下のように直します。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.nordicsemi.nrfUARTv2"
    android:versionCode="43"
    android:versionName="2.0" >

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
・・・

RUN

Run-Run 'app' で、接続するとアプリが実行されます。

なお、


Installation failed with message Failed to establish session.

と出たことがありました。
その場合、 “Build, Execution, Deployment” の下の、”Instant Run”の画面で、
Enable Instant Run to hot swap code/resource changes on deploy(default enabled).

のチェックを外して、OKをクリックしたら動作しました。

apkファイル作る

Build - Make Module 'app' とすると app/build/outputs/apk/debug に  app-debug.apk が生成されます。

なお、この apk ファイルインストールしようとしても、
「アプリはインストールされていません」と出ることがありました。
その場合、
~/.android/中の
debug.keystore
debug.keystore.lock
を削除したら動くようになりました。

改造する

元々の Android-nRF-UART は以下のような動作をします。

  • テキスト入力した一行をSend ボタンを押すと BLE デバイスに送信
  • BLE デバイスから受信したデータを画面にテキスト表示

これを、以下のように直します。

  • テキスト入力エリアを削除し、Send ボタンを押すと定形データ (今回は "UDLRABUD" )を送る
  • BLEデバイスから受信したデータを( Byte列 )をカンマ区切り数値形式で表示

Send ボタンを押すと定形データを送る

まず、main.xml 中にある sendTextを削除します。
image.png

次に、app-java-MainActivity中の以下の箇所を修正します。


        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//              EditText editText = (EditText) findViewById(R.id.sendText);
//              String message = editText.getText().toString();
            String message = "UDLRABUD";
                message = "timedemo";
                byte[] value;
                try {
                    //send data to

更に、MainActivity中で sendText で検索して出てきた行をコメントアウトします。
また、edtMessage で検索して出てきた行もコメントアウトします。

受信したデータを( Byte列 )をカンマ区切り数値形式で表示

app-java-MainActivity中の
if (action.equals(UartService.ACTION_DATA_AVAILABLE))
箇所を修正します。


          //*********************//
            if (action.equals(UartService.ACTION_DATA_AVAILABLE)) {

                 final byte[] txValue = intent.getByteArrayExtra(UartService.EXTRA_DATA);
                 runOnUiThread(new Runnable() {
                     public void run() {
                         try {
                             if (txValue != null && txValue.length > 0) {
                                 StringBuilder text = new StringBuilder();
                                 for (byte d : txValue) {
//                                     text.append(String.format("X%02X,", d));   // Hexadecimal
                                     text.append(String.format("%d,", d));    // Decimal
                                 }
                                 String currentDateTimeString = DateFormat.getTimeInstance().format(new Date());
                                 listAdapter.add("[" + currentDateTimeString + "] RX: " + text);
                                 messageListView.smoothScrollToPosition(listAdapter.getCount() - 1);
                             }
                         } catch (Exception e) {
                             Log.e(TAG, e.toString());
                         }
                     }
                 });
             }
           //*********************//

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6