osmdroid E/OsmDroid: Please configure a relevant user agent; current value is: osmdroid

AndroidでOpen Street Mapを表示させるライブラリ、OsmDroid。

無料で地図を利用できる幸せ…。開発者の皆様には本当にありがとうございます。


osmdroid E/OsmDroid: Please configure a relevant user agent; current value is: osmdroid

というエラーが表示されて、地図が表示されなくなってしまいました。

下記に情報ありますが、

https://github.com/osmdroid/osmdroid/wiki/Important-notes-on-using-osmdroid-in-your-app

地図の画像をOSMのサーバーからダウンロードする際に、HttpのユーザーエージェントにアプリのIDを入れなくてはいけなくなったようです。

方法は簡単でして地図を表示させるActivityのOnCreateに

Configuration.getInstance().setUserAgentValue(BuildConfig.APPLICATION_ID)

と入れるだけです。(Osmdroid5.6以降)

Android Gradleファイルの階層関係とsettings.gradleについて

Androidの開発をしていると、コードを書いているよりビルドに四苦八苦する時間が多い…ぐらいな気もしてしまいます。

Androidが利用しているビルドツールであるGradleのことについては、大体はAndroid Studioさんがやってくれるので、プログラマの日常業務としてはライブラリの読み込みを編集したり、SDKのバージョンを変更したり、Flavorごとの設定を変更したり…ぐらいなことをやっていて、あんまり理解が進んでいなかったなという気がします。

これにはきっかけがあって、Open Street MapのAndroid組み込み用のサンプルプログラムを自分で使ってみて参考にしようと思ったんですが、Gradle Furyというプラグインを使っていて、結局ビルドできなかったんですよね。Gradle Furyは「Gradleに怒っている人が使う」wwwらしく、POMでいろんなことを定義しちゃおうぜーという試みだったらしいです。

ただ、Gradleのことを全部わかろうというのもちょっと時間の無駄な気がしますね。なので、今回は階層関係と、settings.gradleについて書いておきます。詳しくは、下記の公式サイトで見てみてください。

ビルドの設定

https://developer.android.com/studio/build?hl=JA

Android Studioでプロジェクトを作ると、図のように階層やフォルダができていると思います。(私はWindows 10で開発しています。)


Android StudioでSampleAppというアプリを作ったところ

こんな風に表示されてないよー、という場合は、赤丸してあるところがAndroidになっていると思います。クリックして、「Project Files」にすると、ファイルシステムと同じビューで見れます。この方が、今回はわかりやすいので、この「Project Files」ビューで進めます。

さて、今回最初に話題にしたいのは、下記の水色でマルしたsettings.gradleとbuild.gradleです。

settings.gradleから。中身は下記の一文だけ。


include ':app'

appをつかってビルドしましょうね~って意味でして、これがないと何も始まらないw
今回、一個だけのアプリケーションを使ってビルドするので、一文だけですが、ほかのアプリケーションをモジュールとして利用したい場合、ここにincludeするものが増えていきます。

build.gradleは次の通り。

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
repositories {
google()
jcenter()

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

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()

}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

ここでは、全部のアプリケーションに共通のビルドの設定を書いておきます。さっきも書きましたが、今回は一つのアプリケーションだけなので、あまり意味がありませんが、2つ、3つと増えてくると、一つ一つのアプリケーションのGradleファイルにbuildscriptとか書くのは「ええい、面倒!」と思ってくると思いますので、意味があります。

次に、図の紫で囲った、一個下のappフォルダ内のファイルbuild.gradleの説明です。中身は

apply plugin: 'com.android.application'

android {
compileSdkVersion 28
defaultConfig {
applicationId "smart.location.admin.sampleapp"
minSdkVersion 14
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

で、こっちは見慣れた感じだと思います。こっちで利用するライブラリやビルドタイプなどを決めていきます。

今回は本当に触りだけですが、以上です。

Vagrant + VirtualBox ローカルの開発環境をうっかり消し飛ばした日の話

2019年3月14日 快晴 社員旅行を明日にひかえ、本日も開発日和である。

普段使っている開発環境の挙動が気になり、ゴミファイルの掃除を思いつきました。

私は普段、Vagrant と VirtualBox で作った仮想環境で開発を行っています。

仮想マシンを閉じてもマシンが動いているような気配を感じたスピリチュアルエンジニアの私は、vagrantの様子を伺いました。

こころがおだやかではないので、たんたんとかいてゆきます。
ぜったいにまねしないでください。

>vagrant box list

hogehoge (virtualbox, 0)
piyopiyo (virtualbox, 0)

ここで私はhogehogeの方しか使っていないつもりだったので、piyopiyoを消そうと考えました。

>vagrant box remove piyopiyo
Box 'piyopiyo' (v0) with provider 'virtualbox' appears
to still be in use by at least one Vagrant environment. Removing
the box could corrupt the environment. We recommend destroying
these environments first:

default (ID: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)
default (ID: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb)

Are you sure you want to remove this box? [y/N] n

???

なんか2つ動いてる。どういうこっちゃ。

ここでVMの電源をオフにします。

>vagrant box remove piyopiyo
Box 'piyopiyo' (v0) with provider 'virtualbox' appears
to still be in use by at least one Vagrant environment. Removing
the box could corrupt the environment. We recommend destroying
these environments first:

default (ID: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb)

Are you sure you want to remove this box? [y/N] n

おっ 片方消えた。残った方何者。

>vagrant global-status
id       name    provider   state    directory
--------------------------------------------------------------------------
aaaaaaa  default virtualbox poweroff C:/test_vagrant/hogehuga
bbbbbbb  default virtualbox running  C:/vagrant_test/hogehuga
ccccccc  default virtualbox poweroff C:/vagrant/test
ddddddd  default virtualbox running  C:/vagrant/hogehuga
eeeeeee  default virtualbox aborted  c:/vagrant/hogehuga

The above shows information about all known Vagrant environments
on this machine. This data is cached and may not be completely
up-to-date. To interact with any of the machines, you can go to
that directory and run Vagrant, or you can use the ID directly
with Vagrant commands from any directory. For example:
"vagrant destroy 1a2b3c4d"

うわなんかめっちゃある。

どうやら過去に使った事があるもの(=キャッシュの残っているもの)は全て表示されているらしい。

>vagrant up

>vagrant global-status
id       name    provider   state    directory
--------------------------------------------------------------------------
aaaaaaa  default virtualbox poweroff C:/test_vagrant/hogehuga
bbbbbbb  default virtualbox running  C:/vagrant_test/hogehuga
ccccccc  default virtualbox poweroff C:/vagrant/test
ddddddd  default virtualbox running  C:/vagrant/hogehuga
eeeeeee  default virtualbox running  c:/vagrant/hogehuga

eeeeeeeのやつのstateが変わった。普段使ってるのはコイツか。

>vagrant global-status  --prune
id       name    provider   state   directory
------------------------------------------------------------------------
ddddddd  default virtualbox running  C:/vagrant/hogehuga
eeeeeee  default virtualbox running  c:/vagrant/hogehuga

ふーん? bbbbbbbお前消えるのか。まあ実体無いしそりゃ消えるか。

>vagrant halt
==> default: Attempting graceful shutdown of VM...

>vagrant global-status
id       name    provider   state    directory
-------------------------------------------------------------------------
ddddddd  default virtualbox running  C:/vagrant/hogehuga
eeeeeee  default virtualbox poweroff c:/vagrant/hogehuga

eeeeeeeが停止するよなぁそうだよなぁ。
それはいいんだけど走り続けるddddddd何者なんだ。

>vagrant box list
hogehoge (virtualbox, 0)
piyopiyo (virtualbox, 0)
>vagrant box remove hogehoge
Box 'hogehoge' (v0) with provider 'virtualbox' appears
to still be in use by at least one Vagrant environment. Removing
the box could corrupt the environment. We recommend destroying
these environments first:

default (ID: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb)

Are you sure you want to remove this box? [y/N] n

適当にコマンドを打ち冷静になろうとした。

>vagrant destroy ddddddd
    default: Are you sure you want to destroy the 'default' VM? [y/N] n
==> default: The VM 'default' will not be destroyed, since the confirmation
==> default: was declined.
>vagrant package
==> default: Clearing any previously set forwarded ports...
==> default: Exporting VM...
==> default: Compressing package to: C:/vagrant/hogehuga/package.box

おもむろにバックアップを残そうとする。

>vagrant destroy ddddddd
    default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Destroying VM and associated drives...

あ、今回あっさり消えた。なんで。仮想マシン切ったっけな?

>vagrant global-status
id       name    provider   state   directory
------------------------------------------------------------------------
ddddddd  default virtualbox running C:/vagrant/hogehuga

>vagrant global-status  --prune
id       name   provider state  directory
--------------------------------------------------------------------
There are no active Vagrant environments on this computer! Or,
you haven't destroyed and recreated Vagrant environments that were
started with an older version of Vagrant.

消えてる。

>vagrant box list
hogehoge (virtualbox, 0)
piyopiyo (virtualbox, 0)

piyopiyo消えないかな?

>vagrant up

>vagrant box list
hogehoge (virtualbox, 0)
piyopiyo (virtualbox, 0)

>vagrant global-status
id       name    provider   state   directory
------------------------------------------------------------------------
fffffff  default virtualbox running C:/vagrant/hogehuga

>vagrant halt
==> default: Attempting graceful shutdown of VM...

>vagrant global-status
id       name    provider   state   directory
------------------------------------------------------------------------
fffffff  default virtualbox unknown C:/vagrant/hogehuga

???

――あれ、なんかローカル環境でDBにログインできなくなった。

すっかりvagrantとの戯れを楽しんでしまい、異変に気付くのが遅れました。

サービスもなんかダメだぞなんだこれ?? なんか下手なもん消したか??

やらかした感が溢れだします。面倒なことになりました。

>vagrant up

>vagrant ssh
Last login: Fri Mar 16 14:34:16 2018 from 10.0.2.2
Last login: Fri Mar 16 14:34:16 2018 from 10.0.2.2
Welcome to your Vagrant-built virtual machine.

>vagrant box list
hogehoge (virtualbox, 0)
piyopiyo (virtualbox, 0)

>vagrant box remove piyopiyo
Removing box 'hogehoge' (v0) with provider 'virtualbox'...

>vagrant box list
hogehoge (virtualbox, 0)

>vagrant global-status
id       name    provider   state   directory
------------------------------------------------------------------------
fffffff  default virtualbox unknown C:/vagrant/hogehuga

……(新しくboxから開発環境を復旧させようとする音)

[root@localhost ~]# mysql
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
[root@localhost ~]# mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
[root@localhost ~]# mysql -u root -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

……(裏でmysqlにアクセスができないことを確認している図)

自分の設定したパスでローカルにアクセスできないってのは恐らく、DBが太古の昔(自分がこのDBデータを先人から受け取ったあの日)に戻ってしまったからですね。

……(mysqlのパスを再設定する音

お、DB入れた。

あ、DBのデータが以前のものに戻ってる……

Vagrantをup/haltしても全く動かず電源オフのままであるような、よくわからない仮想マシンを1機削除していたことを思い出し、本件の原因は九割九分九厘それであることを理解しました。

やれやれ。

boxファイルにDBをバックアップしたい。(できるのかな?)

教訓

  • よくわからないデータやファイルを適当に削除するのはやめましょう。
  • 削除前にはバックアップを取るなど、備えを怠らないようにしましょう。

参考

不用意なリソース削除には気をつけよう!

Ghost Inspector の実行APIを試してみる

Ghost Inspector にテストsuiteを実行するためのWebhookがあることに気付いたので、試してみることにしました。

実行API (Webhook URL)

公式のAPIドキュメント によれば、Ghost Inspectorのテストsuite実行APIは、以下の形式になっています。

https://api.ghostinspector.com/v1/suites/<suiteId>/execute/?apiKey=<apiKey>&startUrl=<startUrl>
suiteIdテストsuite画面のアドレスの末尾にある英数字部分です。
https://app.ghostinspector.com/suites/xxx... ←これのxxx...の部分)
apiKey Account Settings > API Access にあるAPI Keyをコピペします。
横にある[Regenerate API Key]は鍵の再生成ボタンなので注意します。
startUrlテストのStart URLが指定できます。(省略するとテストの設定が参照されるっぽい?)
テストの設定が参照される方が嬉しいので、今回は省略します。

というわけで、今回試すWebhook URLは以下のような形になります。

https://api.ghostinspector.com/v1/suites/xxxxxxxxxxxxxxxxxxxxxxxx/execute/?apiKey=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

さあ叩こう

とりあえず、Webhookを叩いてみます。今回はPythonでやってみることにしましょう。

今回、HTTPリクエストの送出には requestsを利用するので、pip等でインストールします。

pip install requests

下記のサイトを参考に、Webhook URLを叩くコードをさっくりと書いていきます。

PythonでSlackのIncoming Webhookを試してみる

先程のWebhook URLをそのまま踏んづけてもテストは実行されるけど、せっかくなのでそれっぽく書いて動作確認。

こちらを実行してみると……Ghost Inspectorのテストが走ります!やったぜ。

もちろんテストの通知設定に従って通知も飛びます。

GETで簡素にやる場合は以下みたいな感じ。

ちなみにrequestsのレスポンスはテストが走り終わるまで返ってこないので、ここでは特に見ていません。
レスポンスに異常があれば、別途Slackに投稿されるような仕組みにしておくと、テストの実行失敗時も検知できて安心感が高まる。

所感

実務的には、動作確認用環境(いわゆるテストサイト/テスト環境)にサービスをデプロイしたあとに、Webhookが自動で叩かれてテストが走る……という流れになると良さそうですね。
テストのし忘れがなくなっていい感じ。

参考

NumPy.add.atなどのユニバーサル関数+at

NumPyについて書くシリーズの続きです。

ユニバーサル関数(ufunc)とは、ベクトル化演算です。いくつもの要素がある中で、一つ一つ処理するよりも、一度に処理したほうが早いですよね。そういうことをやってくれる関数です。

たい焼きを焼くときに、一つ一つ焼いていると大変です。しかし、たい焼き屋さんでは、いくつものたい焼きの穴が開いている鉄板で一度にたくさんのたい焼きをバシッ!!と作りますよね。あんこを足すときも、一度にできて早いですよね。あれのイメージです。

で、今回は、特にそのユニバーサル関数を at と組み合わせた時の動作がちょっとわかりづらかったので書いておきます。

下記の公式サイトにある
https://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.at.html
例なのですが

import numpy as np

a = np.array([1, 2, 3, 4])
np.add.at(a, [0, 1], 1)
print(a)
#下記が出力されます。
array([2, 3, 3, 4])

これを例にとって説明するとadd.atの

・1番目の引数は処理する配列

・2番目の引数は処理したいインデックス

・3番目の引数は、addしたい数

です。

私はPHPとかJavaとかが長いので、こういう「1を加算する」的な処理はついついfor文とかでループで書いてしまいがちなのですが、速さが違うので、NumPyのユニバーサル関数を使いこなしていきたいと思います!!