コンピュータクワガタ

かっぱのかっぱによるコンピュータ関連のサイトです

データ通信(3G)のオン/オフを切り替える

3Gのデータ通信を有効/無効にする設定を探していたが見つからないため、Android 2.3.4の「設定」アプリのソースを見てみた。
ソースは以下。
https://github.com/OESF/OHA-Android-2.3.4_r1.0/blob/master/packages/apps/Phone/src/com/android/phone/Settings.java

「データ通信を有効にする」ボタンを押した時の動作が、150行目から記述されている。それによると

ConnectivityManager#setMobileDataEnabled(boolean)

でデータ通信のオン/オフができるようであるが、そんなメソッドはない。というか少なくとも公開されているAPIにはない。

setMobileDataEnabledで色々検索してみると@hideがついた非公開APIということは確認できた。以下の427行目。
http://www.google.com/codesearch#uX1GffpyOZk/core/java/android/net/ConnectivityManager.java&q=android.net%20IConnectivityManager%20setMobileDataEnabled

非公開ながら、リフレクションで実装している人もいた。
http://stackoverflow.com/questions/4955141/android-public-method-setmobiledataenabled-in-connectivitymanager-not-available

このあたりを参考に、リフレクションのメソッドを作成した。このメソッドでデータ通信のオン/オフができる。あくまで非公開APIなので突然使えなくなるおそれはあるのでその点だけは注意が必要。

public void setMobileDataEnabled(boolean toBeEnabled) {
    ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);

    Class<?> clazz = null;
    try {
        clazz = Class.forName(cm.getClass().getName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        return;
    }
    Method method = null;
    try {
        Method[] available_methods = clazz.getDeclaredMethods();
        for (Method m : available_methods) {
            if (m.getName().contains("setMobileDataEnabled")) {
                method = m;
                break;
            }
        }
        method.invoke(cm, toBeEnabled);
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

ちなみに、以下のパーミッションが必要。

<uses-permission
    android:name="android.permission.CHANGE_NETWORK_STATE" />