5G対応アプリをつくろうZ!Ⅱ

この投稿は、私が所属するKDDIテクノロジーで行っているアドベントカレンダーの9日目の記事となります。
モバイル通信の第5世代目の通信規格「5G」。対応エリアも広がり、5G端末を使っていれば、アンテナ横の「5G」のマークが点いていることも事も多くなりました。
しかし、まだまだ5Gは進化中です。
私の本日のアトレベントカレンダーでは、この「5GのアプリつくろうZ」の続きとして、前回紹介されてもらった機能をアプリ上でどのように実装するのか紹介させて頂きます。
# 前の記事
「5G対応アプリをつくろうZ!」
https://qiita.com/simdroid/items/4c755cac1357c6afe72c

# 5Gエクスペリエンス機能を使おう
## 前回からの続き
前号では5Gの特徴とともに、大容量通信を実現する際に、配慮すべき「5Gエクスベエンス機能」の紹介をさせてもらいました。

　1 5Gエリア判定
　2 5G通信速度の推定
　3 従量課金の判定

これらの判定や推定、従量期間判定を行う理由に対て紹介させてもらいました。
今回は具体的に、どのように設定するのかを紹介させて頂きます。なおこちらの資料は、過去KDDIテクノロジーが運営を行った「5Gエクスペリエンスハッカソン( https://japan-android-group.connpass.com/event/208114/presentation/ )」というイベントで、解説に使った資料をベースに執筆しています。

# 5Gエリア判定を使うには
## Androidの場合
### 動作条件
| 項目 | 必要なもの |
|:----|:----|
|API Level	| 30以上 |
|Device	| Android 11以降 |
|Permission	| READ_PHONE_STATE |

### 実装方法
* TelephonyManager.listen(LISTEN_DISPLAY_INFO_CHANGED)で監視を開始
* onDisplayInfoChanged() で通知される TelephonyDisplayInfo に対してgetOverrideNetworkInfo() で取得されるデータで判定

### アイコンとoverrideNetworkInfoの関係

|	|圏外|4G|5G|
|:--|:----|:----|:----|
|OVERRIDE_NETWORK_TYPE_NONE	|〇	|〇	|-|
|OVERRIDE_NETWORK_TYPE_LTE_CA|-|〇|	-|
|OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO|-|	-|	〇？|
|OVERRIDE_NETWORK_TYPE_NR_NSA|	-|	-|	〇|
|OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE|	-|	-|	〇？|

### onDisplayInfoChanged()の通知タイミング
* TelephonyManager.listen()をコールした直後
* overrideNetworkInfoの変化時（≒ステータスバーのアイコン変化時）

## iOSの場合
### 実装方法
serviceCurrentRadioAccessTechnology
CTServiceRadioAccessTechnologyDidChanfeNotification
を用いる

# 5G通信速度の推定を使うには
## Androidの場合
### 動作条件
| 項目 | 必要なもの |
|:----|:----|
|API Level	|30以上|
|Device	Android |11以降|
|Permission	|ACCESS_NETWORK_STATE|

### 実装方法
・ConnectivityManager.registerDefaultNetworkCallback() を使用してネットワーク コールバックに登録
・NetworkCallback の onCapabilitiesChanged() で通知される NetworkCapabilities に対して、以下を取得する
　・下り：getLinkDownstreamBandwidthKbps() 
　・上り：getLinkUpstreamBandwidthKbps() 

# 従量課金の判定を使うには
## Androidの場合
### 動作条件
| 項目 | 必要なもの |
|:----|:----|
|API Level|	30以上|
|Device	Android| 11以降、(Android 10の一部？)|
|Permission|	ACCESS_NETWORK_STATE|

### 実装方法
・ConnectivityManager.registerNetworkCallback() を使用してネットワークコールバックを登録
・NetworkCallback の onCapabilitiesChanged() で通知される NetworkCapabilities に対して、以下を取得
　・hasCapability(NET_CAPABILITY_NOT_METERED) 
　・hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)

### 判定結果

|接続ネットワーク|hasCapability(NET_CAPABILITY_NOT_METERED)	|hasCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)|
|:---|:---|:---|
|WiFi|	TRUE|	FALSE|
|4G|	FALSE|	FALSE|
|5G(従量制)|	FALSE|	FALSE|
|5G(定額制)|	FALSE|	TRUE|

### 備考
* NET_CAPABILITY_TEMPORARILY_NOT_METEREDの判定には以下が必要
　- 通信事業者とGoogleの連携 (加入者情報の連携のため)
　- GooglePlay開発者サービスの更新
* 現時点ではベータテスタープログラムに登録し、ベータ版の開発者サービスをインストールする必要あり

## iOSの場合
### 実装方法
isExpensiveを用いる

# 参考情報
## Android　5Gエクスペリエンス開発ページ　
### Google公式
https://developer.android.com/about/versions/11/features/5g
### Androidのサンプルアプリとソースコード(小野直人作)
https://github.com/na-ono/detect5gsample

### Googleのサンプルアプリ
https://play.google.com/store/apps/details?id=com.devrel.android.minwos
### Googleのサンプルソースコード(Kotlin)　
https://github.com/fstanis/miNWos

## iOS開発ページ
https://developer.apple.com/documentation/foundation/urlsessiontasktransactionmetrics/3240635-isexpensive

# 最後に(ちょっと宣伝)
株式会社KDDIテクノロジーでは、AndroidやiOSのアプリを中心に開発を行う仲閒を積極的に募集しています。ともに開発やPMの仕事をしてみませんか? 興味ある方は是非こちらの採用ページからご相談ください。お待ち申し上げています。
→　https://recruit.kddi-tech.com/