如何在 Android 上以编程方式关闭 3G/数据?
Posted
技术标签:
【中文标题】如何在 Android 上以编程方式关闭 3G/数据?【英文标题】:How can i turn off 3G/Data programmatically on Android? 【发布时间】:2012-09-14 03:30:23 【问题描述】:不是 Wifi,而是 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 上打开了移动数据;但我们需要添加上一个答案建议的权限我还在使用 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_
android:layout_
tools:context=".Turn3GOnOff" >
<ToggleButton
android:id="@+id/toggleButton"
android:layout_
android:layout_
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="60dp"
android:textOn="3G on"
android:textOff="3G off"
android:text="ToggleButton" />
</RelativeLayout>
【讨论】:
以上是关于如何在 Android 上以编程方式关闭 3G/数据?的主要内容,如果未能解决你的问题,请参考以下文章