【问题标题】:How can i turn off 3G/Data programmatically on Android?如何在 Android 上以编程方式关闭 3G/数据?
【发布时间】:2012-09-14 03:30:23
【问题描述】:

如何在 Android 上以编程方式关闭 3G/数据?

不是 Wifi,而是 3G/数据。

【问题讨论】:

  • 如果它是重复的,我不会感到惊讶,但不确定为什么会有投票结束这个不是一个真正的问题。

标签: android 3g


【解决方案1】:

没有官方的方法可以做到这一点。但是,它可以通过反射非官方实现。

对于 Android 2.3 及更高版本:

private void setMobileDataEnabled(Context context, boolean enabled) {
    final ConnectivityManager conman = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    final Class conmanClass = Class.forName(conman.getClass().getName());
    final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
    iConnectivityManagerField.setAccessible(true);
    final Object iConnectivityManager = iConnectivityManagerField.get(conman);
    final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
    final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
    setMobileDataEnabledMethod.setAccessible(true);

    setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
}

这还需要以下权限。

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

适用于 Android 2.2 及以下版本:

Method dataConnSwitchmethod;
Class telephonyManagerClass;
Object ITelephonyStub;
Class ITelephonyClass;

TelephonyManager telephonyManager = (TelephonyManager) context
        .getSystemService(Context.TELEPHONY_SERVICE);

if(telephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED){
    isEnabled = true;
}else{
    isEnabled = false;  
}   

telephonyManagerClass = Class.forName(telephonyManager.getClass().getName());
Method getITelephonyMethod = telephonyManagerClass.getDeclaredMethod("getITelephony");
getITelephonyMethod.setAccessible(true);
ITelephonyStub = getITelephonyMethod.invoke(telephonyManager);
ITelephonyClass = Class.forName(ITelephonyStub.getClass().getName());

if (isEnabled) {
    dataConnSwitchmethod = ITelephonyClass
            .getDeclaredMethod("disableDataConnectivity");
} else {
    dataConnSwitchmethod = ITelephonyClass
            .getDeclaredMethod("enableDataConnectivity");   
}
dataConnSwitchmethod.setAccessible(true);
dataConnSwitchmethod.invoke(ITelephonyStub);

这需要以下权限:

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

请注意,这两个都是非官方的,可能不再有效。由于 2.2 及以下的方法在 2.3 上发生了故障,因此不需要再证明这种事情会被破坏。

【讨论】:

  • 嘿 Raghav,你能告诉我哪些包导入到 2.3 的项目中吗?当我导入 java.lang.reflect.Method;我遇到了一些错误。
  • 我可以将您的代码用作私有 void setMobileDataEnabled(boolean enabled) { Context context ; // ... } ?换句话说,你为什么选择使用 Context 作为参数?
  • @gcc 这样的方法通常进入实用程序类,我们需要一个 Context 才能获取 SystemServices 等。但是,如果您将其直接放在 Activity 或 Service 中,则可以删除上下文。
  • 如果我在 Activity 类的顶部写了Context context;。然后,我调用了你的函数。是否按预期运行?或者,我应该初始化或分配上下文吗?无论如何,谢谢
  • 你应该添加 context = getApplicationContext(); 到你的 onCreate() 以便能够使用它。
【解决方案2】:

try/catch块包围代码

public void mobiledataenable(boolean enabled) {

try { 
        final ConnectivityManager conman = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        final Class<?> conmanClass = Class.forName(conman.getClass().getName());
        final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
        iConnectivityManagerField.setAccessible(true);
        final Object iConnectivityManager = iConnectivityManagerField.get(conman);
        final Class<?> iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
        final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
        setMobileDataEnabledMethod.setAccessible(true);
        setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }     
}

在 Manifest 中,添加以下权限:

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

【讨论】:

    【解决方案3】:
     public void onClick(View view){
            ConnectivityManager dataManager;
            dataManager  = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
            Method dataMtd = null;
            try {
                dataMtd = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", boolean.class);
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            dataMtd.setAccessible(true);
            try {
                dataMtd.invoke(dataManager, true);
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }   
        }
    

    【讨论】:

    • +1,它确实在 Android 4.3 上打开了移动数据;但我们需要添加上一个答案建议的权限
    • 这种方法不再适用于 Android 4.2.2 及更高版本,因为 android.permission.MODIFY_PHONE_STATE 现在是一个受保护的权限,它只被授予到系统应用程序。
    【解决方案4】:

    我还在使用 2.1,所以这个解决方案适合我。

    但您还需要包含 MODIFY_PHONE_STATE 权限。

    完整代码(带有工具按钮)2.1:

    package com.rivaldo.turn3gonoff;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.content.Context;
    import android.telephony.TelephonyManager;
    import android.view.Menu;
    import android.widget.CompoundButton;
    import android.widget.ToggleButton;
    
    public class Turn3GOnOff extends Activity {
    
    Method dataConnSwitchmethod_ON;
    Method dataConnSwitchmethod_OFF;
    Class telephonyManagerClass;
    Object ITelephonyStub;
    Class ITelephonyClass;
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_turn3_gon_off);
    
        GetDataConnectionAPI();
    
        ToggleButton toggle = (ToggleButton) findViewById(R.id.toggleButton);
        toggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    turn3GOn();
                } else {
                    turn3GOff();
                }
            }
        });
    
    }
    
    private void GetDataConnectionAPI() {
        this.getApplicationContext();
        TelephonyManager telephonyManager = 
                        (TelephonyManager) this.getApplicationContext().
                                                  getSystemService(Context.TELEPHONY_SERVICE);
    
        try {
            telephonyManagerClass = Class.forName(telephonyManager.getClass().getName());
            Method getITelephonyMethod = telephonyManagerClass.getDeclaredMethod("getITelephony");
            getITelephonyMethod.setAccessible(true);
            ITelephonyStub = getITelephonyMethod.invoke(telephonyManager);
            ITelephonyClass = Class.forName(ITelephonyStub.getClass().getName());
    
            dataConnSwitchmethod_OFF = 
                            ITelephonyClass.getDeclaredMethod("disableDataConnectivity");
            dataConnSwitchmethod_ON = ITelephonyClass.getDeclaredMethod("enableDataConnectivity");   
        } catch (Exception e) { // ugly but works for me
            e.printStackTrace();
        }
    }
    private void turn3GOn() {
        dataConnSwitchmethod_ON.setAccessible(true);
        try {
            dataConnSwitchmethod_ON.invoke(ITelephonyStub);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    
    private void turn3GOff() {
        dataConnSwitchmethod_OFF.setAccessible(true);
        try {
            dataConnSwitchmethod_OFF.invoke(ITelephonyStub);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    
    }
    

    Manifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.rivaldo.turn3gonoff"
    android:versionCode="1"
    android:versionName="1.0" >
    
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
    <uses-sdk
        android:minSdkVersion="7"
        android:targetSdkVersion="7" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.rivaldo.turn3gonoff.Turn3GOnOff"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    
    
    </application>
    </manifest>
    

    activity_turn3_gon_off.xml

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    tools:context=".Turn3GOnOff" >
    
    <ToggleButton
        android:id="@+id/toggleButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="60dp"
        android:textOn="3G on"
        android:textOff="3G off"
        android:text="ToggleButton" />
    
    </RelativeLayout>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-16
      • 1970-01-01
      • 2014-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-14
      相关资源
      最近更新 更多