2026年9月25日金曜日

[バイク]GoogleMap vs moviLink

バイクに乗る人なら、ほぼ全員が使ったことがあるであろう「スマホの地図アプリ」。
私はこれまでずーっとGoogleマップを使ってきたんですが、「moviLink(モビリンク)」の使い勝手がいいと聞いたので、ちょっと試してみました。
もちろん、バイクに付けたスマートモニター(Android Auto)と連動させてのレビューです。
結論から言うと、
  • ソロツーリングならば moviLink
  • マスツーリングならば Googleマップ
というのが個人的な見解。ということで、それぞれを使った感じで評価してみた。

■ moviLink(モビリンク)
〇 通りやすい道を選んでくれる(細い抜け道ではなく、国道や幹線道路を優先してくれるので安心)
〇 ナビ中の地図を、自分の見やすい縮尺に自由に拡大・縮小できる
〇 地図表記が全部日本語(パッと見で分かりやすい)
× スマートモニターからの操作だと、経路変更がしづらい
× 曲がるポイントのガイダンスが若干遅い
× スマートモニタと連動していると、携帯で操作できなくなる?(使い方がよくわかっていないだけかも)

■ Googleマップ
〇 経由地点の削除など、画面の操作がグローブ越しでもやりやすい
〇 ほかの人もGoogleマップを使っていることが多いので、マスツーで同じ経路になりやすい(はぐれにくい)
× ナビ中の地図の縮尺変更がしづらい(拡大・縮小すると現在地追従が止まってしまう)
× 一部が英語表記になる(通りの名前や高速道路の名前など)
× 案内表示の看板が、高速も一般道も「緑」(一般道は日本の標識と同じ「青」であってほしかった)
× 曲がるポイントのガイダンスが若干遅い

まぁ結論としては、好みの問題かもしれません。
どちらのアプリを使っても、曲がるポイントをいつも見逃してしまうのは……私の判断力がアレなところですね(笑)。

先日は、大槻JCTで逆方向に進んでしまい、友人に大変迷惑を。。。そんなこと気にする人たちじゃないが、この場を借りてお詫びをしておこう。

[バイク]スマートモニタの電源を取り直す

先日、バイクで2泊3日の四国一周(くらいな感じの)旅行に行ってきました。総走行距離は1400kmくらい。 
 しかし、日程的にドンピシャで台風が接近中。 これまでハンドルにつけたUSBからスマートモニタの電源をとっていたんですが、当然防水じゃあありません。 ということで、雨の中走るならACC電源から取り直すかと思い立ち、ちょっとDIYしてみました。

 接続のイメージはこんな感じ。 
【 バッテリー 】→【 リレー 】→【 スマートモニタ 】 

 バッテリーとリレーは、ETCとUSBをつける前に自分で追加していました。ETCとUSBは、そのリレーからバイク屋さんにギボシ加工をお願いしてつけてもらったもの。
 このリレーは3つに分岐できるので、余った1か所を使ってスマートモニタの電源を確保する。という計画です。 

 問題は配線。私のXJR1300はネイキッド。カウルがないので、配線の取り回し自体は意外とやりやすいはず。ChatGPTさんやYoutubeを参考にしつつ、いざ配線開始。
 今回のポイントは「タンクを外さないこと」。 完全に外さないまでも、シート側のボルトを外して5cmくらい浮かせると、かなり作業がしやすくなります。 

 タンク下の配線は結束バンドで3点止めました。シート側と真ん中辺りは、それほど苦労することなく結束バンドで固定完了。
 一番苦労したのはハンドル側です。ここはもう気合で結束バンドを通し、何とか固定できました。というか、すでに這わせてあったETCのケーブルに便乗して結び付けた感じです。

 やや強引で心配だったものの、結論から言うと1400kmの移動でも全く問題なし。高速・一般道両方使ったし、とにかく暑くてしんどかった。しかし、トラブルは皆無。

 ただ、肝心の雨はほぼ降らなかったので、防水化の恩恵はあまり感じられなかった……というのはあります。 
 でも、空いたUSBポートのおかげでハンドル周りはすっきりした。今度はUSB電源のドラレコでもつけようかと。

2026年2月25日水曜日

[Android]RoomとKPSとKotlinのバージョン(2026/02)

AndroidのRoomは、SQLiteを簡単に扱えて、Flowで値を取得できます。
RoomのFlowを使った制御の何がよいかというと、データベースを更新すると、勝手にデータをリフレッシュしてくれるんですよね。

最初にRoomを使ったときは、「え?なんでDBを更新すると、画面が勝手に更新されるの?」というのが理解できませんでした。 そうなんです。仕組みを理解していないと、これが分からないんですよね。

ざっくり言うと、DAOにFlowで値を返す関数がある場合、データを更新すると自動でFlowに新しいデータが流れてきて自動的にFlowデータを取り込む。
データを取り込むとFlow(State)を参照しているUIが勝手に更新される。そんな感じ。

ただ、Roomはクセが強い。どこがクセ強かというと、KSPとKotlinのバージョンの組み合わせに依存関係があって、例えばKotlinの版を上げたいなら、合わせてKSPとRoomもいい感じのバージョンにそろえる必要があるのです。 ということで、今日ちょっと調べてみると、最新環境ではこんな感じで合わせられそうだな、ということが分かったので、備忘としてメモ。


■libs.versions.toml抜粋(Kotlinが2.3.10)
[versions]
agp = "9.0.1"
coreKtx = "1.17.0"
junit = "4.13.2"
junitVersion = "1.3.0"
espressoCore = "3.7.0"
lifecycleRuntimeKtx = "2.10.0"
activityCompose = "1.12.4"
kotlin = "2.3.10" // ★2026/02時点では最新版
composeBom = "2026.02.00"
■build.gradle.kts(:app)
plugins {
  alias(libs.plugins.android.application)
  alias(libs.plugins.kotlin.compose)
  id("com.google.devtools.ksp") version "2.3.5" // ★Kotlin 2系に対応したKSP 2026/02時点では最新版

}

・・・省略・・・

dependencies {
  implementation("androidx.room:room-runtime:2.8.4") // ★Room関連 2026/02時点では最新版
  implementation("androidx.room:room-ktx:2.8.4")
  ksp("androidx.room:room-compiler:2.8.4") // ★KSP 2026/02時点では最新版


・・・
}
依存関係に負けてRoomをあきらめた人や、これからRoomちょっと使ってみようかな。という人参考までに。 最新版は↓からたどれます。
Room(部屋って訳されるのが笑える)
KSP

2026年2月10日火曜日

[バイク]レッグウォーマー

仕事中、足元が冷えるんだよねー。冬は。という方にお勧めしたいのが、コレ。おたふく手袋 の冬用レッグウォーマー。

スーツなど、もこもこしたタイプのレッグウォーマーをつけるのがむつかしい服装で働く人にお勧め。しかも安い。股引とかタイツ的なものを使うならこっちのほうがイイかも。っていうくらいイイ。足首やふくらはぎがあったかいと、意外と全体的にあったかくなる。

また、この製品「発熱・防風・保温」をうたっているので、バイクに乗った時どうなんだろう?と試してみるとこれが効果抜群。イイ買い物したな、と思います。

ただ残念なのが、歩いているとズルズルちょっとずつ下がってくる。が、もう手放せないです。

[バイク]後付けグリップヒーター

冬のバイク。楽しいんだけど、乗るまでのハードルが高いんだよねー。

ということで、その辺を緩和する方法として “あったかくする” がある。体は着込めばイイんだけど、手先と足など末端が寒くて死にそうに。ということで、緩和案としてグリップヒーターを買ってみました。

製品は何だっけ?買ったはいいけど一年くらいかしてたんだよね。買ったのはコレ。 

グリップ巻き付け式のUSB電源のタイプのもの。モバイルバッテリーでも行けるタイプ。


使った感想としては、いまいち。個人的な感想。素手で触ると結構あったかいんだけど、グローブ越しだと出力がちょっと足りていない。機能はしているが効果が大きくはない感じ。
ないよりは全然イイ。まぁ冷風を当て続けているので仕方かないのかも。


[バイク]スマートモニタ。意外と悪くない

今までバイク用のナビとして Pixel Watch(+Pixel 9 Pro)を使っていたんだけど、タイムラグがあるのと画面が見づらいせいで、曲がるポイントをよく見逃していました。

まぁあれですね。ないよりは全然イイ。そんな感じ。

しかし、ソロの時はいいのだけど、仲間内でコレをやっちゃうとさすがに迷惑。ということで、スマートモニタを買ってみました。

いや、最初はスマホフォルダを買おうかなと Amazon を物色していたんだけど、そこでスマートモニタを発見。しかも9,000円くらいのタイムセール。これは買うしかない。と思い勢いでMG100を購入。

この製品は USB 電源でも稼働するタイプの機材なので、ハンドルにつけた USB 電源でそのまま動きます。さらに、モバイルバッテリーでも動作するらしい。

で、今日使ってみました。

感覚的に言うとすごくイイ。スマートウォッチと違って反応が早い。あと、5インチと小さいので目立たない。
自宅で初動確認やペアリングしていた時は、正直画面解像度が低いなと思ったんだけど、実際バイクに乗せて動かしてみると、「いや、運転中はこれくらいで十分」と納得。
製品のレビューを見ると、ねじが緩む的なことが書いてあるけど、今のところ大丈夫そう。

そんなに多くの製品を知っているわけじゃないけど、しっかりしてるんじゃないかなーと思う。


ということで、高価なスマフォフォルダ買おうとしている人は一考の価値があると思う。

2026年2月4日水曜日

[Other]Google Books APIsを使う

Google Books APIsは、基本APIキーなしでも使えるんですが、最近キーなしのアクセスが多発気味なのか、すぐに制限がかかっちゃいます。 ということで、APIキーの作り方と、APIの有効化についてメモを残しておきます。 APIキーを取った後は、次のような感じで、アクセスすればOKということで、GETのパラメータにつける簡単な方法を紹介。

書式はこんな感じ
 https://www.googleapis.com/books/v1/volumes?q=inauthor:%E8%8A%A5%E5%B7%9D%E9%BE%8D%E4%B9%8B%E4%BB%8B&key=AIza・・・・
これは、著者が芥川龍之介の書籍を検索する例。key=の後ろに取得したAPIキーをつけることで、制限がかかることがほぼなくなります。

登録手順は次の通り。

まず、「https://console.cloud.google.com/」にアクセス

■プロジェクトの作成
初回のアクセスの場合、利用の同意を求められれます。ということで、チェックをつけて「同意して継続をクリック」

















続けて、プロジェクトの作成。
デフォルトで「My First Project」というプロジェクトができている感じがありますが、なければ、右上の「新しいプロジェクト」をクリックし新規プロジェクトを作成する。





■APIの有効化

Google Books APIsをアクティブ?にします。




「プロジェクト選択」をクリックし、プロジェクトを選択した後、メニュー(3本線)ボタンをクリックする。














有効なAPIとサービスをクリックする。










検索バーに「google books」あたりまで入れると、一番上に、    Books APIが出てくるのでこれをクリック。




有効にするボタンをクリックする。










■APIキーの作成
メニューから、「認証情報」を選択。
    

















「+認証情報を作成」をクリックすると、何の認証情報を作るかを選択できる。
ここで、「APIキー」をクリック。








特に制限することもないので、デフォルトのまま「作成」ボタンを押す。







APIキーの生成が終わると、認証情報の一覧に戻る。






■APIキーの確認

認証情報一覧の画面で、「鍵を表示します」をクリックする。
    
ポップアップが表示されてキーの情報表示される。
この「自分のAPIキー」をコピーし、URLの最後に

「&key=Al.....」をくっつければOK。











2025年10月15日水曜日

[Firebase]firebase deployでハマる

 Firebaseは、googleさんのいろんなAPIやサービスを提供するプラットフォームです。

Firebase Hostingというのがあり、ちょっとしたWebサイト(HTMLなどの公開)がちょっと便利。今回はFirebase Hostingではまった話。


久しぶりに上げていた情報を更新し、Firebase Hostingにdeployしようと思ってコマンドをたたく。の前に、firebase-toolsのアップデート

c:\>npm install -g firebase-tools

いい感じに進んでいく。で、ログインの確認。これもOK

c:\>firebase login
Already logged in as gen**********.com

じゃあコンテンツ修正したしデプロイ行ってみよう!

c:\>firebase deploy

Error: Assertion failed: resolving hosting target of a site with no site name or target name. This should have caused an error earlier

ナニコレ

フォルダの中身を確認すると、認証がダメっぽいログが...

[debug] [2025-10-15T03:05:55.323Z] <<< [apiv2][body] POST https://cloudresourcemanager.googleapis.com/v1/projects/ao-program:testIamPermissions {"error":{"code":401,"message":"Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.","status":"UNAUTHENTICATED","details":...

そこで、cliでfirebaseにログアウトしてログイン。いくつか質問(Geminiを使うか的な確認等)が出てくるがこれをnoで回答。その後再度デプロイでうまくいった。

前回からの作業で、ちょっと時間がたっている場合は、認証に期限切れに注意ってことですね。

2025年9月21日日曜日

[バイク]早旅の登録ができない?

バイク用のETC2.0を付けたのは、速旅という制度があり、コレいいよね。と友人と話していたのがきっかけです。

この速旅にはバイク用のツーリングプランというのがあり、2日間一定の区間が乗り降りし放題など、いろんなプランが用意されている。というバイクに乗る人には、ちょっとうれしい仕組みがあります。

その他の利用シーンとしては、バイクの場合、車と比べ一般的に走行距離が短め。私の所有するXJR1300(98年)は、燃費があまりよくありません。町中を走ると、1リットル当たり10Km走らないことも(これは個体差によるものだと思います。。。)。

ということで、次のSAまでにガソリン尽きるんじゃないコレ。みたいなときに、ちょっと降りて給油する。的なことができるのはいいかもしれませんね。心理的に安全な感じがいい。というかETC2.0なら早旅じゃなくても、一時下車なら2時間まで行ける。仲間内に1系のETCをつけている人がいるならば、いろいろ融通が利きそう。

わき道にそれましたが、この早旅を使わない手はない。ということで利用できるようにするため、速旅のサイトでETCカードと車載器を登録。仕組み的には、ETCカードと車載器番号を紐付けて、その組み合わせが一致したら、事前登録したエリアが乗り放題になる。という仕組みらしい。

・・・で、さっそく登録するも失敗。
登録できるようになるまで、しばらく時間がかかるらしいことが書かれている。

友人(ハーレ)はつけた翌日に登録できたといっていたので、ちょっと心配になってくる。

取り付けしてもらってから3日後、改めて登録をするとすんなり完了。

おそらく、システム間の連携問題。バッチなんだろう。と想像がつく。バッチの処理件数が上限で先送りされたか、そもそもバッチの処理間隔が3日などで、一番遅いパターンにはまったのかな。と推測。

登録ができなかった間、ちょっと試行錯誤。
車載器登録番号って何よ?ってよく見てみると連番ぽい感じがする。自分の番号-1で登録を試みると、なんと成功。確認画面に遷移した。

なんだコレ、大丈夫か?と思ったけど、仕様的にはETCカードと車載器番号が一致しないと割引にならん。ということなんだろう。あと、複数台所有している人向けの考慮だと思う。設計したやつか要件を考えた人が複数台持っているのかなー。

で、車載器番号について、他人の番号がわかってもいいのか?と思ったけど単なる連番の数字だし、何か個人的な情報が洩れることもないだろう。と思われる。。。今時点では。

しかし逆に考えると、友人にバイクを貸す。とか、レンタルバイクに乗車したときに、うまく登録すれば、この割引が使えるじゃない?ということになる。そういうところは芸が細かい。

調べてみると、レンタルバイクの場合、レンタルバイクのオーナーがOKと言ったらコレ使えるらしい。


OKといわなくても、車載器に車載器番号のシール的なものが貼られていて、やろうと思えばできちゃう問題があることはさておき。。。
少し前の話に戻るが、こういう都合もあり、ETCカードと車載器番号で一意に割引対象を特定するシステムなんだろうな。という推測ができる。コレはこれでありだなー。という感想。

しかし、サイト側の画面ちょっと使いづらい。PCの場合、ID/PW入力後、エンターキーでログインしてほしいよね。携帯じゃなくPCを主に使うおじいさんとしては。

たぶん、芸が細かい人が設計して、雑なやつが画面作ったんだろうなー。

2025年9月20日土曜日

[バイク]フロントフォークのオーバーホール(オイルのシミ)

 長く同じバイクに乗っていると、いろんなところが悪くなってきます。その中でもフロントフォークは最多の4回目のオーバーホール。。。


ETC取り付けから帰ってきたら、駐車場に油シミ。。。2個油じみがあるっとことは、ちょっと前からだったのか。

シミをたどって上の方をたどっていくと、フロントフォークにわっか状の跡が。フロントフォークからのオイル漏れか。。。

仕方がないので、にりんかんとYSPに電話。修理の額面は同じくらいだったので、着手が早くできそうなYSPに依頼。

代車(125のスクーター)貸してくれるんだけど、ちょっと遠いんだよね。・・・ミスターバイクがあれば。。。なんも考えなくてよかったのにー。と、ないものを考えても仕方がない。



YSPで見てもらうと、おそらくインナーチューブは大丈夫。ということでオーバーホールのみ。なんかインナーチューブの値段が上がっているらしく、1本5万くらいするらしい。これダメだったら2本交換の+10万。。。今回はオーバーホールだけなので6万コース。9月の終わりに帰還予定。


2025年9月18日木曜日

[バイク]甲信・東海・北陸エリアETC車載器購入助成キャンペーン2025

今、etc車載器の取り付けキャンペーンやっています。
 私は2りんかんさんでMSC-BE700Sを取り付けました。 

xjr1300(ネイキッド)なので¥37,790から1万円引きでした。
本体はシート下、アンテナは左側のバックミラーにステイ?をつけてその上に。

タンクを外しての作業なので、ついでにプラグ交換とUSB電源取り付けも。ETC取り付けと同時だと工賃半分くらいになります。 

作業は3時間くらいかかるかも。ということで、貸し出してくるすくーたでマクドナルドへ。
ご飯食べて、しばらくお仕事。1時間半くらいで作業完了の連絡がきました。早い。もともとリレーが入っていたからかな?

気になっていたプラグ交換も安くできたし、 それほど使わないけど、先々高速度道路を使うことを考えると、結構お得かも。

2022年3月8日火曜日

[Android]Android Studio(2021.1.1 Patch2)でFirebase Cloud Firestoreを使う その2

さすがに、カンで終わらすのは。と思い、前回の続き。
android studioで
 ツール(T)→Firebase
と押すと、下の画像のようなViewが出てくる。
ここで②のところ(すでにやっちゃってますが)を押すと、build.gradleに必要な設定が入ってくれる!
何てことだろう。。。みんなコレやってるんだよね。きっと。
カンでやったのとは、一味違いますね。参考にするならこっちでお願いします。

[Android]Android Studio(2021.1.1 Patch2)でFirebase Cloud Firestoreを使う

ちょっと古めのAndroidStudioを使っていて、ま、Firestoreを使うならアレね。というのは覚えた。血反吐を吐きながら。
時は流れ、AndroidStudioのバージョン新しめにして、同じことをやってみる。っという感じでbuild.gradleを編集。
ということで、build.gradle(プロジェクト)を開いてみる
plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
・・・ずいぶんシンプルになったなぁ。と思いつつ、いつも通りのアレを追加してみる。
plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
}

// 追加
buildscript {
  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository

  }
  dependencies {
    ...
    // Add this line
    classpath 'com.google.gms:google-services:4.3.10'

  }
}
// 追加


task clean(type: Delete) {
    delete rootProject.buildDir
}
で、syncnowを押してみる。いつも通りいけるかなぁ。。。と甘くはない。公式サイトの「Firebase SDK の追加」の手順なんだけどね。
ということで、直感を信じて適当に直してみる。
plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
    // 追加
    id 'com.google.gms.google-services' version '4.3.10' apply false
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
こんなんでいいはずないしー。と思いつつsyncnowを押してみると、正常終了。
で、build.gradle(モジュール)のほう。こちらもいつも通り、依存を追加してみる。
dependencies {
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    //追加した記憶がない...
    implementation 'com.google.firebase:firebase-firestore:23.0.2'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    //追加
    implementation platform('com.google.firebase:firebase-bom:29.1.0')
}
こんな適当でうまくいくなら苦労はないわー。と思いつつサンプルを実装。


お、コンパイルった。じゃあ、ランタイムエラーかな?と思ったらコイツ動くぞ。
ということで、理屈はわかりませんが、firestoreでbuild.gradleに困ったら参考にしてください。

2021年8月13日金曜日

[JavaScript]Mapを使う(連想配列)

JavaScriptは、ちょっとくらい変な実装をしてもそれっぽく動くことがあります。
コンパイルする形式の言語である、C#やJavaに慣れていると、むずがゆくなることがあります。

ということで、間違えから偶然見つけて、調べてみると普通に連想配列だった話。
JavaScriptでMapを使うには、以下のようにする。そう、何も考える必要はないのです。なぜならば、objectに連想配列の機能が混ぜ込まれているからです。
コードはこんな感じ。
let map ={};
map["aaa"] = "aaa";
console.log(map["aaa"]);
//"aaa"と表示される

//ちなみに↓のようにもアクセスができる
console.log(map.aaa); // aaaと出力される

//メンバ変数のように代入もできる
map.bbb = "bbb"
console.log(map.bbb); // bbbと出力される
JSONをオブジェクト化するとこもこんな感じでやってるんだろうね。
・・・mapというか、属性を動的に増やす。という考え方。 ちなみに、objectなら何でもOK。こんなこともできる。
let list =[1,2,3];
list.bbb = "bbb";
console.log(list.bbb);// bbbと出力される
console.log(list);(3) [1, 2, 3, bbb: "bbb"]と出力される
JavaScript。。。何でもありですね。

[JavaScript]変数宣言の仕方(var let const)

JavaScriptの変数宣言。書き方いろいろある。制限(コーディング規約等)がないならlet使えというのが結論。
理由は、letを使っておけば、動作時に変数宣言の上書きに気が付けるから。です。
あと、定数はconstを使うのが結論。値を書き換えることができないからね。 

 以下、それぞれ組合せでの検証結果。

■varとletの組合せ
var let
var var a="a";
var a="b";
aの値は"b"になる!
var a="a";
let a="b";
実行時エラー
let let a="a";
var a="b";
実行時エラー
let a="a";
let a="b";
実行時エラー

constもletと同じ特性。consutは、値の更新もできない。↓のような場合エラーになる。
const b = "b";
b="B"; //エラー

let c ="c";
c = "C";// こっちはOK。というか普通の使い方。

ちなみに、varの上書きパターンこういうのが正常終了しちゃう。意味の分からない障害が出そう。
var aaa = "aaa";
var aaa = 100;
ということでletがおすすめ。

[JavaScript]Listを使う(動的に要素を増やすことのできる配列)

C#やJavaはクラスライブラリで様々な機能が提供されているけど、JavaScriptで同じようなことをしようとすると、外部のライブラリをインクルードする感じで使うのが一般的かな。と思います。
と、前置きが長くなりましたが、Listを使いたかったのです。
C#でいうと、↓のような感じ。
var list = new List<string>();
で調べてみたら、JavaScriptでは、[](Arrayというクラス)を使う。使い方は以下の通り。
JavaScriptの型については、闇が深そうなので、今日は割愛。
let list = [1,2,3];
//初期値不要なら
//let list = [];
//要素の追加
list.push(4);
console.log(list);
//(4) [1, 2, 3, 4] と表示される
つまるところ、変数に[]を代入すると、そいつは、Listになる。ってことですね。そしてなんでも入れれてしまいます。
let list = [1,2,3];
//要素の追加
list.push("あ");
console.log(list);
//(4) [1, 2, 3, "あ"] と表示される
list.push({name:"hoge"});
console.log(list);
//(5) [1, 2, 3, "あ", {…}] と表示される
genericsがなかったころのjavaを思い出します。。。 ちなみに、pushがあるならpopもあるだろと。そうあるんです。さっきの続き。
list.pop()
//戻り値→{name: "hoge"}
console.log(list);
// (4) [1, 2, 3, "あ"] 最後に突っ込んだ要素がなくなっている。
list.pop()
//戻り値→"あ"
console.log(list);
// (3) [1, 2, 3] その前の要素がなくなっている
スタックがあるならキューもあるだろーと。そうあるんです。さらに続き。
list.shift()
//戻り値→1
console.log(list);
// (2) [2, 3] 先頭の要素がなくなっている
JavaScriptなんでもありっすね。

[JavaScript]confirmやalertをオーバーライドする

sliniumun等を使って、Webサイトの自動操作をすることがあります。んーあんまりないか。
自動操作しない場合でも、デバッグの時は、alertを出し、本番環境では、ログ出力。みたいなことをしたいことがあります。んーあんまりないか。console.log使うもんね。
ということで、強制的にalertやconfirmを何とかする方法ないかな。と思って調べてみると、alertやconfirmを上書き(オーバライド?)する方法がありました。
実装は↓のような感じ。以下は、chromeのconsoleで実行しているけど、htmlに入れれば、そのまま実現できる
window.confirm = (text) => { console.log(text); return true; }
常に「はい」ボタンを押した状態と同じになっちゃいますが、自動運転中に入力不要になりいい感じ。

ちなみに、alertも同じように、window.alert = function(text){}でOK。

で、chromeのconsoleで確認してみると、↓みたいになっている。
//chromeのconsoleで↓を入力
> window.confirm
//こんなのが表示された。edgeでは表示されなかった。。。
ƒ (text) {
    recordedConfirmation = text
    if (document.body.hasAttribute('setConfirm')) {
      document.body.removeAttribute('setConfirm')
      return nextConfirmationResult
    } else {
      l…
よくわからないけど、prompt.jsというソースにたどり着き、中身が見れる。 プラグインがいろいろ入っているからかもしれないけどね。

2021年1月9日土曜日

[Other]コードのシンタックスハイライト

コードをハイライトするために、SyntaxHighlighterを使っていたんですがリンク切れで遅くなていました。
で、とりあえずスタイルやJSのリンクを消したものの、コードのサンプル表示がかっこ悪かったので、これを機に修正しました。
で、使ったのが、「highlight.js」です。
SyntaxHighlighterとくらべ軽量で言語の対応も多いらしいです。 ということで使い方。
↓のコードを<head>に埋め込めばOK
<link rel="stylesheet"
      href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.5.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
サポートしている言語は、GitHubのほうを参照で。
使い方はhttps://highlightjs.org/usage/を参照。


当サイトは、VisualSutudio風のデザインを使っていますが、このデザイン枠がなんです。
ということで、スタイルの一部を改変。現状はこのスタイル(.hljs)が必ずセットされるので、それをチョット改変。
<style type='text/css'>
.hljs {
  display:block;
  border:1px solid #ffa500;
}
</style>

デモサイトがあり、こっちも便利。分かりやすい。参考になる。


取り合えず、チョットやな感じで何とかしたいこと。
  • 1行目の空行<pre><code>の後ろに改行入れると、改行されちゃう
  • <と>。コードをそのまま貼り付けれない。1行に1個までなら何とかなるっぽいけど、理由がわからない。js内に変換してそうなコードはあるんだけど。。。うまく動いていないのだろうか
・・・こいつら何とかしたい。

2021年1月6日水曜日

[Android]非推奨になったAsyncTaskの代わりに、ExecutorServiceとLiveDataを使う

Android11(APIレベル30)がリリースされてからしばらくたちます。
その中でも困りそうなのが、AsyncTaskが非推奨になったことです。
AsyncTaskを使うと、AndroidStudioに取り消し線がつくのが気に入らないので、今のうちにイイ感じの実装方法を覚えていおたほうがいいかな。と思います。

AsyncTaskを機能分割すると、流れ的に大きく3つ。
  1. doInBackground(Params... params) バックグラウンド処理
  2. onProgressUpdate(Progress... values) 進捗状況をUIで表現
  3. onPostExecute(Result result) 1.の結果を処理する(成功したらDBに登録とか)
このうち、1,3は必須。2は場合によってって感じかな。と思います。

で、よさげな実装案は、次の通り。
  1. java.util.concurrent.ExecutorServiceでバックグラウンド処理
  2. JetPackのLiveDataで進捗状況をUIで表現
  3. JetPackのLiveDataで1.の結果を処理する
1,3はイイ感じかなと思います。2はちょっとダサいけどできなくはない。じゃあ実際にどうするか。というと、
  1. JetPack LiveDataの利用準備
  2. LiveData用モデルの作成
  3. LiveDataの更新コールバックを受け取るリスナーの設定
  4. ExecutorServiceを使った非同期処理の実行
という感じかな。と思います。じゃあ、実装例。

1.JetPack LiveDataの利用準備
app/build.gradleに以下追記。ADDってなっている部分。
dependencies {
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'com.google.android.material:material:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.navigation:navigation-fragment:2.2.2'
    implementation 'androidx.navigation:navigation-ui:2.2.2'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    //<<ADD
    def lifecycle_version = "2.2.0"
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
   //>>ADD
}
2.LiveData用モデルの作成(クラスの用意) 
↓のような感じのクラスを作る。
public class MyViewModel extends ViewModel {
    private MutableLiveData<String> currentName = new MutableLiveData<String>();
    public MutableLiveData<String> getCurrentValue() {
        return currentName;
    }
}
3.LiveDataの更新コールバックを受け取るリスナーの設定
4.ExecutorServiceを使った非同期処理の実行
public class FirstFragment extends Fragment {

    //2.LiveData用モデルの作成(変数定義)
    private MyViewModel model;

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        //2.LiveData用モデルの作成(インスタンス生成)
        model = new ViewModelProvider(this).get(MyViewModel.class);

        //3.LiveDataの更新コールバックを受け取るリスナーの設定
        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newValue) {
                // 画面の更新
                TextView textView = view.findViewById(R.id.textview);
                textView.setText(newValue);
            }
        };
        model.getCurrentValue().observe(this, nameObserver);

        view.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //4.ExecutorServiceを使った非同期処理の実行
                ExecutorService executor = Executors.newSingleThreadExecutor();
                executor.submit(new Runnable() {
                    @Override
                    public void run() {
                        //10秒経過後、ワーカースレッドより、モデルの値を更新
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                        }
                        String anotherName = "3秒経過 " + new Date();
                        //他のスレッドから情報更新する場合、postValueで値をセットする必要がある
                        model.getCurrentValue().postValue(anotherName);
                    }
                });
            }
        });
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_first, container, false);
    }

}

LiveDataを使うことでObserverパターンを実現しています。
また、postValueを使うことで、スレッドを意識する必要がなくなります。
Handlerを使えば、同じことはできますが、スレッドの入れ替えを隠蔽することで、コードがわかりやすくなりますね(個人的な感覚)。
また、値の取り回しが複数になる場合、面倒なので、更新通知用のフィールドを設けるのもありかなと思います。

「2.JetPackのLiveDataを使う」は、ちょっとダサいですけど、MyViewModelに進捗状況を表す数字を持たせ、postValueすればできるかな。と思います。
・・・でもダサいですね。

2021年1月3日日曜日

[PHP]Windows × xampp × Visual Studio CodeでPHPをデバッグ(Step実行)する

どのプログラム言語でも、デバッグするには変数など内部データを見る必要があります。
変数を簡単に見るには、ステップ実行するのが一番の近道かなと思います。

今回、PHPの開発に携わる機会があり、xampp環境でステップ実行するための環境を作ったんですが、うまくいかない。。。。
何がうまくいかないか。というと「ブレークポイントを設定しても止まらない」です。


環境は、以下の通りです。
 ・PHP Version 8.0.0
 ・Xdebug 3.0.1
 ・Visual Studio Code 1.52.1
 ・PHP Debug 1.14.5(Visual Studio Code のデバッグ用プラグイン)

環境により違いはあると思いますが、この環境においての原因は以下の2点でした。
 ・Xdebug v3.0.0系より、php.iniに書く設定が変わった
 ・デバッグ用のポート番号が変わった

対策は以下の2つ。
 1.PHP.iniの設定
 2.lunch.jsonの設定


1.PHP.iniの設定
[XDebug]
xdebug.mode=debug
xdebug.start_with_request=yes
zend_extension = C:\xampp\php\ext\php_xdebug-3.0.1-8.0-vs16-x86_64.dll
うまくいっている場合、↓のURLで確認ができる。
http://localhost/dashboard/phpinfo.php
xdebugの「Step Debugger」が「enabled」になっていたらOK。

zend_extensionはバージョンによって異なる。コイツの導き出し方は、他のサイトを探してみてください。


2.lunch.jsonの設定
ポート番号が変わったらしい。その設定を合わせる。 9001→9003

{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    'version': '0.2.0',
    'configurations': [
    
        {
            'name': 'Listen for XDebug',
            'type': 'php',
            'request': 'launch',
            'port': 9003,
            'runtimeExecutable': 'C:\\xampp\\php\\php.exe'
        },
        {
            'name': 'Launch currently open script',
            'type': 'php',
            'request': 'launch',
            'stopOnEntry': true,
            'program': '${file}',
            'cwd': '${fileDirname}',
            'port': 9003,
            'runtimeExecutable': 'C:\\xampp\\php\\php.exe'
        }
    ]
}
設定の変更は、Visual Studio Codeのメニュー「実行(R)」→「構成を開く」で編集できます。

Lunch Currently open Scriptを選択し、F5でデバッグスタート。
ブレークポイントを設定しておくと、そこで止まるようになりました。