- 投稿日:2019-05-24T19:19:10+09:00
AWS Cloud9 で サーバサイドKotlin の開発環境を構築する
こんにちは。らすてぃです。
昨年あたりから、SpringBoot + Kotlin
をIntelliJ IDEA
で弄っていたのですが
事情により、その開発環境を クラウドIDE(AWS Cloud9) で用意することにしました。最終的に到達したいことはもろもろあるのですが、少しずつ進んでいきたいと思います。
できるようになること
- AWS Cloud9 上で
- Kotlinの開発ができる
- githubのリモートリポジトリにpushできる
- docker-composeが利用できる
事前にやっておくこと
- AWS Cloud9 の準備
- アカウント作成とかIAM作成とかそのあたり
Kotlin の環境を作る
EC2のOSはUbuntuを選択。なので、aptで構築していきます。
以下の記事がとても参考になりました。
https://qiita.com/kako351/items/3360cbac578aa7e35c9bJavaのインストール
1. リポジトリ追加
$ sudo add-apt-repository ppa:openjdk-r/ppa2. アップデート
$ sudo apt-get update3. Javaのパッケージ確認
$ sudo apt-cache search openjdk-.+-jdk$ openjdk-11-jdk - OpenJDK Development Kit (JDK) openjdk-8-jdk - OpenJDK Development Kit (JDK)4. Java11をインストール
$ sudo apt-get install openjdk-11-jdk5. Java11に設定
$ sudo update-alternatives --config java There are 2 choices for the alternative java (providing /usr/bin/java). Selection Path Priority Status ------------------------------------------------------------ * 0 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 auto mode 1 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 manual mode 2 /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java 1081 manual mode Press <enter> to keep the current choice[*], or type selection number:選択肢を聞かれるので、
java11
を選択します。 (この場合は1)6. バージョン確認
$ java -version openjdk version "11.0.3" 2019-04-16 OpenJDK Runtime Environment (build 11.0.3+7-Ubuntu-1ubuntu218.04.1) OpenJDK 64-Bit Server VM (build 11.0.3+7-Ubuntu-1ubuntu218.04.1, mixed mode, sharing)Kotlinのインストール
公式サイトを見ながらインストールします。
https://kotlinlang.org/docs/tutorials/command-line.html
1. SDKMAN!のインストール
$ curl -s https://get.sdkman.io | bash $ source "/home/ubuntu/.sdkman/bin/sdkman-init.sh"2. Kotlinのインストール
$ sdk install kotlinちなみにバージョンを指定したい場合は、次のように利用可能なバージョンを確認・指定する
$ sdk list kotlin ================================================================================ Available Kotlin Versions ================================================================================ 1.3.31 1.2.31 1.1.2-5 1.0.0 1.3.30 1.2.30 1.1.2-2 1.3.21 1.2.21 1.1.2 1.3.20 1.2.20 1.1.1 1.3.11 1.2.10 1.1 1.3.10 1.2.0 1.0.7 1.3.0 1.1.61 1.0.6 1.2.71 1.1.60 1.0.5-2 1.2.70 1.1.51 1.0.5 1.2.61 1.1.50 1.0.4 1.2.60 1.1.4-3 1.0.3 1.2.51 1.1.4-2 1.0.2 1.2.50 1.1.4 1.0.1-2 1.2.41 1.1.3-2 1.0.1-1 1.2.40 1.1.3 1.0.1 ================================================================================ + - local version * - installed > - currently in use ================================================================================ $ sdk install kotlin 1.3.313. バージョン確認
$ kotlinc -version info: kotlinc-jvm 1.3.31 (JRE 11.0.3+7-Ubuntu-1ubuntu218.04.1)4. Hello, World!
hello.ktfun main(args: Array<String>) { println("Hello, World!") }$ kotlinc hello.kt -include-runtime -d hello.jar $ java -jar hello.jar Hello, World!Gradleのインストール
これも公式サイトを見ながらインストールします。
SDKMAN!が使えるようになっているので、それを使います。
$ sdk install gradlegithubの設定をする
鍵の作成
$ ssh-keygen -t rsa -b 4096 -f id_rsa_cloud9 -C your_email@example.com公開鍵の設定
- github.com の
Settings
からSSH and GPG keys
にあるNew SSH key
をクリック- Title に識別できる文字列を入力し、Key に先程作成した公開鍵の内容をペーストする
Add SSH key
をクリック接続の確認
$ ssh-agent bash $ ssh-add ~/.ssh/id_rsa_cloud9 $ ssh -T git@github.com Hi Your-name! You've successfully authenticated, but GitHub does not provide shell access.Dockerを動かす環境を作る
docker
コマンドは入ってるけど、docker-compose
コマンドは入ってないので、Latest release
バージョンを確認してインストールします。https://github.com/docker/compose/releases/
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose $ docker-compose --version docker-compose version 1.24.0, build 0aa59064執筆時点の最新は
1.24.0
です。次にやることリスト
- SpringBoot + Kotlin の雛形をつくり、github.com のリモートリポジトリにコミットする
- DockerでSpringBootアプリケーションを動かす
- 投稿日:2019-05-24T12:43:19+09:00
【Android】altbeaconでBeaconからの距離(Proximity)を測りたかった話
前回 Macから無事Beaconを発射できるようになった。
Beaconの仕様を知らないまま、BeaconからAndroid端末の距離って測れるよね?と軽い気持ちで試してみようとした記録とメモを兼ねて。。。。
結論から言うと
色々調べてみると、どうやら電波強度や建物の干渉などで正確な距離は測れないみたい。
一応
BeaconManager#addRangeNotifier
で受け取れるbeaconに生えてるdistance(メートル単位)があるけど
本当にメートル???ってなるくらい誤差がひどかった。どうやったか
ググラーエンジニアなのでこのQiitaを発見。
RSSI と TxPower からビーコンとの距離および近接度(Proximity)を推定する
この記事によるとRSSI と TxPower から推定距離を計算する
自由空間では受信信号強度は距離の二乗に反比例して減衰していく(フリスの伝達公式)ので、RSSI と TxPower と距離(d)の関係は次のようになります。
RSSI = TxPower - 20 * lg(d)(lg は底を 10 とする常用対数)
というわけで、距離 d の計算式は以下のようになります。
d = 10 ^ ((TxPower - RSSI) / 20)なんかすごい物理法則的なアレを加味して計算しないといけないっぽかった。(語彙力)
先人の知恵を頂戴して、Kotlinで便利そうな関数を作る。Sample.ktfun beaconDistance(txPower: Int, rssi: Int): Double = 10.0.pow((txPower - rssi) / 20.0)実際に観測してログに出すだけのコードはこちら
Sample.ktoverride fun onBeaconServiceConnect() { ~ 略 ~ beaconManager?.addRangeNotifier { beacons, region -> beacons .map { "Distance:"+beaconDistance(it.txPower, it.rssi) // it.distanceもあったけど誤差がやばい(私的見解) } .forEach { Log.d(TAG, it) } } ~ 略 ~ }測ってみてどうだった?
端末持ってウロウロしてみたけど外の交通量やノイズ?や建物の作りでまあまあ誤差がでるみたい。
beacon.distance
使えないな〜、もうちょっと正確なのがいいな。
くらいの時に目安に使うのならいいかもね。
- 投稿日:2019-05-24T03:51:55+09:00
BiometricPromptをAndroid Mから使う
はじめに
Android Pから
BiometricPrompt
というクラスが追加されました。これはバイオメトリック(生体認証)に関連する処理を引き受けてくれるもので、これを使うと今までアプリ側で実装していたダイアログの表示をシステム側で提供してくれるようになります。また、指紋認証だけでなく、虹彩認証や顔認証にも対応しており、ユーザが選択した方式を判別し、適切なダイアログを表示してくれるという優れものです。それに伴い、従来のFingerprintManager
はAndroid API 28より非推奨になりました。こんな便利な物を使わない手がないと、早速移行してみようと思ったのですが、BiometricPrompt
の最低サポートがAndroid API 28からなので、Min SDKバージョンが28より低い場合は完全に移行することが出来ません?今回はこの問題の解決方法と実装の仕方を簡単にまとめました。
解決方法
いきなり結論からです。
android.hardware.biometrics.BiometricPrompt
ではなくandroidx.biometrics.BiometricsPrompt
を使います。ただし、AndroidXを使うので従来のAndroid Support Libraryとは共存出来ない点に注意してください。実装方法
まず、依存関係をGradleに追加します。
dependencies { ... implementation 'androidx.biometric:biometric:1.0.0-alpha04' }生体認証を使う為、
Android Manifest
にパーミッションを追加します。<uses-permission android:name="android.permission.USE_BIOMETRIC" />最後に認証ダイアログを呼び出す処理を実装します。
val executor = Executors.newSingleThreadExecutor() val biometricPrompt = BiometricPrompt(this, executor, object : BiometricPrompt.AuthenticationCallback() { override fun onAuthenticationError(errorCode: Int, errString: CharSequence) { super.onAuthenticationError(errorCode, errString) Log.d("Biometric", "Error") } override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) { super.onAuthenticationSucceeded(result) Log.d("Biometric", "Succeeded") } override fun onAuthenticationFailed() { super.onAuthenticationFailed() Log.d("Biometric", "Failed") } }) val promptInfo = BiometricPrompt.PromptInfo.Builder() .setTitle("Title") .setSubtitle("Sub title") .setDescription("Description") .setNegativeButtonText("Cancel") .build() biometricPrompt.authenticate(promptInfo)これだけで、認証ダイアログを表示できます。
i ii iii 軽くコードの説明をします。
認証の結果を受け取るのは
BiometricPrompt
インスタンス生成時に渡しているBiometricPrompt.AuthenticationCallback
になります。
関数名 内容 onAuthenticationError エラーが発生して操作が完了された時に呼び出される onAuthenticationSucceeded 生体認証が成功した時に呼び出される onAuthenticationFailed 生体認証が有効だが認識されない時に呼び出される キャンセルボタンのイベントは
onAuthenticationError
メソッドでerrorCode == BiometricPrompt.ERROR_NEGATIVE_BUTTON
と比較することでキャッチすることができます。BIOMETRIC_ERROR
定数に関しては以下のものがあります。
定数名 内容 ERROR_CANCELED 生体認証が利用できない為、操作がキャンセルされた ERROR_HW_NOT_PRESENT 端末に生体センサが搭載されていない ERROR_HW_UNAVAILABLE 端末が利用できない ERROR_LOCKOUT 生体認証に5回失敗した ERROR_LOCKOUT_PERMANENT ERROR_LOCKOUT
の発生回数が多すぎる為、操作がキャンセルされたERROR_NEGATIVE_BUTTON ユーザがネガティブボタン(ダイアログのキャンセルボタン)を押した ERROR_NO_BIOMETRICS ユーザの生体認証情報が登録されていない ERROR_NO_SPACE 操作を完了するのに十分なストレージが用意されていない ERROR_TIMEOUT 認証を実行するまでの時間が長すぎる為、タイムアウトが発生した ERROR_UNABLE_TO_PROCESS 生体センサが画像を処理できない ERROR_USER_CANCELED ユーザが操作をキャンセルした ERROR_VENDOR いずれのエラーにも該当しない
ERROR_CANCELED
は具体的に端末で使用するユーザを切り替えた場合(おそらく生体認証情報がリセットされる)や端末がロックされている場合、他のアプリが生体認証を利用中の場合に発生するみたいです。ERROR_HW_UNAVAILABLE
はどういったタイミングで発生するのかがわかりませんでした。ERROR_LOCKOUT
が発生した場合、30秒後に再度認証可能になるみたいです(知らなかった)。ERROR_UNABLE_TO_PROCESS
はおそらく虹彩認証や顔認証などのカメラを利用する場合に発生するのかと思います。認証ダイアログのカスタマイズは
BiometricPrompt.PromptInfo.Builder
で行います。指定できる項目は以下の通りです。
関数名 内容 setTitle タイトルを設定(必須) setSubtitle サブタイトルを設定(任意) setDescription 説明を設定(任意) setNegativeButtonText ネガティブボタンに表示されるテキストを設定(必須) ダイアログの画像やメッセージといった細かい部分は流石に設定できないみたいですね。
また、認証ダイアログを表示する前に
private fun isBiometricEnabled(context: Context): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context.getSystemService(KeyguardManager::class.java).isKeyguardSecure && context.packageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)のように端末が生体認証を利用出来るか判定した方が良さそうです。
まとめ
足早にですが
BiometricPrompt
をAndroid Mから使う方法を解説しました。本来はBuild.VERSION.SDK_INT
でAndroidのバージョンを取得してFingerprintManager
との処理を切り分けるのが行儀がいいのですが、ぶっちゃけめんどくさい効率的に出来るのであれば致し方ないのかなと。また、虹彩認証と顔認証については、次期バージョンのAndroid Q(API 29)から利用出来るみたいです。今回のデモアプリをGitHubに公開しておきますので、参考にしていただければ嬉しいです。では。参考文献
- Android Developers Docs: https://developer.android.com/reference/androidx/biometric/BiometricPrompt
- Android 9 features and APIs: https://developer.android.com/about/versions/pie/android-9.0
- Fingerprint Authentication using BiometricPrompt Compat: https://medium.com/mindorks/fingerprint-authentication-using-biometricprompt-compat-1466365b4795