Android
Network
WiFi

(Android)Networkの通信状況をしっかり見る

More than 3 years have passed since last update.


Androidアプリの改善

接続中の通信回線を見て,

サーバから取ってくる画像のサイズを変えるようにしました.

今回は,そのために学んだ


  • オンライン,オフライン判定

  • Wi-Fi, Mobileネットワーク判定

  • ネットワーク状況の変化を動的に受け取るReceiver

についてのコードを載せます.


オンライン,オフライン判定

簡単に判定できます.


NetUtils.java

    public static boolean isOnline(Context context) {

ConnectivityManager connMgr = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
// You should always check isConnected(), since isConnected()
// handles cases like unstable network state.
return (networkInfo != null && networkInfo.isConnected());
}

ただ,Wifi, Mobileいずれのネットワークも見つからない場合 (機内モードなど) ,

connMgr.getActiveNetworkInfo()Nullを返すので気をつけてください.


Wi-Fi, Moblieネットワーク判定

こちらも簡単です.


NetUtils.java

    public static boolean isWifiConnected(Context context) {

ConnectivityManager connMgr = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected()
&& networkInfo.getType() == ConnectivityManager.TYPE_WIFI;
}


ネットワーク状況の変化を動的に受け取るReceiver

こちらはまず,BroadcastReceiverを継承したクラスを作り,

onReceive(context, intent)メソッドを次のようにオーバーライドします.


NetworkReceiver.java

    public interface OnNetworkStateChangedListener {

void changedToWifi();
void changedToMobile();
void changedToOffline();
}

  @Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager conn = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = conn.getActiveNetworkInfo();

if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
if(mCallback!=null) mCallback.changedToWifi();
Log.i(TAG, "Network state has changed to WIFI");
} else if (networkInfo != null) {
if(mCallback!=null) mCallback.changedToMobile();
Log.i(TAG, "Network state has changed to MOBILE");
} else {
if(mCallback!=null) mCallback.changedToOffline();
Log.i(TAG, "I have no idea...");
}
}


あとは,ネットワーク状況の変化を受け取りたいActivityなどで,

コールバックを受け取れるようにすれば完成です.

今回は,Callback インターフェースを介して,eventの受け渡しをします.

下のようにReceiverを登録することで,Wi-Fi -> Mobile回線のような変化を

Receiverが受け取れるようになります.


MainActivity.java

  @Override

public void onResume() {
super.onResume();
// Registers BroadcastReceiver to track network connection changes.
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
mReceiver = new NetworkReceiver(mListener);
registerReceiver(mReceiver, filter);
}

@Override
public void onPause() {
super.onPause();
if(mReceiver != null) {
unregisterReceiver(mReceiver);
}
}



おまけ

今回,行った変更はこんな感じです.

Before

リスト表示に使う画像は,Wi-Fiが使えない時を意識して,小さめの画像にしてました.

ListViewに渡すAdapterの中はこんな感じで,常に150x150の画像をリクエストしてました.


ImageAdapter.java

// always requests 150x150 image

ListItem item = getItem(position);
String url = item.generatePhotoURL("q"); // q : 150x150 image

ImageLoader.ImageListener listener =
ImageLoader.getImageListener(holder.imageView,
R.drawable.loading_default, R.drawable.ic_image_broken);
holder.imageView.setTag(mImageLoader.get(url, listener));


After

Wi-Fiにつながっているときは,大きめの画像を取ってくるようにしました.


ImageAdapter.java

// change image quality by checking network state

ListItem item = getItem(position);
String quality_flg = is_wifi_connected ? "z": "q"; // z : 640x640, q : 150x150
String url = item.generatePhotoURL(quality_flg);

ImageLoader.ImageListener listener =
ImageLoader.getImageListener(holder.imageView,
R.drawable.loading_default, R.drawable.ic_image_broken);
holder.imageView.setTag(mImageLoader.get(url, listener));


結果,Wi-Fi時のリストがきれいになりました.


参考文献

PerformingNetworkOperations | Android Developers