どうもこんばんわ。
Chromeくんがたまによく固まるんだけどどうした?
本題
Android 12からローカルIPアドレスを取得する際にWifiManager
を利用するほうが非推奨になり、
ConnectivityManager
を使うのが正規ルートになったみたいなのでメモ
公式リファレンス
https://developer.android.com/reference/android/net/ConnectivityManager#getLinkProperties(android.net.Network)
https://developer.android.com/reference/kotlin/android/net/wifi/WifiManager#getConnectionInfo()
権限
AndroidManifest.xml
にandroid.permission.ACCESS_NETWORK_STATE
を追加します。
DANGERレベルじゃないので自動で付与されます。
レイアウト
適当にTextViewを置いておけばいいと思います(idはactivity_main_text_view
)
同期的に取得
一回だけ取得する際はどんな難しくないです。ただしネットワークの変更があった際に対応できません。
LinkProperties#getLinkAddresses() メソッド
どうやらこれ、IPv6アドレス(16進数の:
区切りのやつ)とIPv4アドレス(10進数で.
区切りのやつ)が一緒の配列に入ってるみたいなので、
配列の中からIPアドレスに192
が含まれているものを探してます。
該当のコード
非同期的に取得する
コードが複雑になる代償にネットワーク変更の検知に対応できます。
ライブラリ
app/build.gradle
にコルーチンとライフサイクルのライブラリを入れます。
コールバックをいい感じに扱いたい!
Kotlin
のコルーチンにある、Flow
の一種、callbackFlow
がいい感じに扱ってくれます。
これを使うと、コールバック形式のコードをFlowに変換してくれます。さらに、コルーチンが終了した際の後始末まで一つの関数で完結するのでマジ便利。
FlowでIPアドレスを送る関数
lifecycleScope
を利用することで、Activityのライフサイクルに合わせてコルーチンを終了してくれます。
コルーチンが終了すると、callbackFlow
内のawaitClose
へ進み後始末をしてくれます。
以上です。
お疲れさまでした
おわりに
ソースコード置いておきます
https://github.com/takusan23/Android12GetIPAddress