Androidアプリの改善
接続中の通信回線を見て,
サーバから取ってくる画像のサイズを変えるようにしました.
今回は,そのために学んだ
- オンライン,オフライン判定
- Wi-Fi, Mobileネットワーク判定
- ネットワーク状況の変化を動的に受け取るReceiver
についてのコードを載せます.
オンライン,オフライン判定
簡単に判定できます.
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ネットワーク判定
こちらも簡単です.
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)
メソッドを次のようにオーバーライドします.
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が受け取れるようになります.
@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の画像をリクエストしてました.
// 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につながっているときは,大きめの画像を取ってくるようにしました.
// 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時のリストがきれいになりました.