Androidでモバイルネットワークが使えるかどうかを判定する方法の実装例.
Androidで電波圏外を判定する
拙作のAndroidアプリ
山旅ロガー
では,GPSで取得した移動中の位置を記録するのですが,それと同時に携帯電波の圏外かどうかを記録する機能があります.
# 余談ですが,記録した電波情報を共有できるサイトを公開しています.→
山の電波地図
この機能で行っている実装について書きます.
ソース
AndroidManifest.xmlに追加する権限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
※なお,6.0以降では今回の用途にREAD_PHONE_STATEはいらないらしく,maxSdkVersionを指定して
<uses-permission android:name="android.permission.READ_PHONE_STATE" android:maxSdkVersion="22" />
という書き方もありうるようです.(私は使ってませんが)
SignalWatcher.java
package
com.kamoland.signaltest;
import
android.content.Context;
import
android.net.ConnectivityManager;
import
android.net.NetworkInfo;
import
android.os.Build;
import
android.telephony.PhoneStateListener;
import
android.telephony.TelephonyManager;
public
class
SignalWatcher {
private
boolean
stateConnected;
public
boolean
isSignalOn(Context context) {
ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo network = null
;
for
(NetworkInfo ni: conMan.getAllNetworkInfo()) {
if
(ni.getType() == ConnectivityManager.TYPE_MOBILE) {
network = ni;
break
;
}
}
if
(network == null
) {
return
false
;
}
// Android 5.0未満では,圏外でisAvailable()がfalseになるので使える
if
(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return
network.isAvailable();
} else
{
if
(!network.isAvailable()) {
return
false
;
}
// Xperia Z5 Compact(Android 5.1.1)では,圏外でも
// TelephonyManager.DATA_DISCONNECTEDが発生しないのでこれが必要
if
(!network.isConnected()) {
return
false
;
}
if
(!stateConnected) {
return
false
;
}
return
true
;
}
}
public
void
start(Context context) {
if
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// Zenfone2 Laser(Android 5.0)では,
// 圏外でもnetwork.isConnected()がfalseにならないので必要
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(stateListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
}
}
private
PhoneStateListener stateListener = new
PhoneStateListener() {
@Override
public
void
onDataConnectionStateChanged(int
state) {
switch
(state) {
case
TelephonyManager.DATA_CONNECTED:
stateConnected = true
;
break
;
case
TelephonyManager.DATA_DISCONNECTED:
stateConnected = false
;
break
;
}
super
.onDataConnectionStateChanged(state);
}
};
public
void
stop(Context context) {
if
(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(stateListener, PhoneStateListener.LISTEN_NONE);
}
}
}
使い方
SignalWatcher signalWatcher = new
SignalWatcher();
signalWatcher.start(context);
・・・
// 必要なときに呼びだす
boolean
signalOn = signalWatcher.isSignalOn(context);
・・・
signalWatcher.stop(context);
全ての機種に対応している保証はありませんので,あしからず.
結局,3種類の方法を組み合わせているわけで,もっと簡単な方法があるかも知れません...
★注意
ASUSの機種では,画面オフ状態では上記の方法でも最新の状態を取得できないことが判明しています.
画面をオンにすれば,最新の状態を取得できます.
ASUSの機種では画面オンの状態でしか使えないという状況ですので,ご注意ください.
他にも同様の機種があるかも知れません.
参考