差分表示
- 最後の更新で追加された行はこのように表示します。
- 最後の更新で削除された行は
このように表示します。
Androidでモバイルネットワークが使えるかどうかを判定する方法の実装例.
//parent=Android
*Androidで電波圏外を判定する
拙作のAndroidアプリ
&link(山旅ロガー,https://play.google.com/store/apps/details?id=com.kamoland.ytlog)
では,GPSで取得した移動中の位置を記録するのですが,それと同時に携帯電波の圏外かどうかを記録する機能があります.
~
# 余談ですが,記録した電波情報を共有できるサイトを公開しています.→&link(山の電波地図,http://www.chizroid.info/denpa/);
この機能で行っている実装について書きます.
**ソース
<itle(AndroidManifest.xmlに追加する権限)
--(1,
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
--)
※なお,6.0以降では今回の用途にREAD_PHONE_STATEはいらないらしく,maxSdkVersionを指定して
--(2,
<uses-permission android:name="android.permission.READ_PHONE_STATE" android:maxSdkVersion="22" />
--)
という書き方もありうるようです.(私は使ってませんが)
-&link(Since Android 6.0 listening to the PhoneStateListener.LISTEN_DATA_CONNECTION_STATE changes seems to no longer require READ_PHONE_STATE permission - Stack Overflow,http://stackoverflow.com/questions/33433829/since-android-6-0-listening-to-the-phonestatelistener-listen-data-connection-sta);
<itle(SignalWatcher.java);
--(1,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);
}
}
}
--)
<itle(使い方);
--(1,java
SignalWatcher signalWatcher = new SignalWatcher();
signalWatcher.start(context);
・・・
// 必要なときに呼びだす
boolean signalOn = signalWatcher.isSignalOn(context);
・・・
signalWatcher.stop(context);
--)
全ての機種に対応している保証はありませんので,あしからず.
結局,3種類の方法を組み合わせているわけで,もっと簡単な方法があるかも知れません...
★注意~
ASUSの機種では,画面オフ状態では上記の方法でも最新の状態を取得できないことが判明しています.
画面をオンにすれば,最新の状態を取得できます.~
ASUSの機種では画面オンの状態でしか使えないという状況ですので,ご注意ください.
他にも同様の機種があるかも知れません.
**参考
-&link(Issue 87569 - android - Android 5: NetworkInfo.isAvailable is still true when Airplane Mode is turned-on - Android Open Source Project - Issue Tracker - Google Project Hosting,https://code.google.com/p/android/issues/detail?id=87569);