【Android】ネットワークの接続状況を判定するクラス『ConnectivityManager』を使う

アイキャッチ_APIAndroidアプリ開発

とあるお仕事で、アプリのオフライン時の処理を実装することがありました。

サバ缶
サバ缶

「ネットワークに繋がっていない場合、エラーダイアログを表示させる」みたいなやつですね。

実は、ネットワークの接続状況を判定するためのクラスがあるので、それを今回紹介したいと思います!

そもそも、どういう場面で使うの?

ネットワーク接続状況を判定する場面は以下の通りです。

利用場面
  • オフラインならエラーのダイアログを表示する
  • WiFi接続時のみダウンロードさせたいコンテンツがある

ゲームアプリなどでよく「WiFi接続時に〜…」とか表示されますね。

ネットワーク通信の種類について

スマホには、様々な種類のネットワーク接続方法があります。

WiFi、モバイル通信、Bluetoothなど……。

詳しく知りたい人は、下記のリンク先の後半部分をご参照ください。

『TYPE_』でページ内検索をすると見つかります。

Androidスマホの通信方法
タップすると拡大

ConnectivityManager を使ってみる

それでは、実際に実装していきましょう!

公式ドキュメントには、以下のように記載されています。

Android Developers公式より
  • ConnectivityManager
    • ネットワーク接続の状態に関するクエリに応答します。
    • また、ネットワーク接続が変更されたときにアプリに通知します。
  • NetworkInfo
    • 特定のタイプ(現在のところ、モバイル接続か Wi-Fi 接続)のネットワーク、インターフェースのステータスを示します。
    • 【注意】API29からデプリケート(非推奨)になっています。

公式ドキュメントの具体例を基に、処理を書いてみました。

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContentView(R.layout.activity_main)

  val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
  var isWiFiConnection: Boolean = false
  var isMobileConnection: Boolean = false

  connectivityManager.allNetworks.forEach { network ->
    connectivityManager.getNetworkInfo(network).apply {
      if (type == ConnectivityManager.TYPE_WIFI) {
        isWiFiConnection = isWiFiConnection or isConnected
      }
      if (type == ConnectivityManager.TYPE_MOBILE) {
        isMobileConnection = isMobileConnection or isConnected
      }
    }
  }
  android.util.Log.d("TEST", "WiFi: ${isWiFiConnection}, Mobile: ${isMobileConnection}")
}

おそらく、connectivityManagerあたりでエラーが起きると思います。

Manifestファイルにパーミッションを追加したら解決します。

uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"
サバ缶
サバ缶

applicationタグの上あたりに追記すればOKです👌

実装したあとのログ結果

ログで確認したところ、結果は以下のようになりました。

ログ結果
  • WiFi
    • 接続時:isWiFiConnection = true
    • 遮断時:isWiFiConnection = false
  • モバイル通信
    • 接続時:isMobileConnection = true
    • 遮断時:isMobileConnection = true

うーん。少し思っていた結果とは異なりましたね。

『or』で isConnected を判定しているからでしょうか?

もっと簡単に、オフラインかどうかを確認する

結果が想定と違いましたが、気を取り直して別の方法を試していきましょう!

fun isOnline(): Boolean {
  val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
  val networkInfo = connectivityManager.activeNetworkInfo
  return networkInfo?.isConnected == true
}

このメソッドを使って、戻り値を確認したところ、WiFiかモバイル通信がONになっている状態だと『true』が返ってきました!

getActiveNetworkInfo()は、検出された最初の接続済みネットワークをNetworkInfoインスタンスで返してくれます。

妥協したら、後から面倒臭くなる

しかしここで問題が…!

上記で使用したactiveNetworkInfoは、deprecated(非推奨)になっているんです。。。

非推奨のメソッドは、後々使えなくなってしまうので、対応せずに放置しておくとアプリがクラッシュする可能性が出てきます。

ということで、新しいOSに対応した処理の書き方は、下記の記事で(投げやり)

まとめ

怒るひと
怒るひと

てか、deprecated になるやつを
公式が紹介してるってどゆこと?!

サバ缶
サバ缶

た、確かに……。

タイトルとURLをコピーしました