android 如何实现移动数据上网的开关?

问题描述

android 如何实现移动数据上网的开关?

android 如何实现移动数据上网的开关?之前百度了一下,找到几篇,但都说不行,今天再搜索,想试一试,竟都不见了!特来此求肋。谢谢

解决方案

感谢名位的回答,虽然没有用到,但也是学到了些东西的。本人已经找到了解决办法,也在此分享吧:
解决办法中使用到了ConnectivityManager类,但是在SDK中的ConnectivityManager类并没有提供setMobileDataEnable()、getMobileDataEnable()等方法。也看了ConnectivityManager类的源码,里面都是有这些方法的。弄了大半天,最终狠下心来,自己写个ConnectivityManager类,其中的方法和源ConnectivityManager类的方法一样,但都是空实现,编译成ConnectivityManager.class文件,然后替换android.jar包中的android.net.ConnectivityManager.class文件。然后在项目中,使用ConnectivityManager的setMobileDataEnable()方法来打开和关闭数据上网,使用getMobileDataEnable()方法获得当前连接状态,当然这需要android.permission.CHANGE_NETWORK_STATE和android.permission.ACCESS_NETWORK_STATE权限。
ConnectivityManager类如下:

    package android.net;

    import java.net.InetAddress;

    public class ConnectivityManager
    {

public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
    public static final String CONNECTIVITY_ACTION_IMMEDIATE = "android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE";
    public static final String EXTRA_NETWORK_INFO = "networkInfo";
    public static final String EXTRA_IS_FAILOVER = "isFailover";
    public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
    public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
    public static final String EXTRA_REASON = "reason";
    public static final String EXTRA_EXTRA_INFO = "extraInfo";
    public static final String EXTRA_INET_CONDITION = "inetCondition";
    public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
    public static final String INET_CONDITION_ACTION = "android.net.conn.INET_CONDITION_ACTION";
    public static final String ACTION_TETHER_STATE_CHANGED = "android.net.conn.TETHER_STATE_CHANGED";
    public static final String EXTRA_AVAILABLE_TETHER = "availableArray";
    public static final String EXTRA_ACTIVE_TETHER = "activeArray";
    public static final String EXTRA_ERRORED_TETHER = "erroredArray";
    public static final int TYPE_NONE = -1;
    public static final int TYPE_MOBILE = 0;
    public static final int TYPE_WIFI = 1;
    public static final int TYPE_MOBILE_MMS = 2;
    public static final int TYPE_MOBILE_SUPL = 3;
    public static final int TYPE_MOBILE_DUN = 4;
    public static final int TYPE_MOBILE_HIPRI = 5;
    public static final int TYPE_WIMAX = 6;
    public static final int TYPE_BLUETOOTH = 7;
    public static final int TYPE_DUMMY = 8;
    public static final int TYPE_ETHERNET = 9;
    public static final int TYPE_MOBILE_FOTA = 10;
    public static final int TYPE_MOBILE_IMS = 11;
    public static final int TYPE_MOBILE_CBS = 12;
    public static final int TYPE_WIFI_P2P = 13;
    public static final int MAX_RADIO_TYPE = TYPE_WIFI_P2P;
    public static final int MAX_NETWORK_TYPE = TYPE_WIFI_P2P;
    public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;

    public static boolean isNetworkTypeValid(int networkType)
    {
        return networkType >= 0 && networkType <= MAX_NETWORK_TYPE;
    }

    /** {@hide} */
    public static String getNetworkTypeName(int type)
    {
        return Integer.toString(type);
    }

    /** {@hide} */
    public static boolean isNetworkTypeMobile(int networkType)
    {
        return false;
    }

    public void setNetworkPreference(int preference)
    {
    }

    public int getNetworkPreference()
    {
        return 0;
    }

    class NetworkInfo
    {
    }

    public NetworkInfo getActiveNetworkInfo()
    {
        return null;
    }

    /** {@hide} */
    public NetworkInfo getActiveNetworkInfoForUid(int uid)
    {
        return null;
    }

    public NetworkInfo getNetworkInfo(int networkType)
    {
        return null;
    }

    public NetworkInfo[] getAllNetworkInfo()
    {
        return null;
    }

    /** {@hide} */
    public LinkProperties getActiveLinkProperties()
    {
        return null;
    }

    /** {@hide} */
    public LinkProperties getLinkProperties(int networkType)
    {
        return null;
    }

    /** {@hide} */
    public boolean setRadios(boolean turnOn)
    {
        return turnOn;
    }

    /** {@hide} */
    public boolean setRadio(int networkType, boolean turnOn)
    {
        return turnOn;
    }

    public int startUsingNetworkFeature(int networkType, String feature)
    {
        return networkType;
    }

    public int stopUsingNetworkFeature(int networkType, String feature)
    {
        return networkType;
    }

    public boolean requestRouteToHost(int networkType, int hostAddress)
    {
        return false;
    }

    public boolean requestRouteToHostAddress(int networkType,
            InetAddress hostAddress)
    {
        return false;
    }

    @Deprecated
    public boolean getBackgroundDataSetting()
    {
        return true;
    }

    @Deprecated
    public void setBackgroundDataSetting(boolean allowBackgroundData)
    {
    }

    public NetworkQuotaInfo getActiveNetworkQuotaInfo()
    {
        return null;

    }

    public boolean getMobileDataEnabled()
    {
        return false;
    }

    public void setMobileDataEnabled(boolean enabled)
    {
    }

    class Context
    {
    }

    public static ConnectivityManager from(Context context)
    {
        return new ConnectivityManager();
    }

    public String[] getTetherableIfaces()
    {
        return null;
    }

    public String[] getTetheredIfaces()
    {
        return null;
    }

    public String[] getTetheringErroredIfaces()
    {
        return null;
    }

    public int tether(String iface)
    {
        return 0;
    }

    public int untether(String iface)
    {
        return 0;
    }

    public boolean isTetheringSupported()
    {
        return false;
    }

    public String[] getTetherableUsbRegexs()
    {
        return null;
    }

    public String[] getTetherableWifiRegexs()
    {
        return null;
    }

    public String[] getTetherableBluetoothRegexs()
    {
        return null;
    }

    public int setUsbTethering(boolean enable)
    {
        return 0;
    }

    /** {@hide} */
    public static final int TETHER_ERROR_NO_ERROR = 0;
    /** {@hide} */
    public static final int TETHER_ERROR_UNKNOWN_IFACE = 1;
    /** {@hide} */
    public static final int TETHER_ERROR_SERVICE_UNAVAIL = 2;
    /** {@hide} */
    public static final int TETHER_ERROR_UNSUPPORTED = 3;
    /** {@hide} */
    public static final int TETHER_ERROR_UNAVAIL_IFACE = 4;
    /** {@hide} */
    public static final int TETHER_ERROR_MASTER_ERROR = 5;
    /** {@hide} */
    public static final int TETHER_ERROR_TETHER_IFACE_ERROR = 6;
    /** {@hide} */
    public static final int TETHER_ERROR_UNTETHER_IFACE_ERROR = 7;
    /** {@hide} */
    public static final int TETHER_ERROR_ENABLE_NAT_ERROR = 8;
    /** {@hide} */
    public static final int TETHER_ERROR_DISABLE_NAT_ERROR = 9;
    /** {@hide} */
    public static final int TETHER_ERROR_IFACE_CFG_ERROR = 10;

    public int getLastTetherError(String iface)
    {
        return 0;
    }

    public boolean requestNetworkTransitionWakelock(String forWhom)
    {
        return false;
    }

    public void reportInetCondition(int networkType, int percentage)
    {
    }

    class PointerProperties
    {
    }

    public void setGlobalProxy(PointerProperties p)
    {
    }

    public PointerProperties getGlobalProxy()
    {
        return null;
    }

    public PointerProperties getProxy()
    {
        return null;
    }

    public void setDataDependency(int networkType, boolean met)
    {
    }

    public boolean isNetworkSupported(int networkType)
    {
        return false;
    }

    public boolean isActiveNetworkMetered()
    {
        return false;
    }
}

解决方案二:

1、调用隐藏的方法可以在源代码中进行编译
2、利用反射

希望下面文章对你有帮助
http://blog.csdn.net/tibib/article/details/8469871

解决方案三:

用我这个方法绝对好使,适用于任何手机。不需要放到系统里编译,也不需要导入jar包。

public void setMobileDataStatus(Context context, boolean enabled)

{

ConnectivityManager conMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

         // ConnectivityManager类
       Class<?> conMgrClass = null;
        // ConnectivityManager类中的字段
       Field iConMgrField = null;
        // IConnectivityManager类的引用
         Object iConMgr = null;
        // IConnectivityManager类
         Class<?> iConMgrClass = null;
        // setMobileDataEnabled方法
         Method setMobileDataEnabledMethod = null;
        try {
             // 取得ConnectivityManager类
             conMgrClass = Class.forName(conMgr.getClass().getName());
             // 取得ConnectivityManager类中的对象Mservice
             iConMgrField = conMgrClass.getDeclaredField("mService");
             // 设置mService可访问
             iConMgrField.setAccessible(true);
             // 取得mService的实例化类IConnectivityManager
             iConMgr = iConMgrField.get(conMgr);
             // 取得IConnectivityManager类
             iConMgrClass = Class.forName(iConMgr.getClass().getName());
             // 取得IConnectivityManager类中的setMobileDataEnabled(boolean)方法
             setMobileDataEnabledMethod = iConMgrClass.getDeclaredMethod(
                     "setMobileDataEnabled", Boolean.TYPE);
             // 设置setMobileDataEnabled方法是否可访问
             setMobileDataEnabledMethod.setAccessible(true);
             // 调用setMobileDataEnabled方法
             setMobileDataEnabledMethod.invoke(iConMgr, enabled);
       } catch (ClassNotFoundException e) {
             e.printStackTrace();
       } catch (NoSuchFieldException e) {
            e.printStackTrace();
       } catch (SecurityException e) {
            e.printStackTrace();
       } catch (NoSuchMethodException e) {
             e.printStackTrace();
       } catch (IllegalArgumentException e) {
             e.printStackTrace();
       } catch (IllegalAccessException e) {
            e.printStackTrace();
       } catch (InvocationTargetException e) {
            e.printStackTrace();
       }
  }

解决方案四:

设置-》流量使用情况

我的是在这里能够开关
不过我不知道各个手机的情况一样不,我的系统是android4.1.1

不知道楼主是想用代码实现还是手机功能?我是按照手机功能回答的

解决方案五:

这个是一种方法,但是对有些手机可能无法实现,我的可以,你可以试一下
Java code

@SuppressWarnings("unchecked")
    public void openDataConnect() throws ClassNotFoundException,
            SecurityException, NoSuchMethodException, IllegalArgumentException,
            IllegalAccessException, InvocationTargetException {
        Method dataConnSwitchmethod;
        Class telephonyManagerClass;
        Object ITelephonyStub;
        Class ITelephonyClass;
        boolean isEnabled = false;

        TelephonyManager telephonyManager = (TelephonyManager) context.get()
                .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);
    }

解决方案六:

android APN的打开与关闭
由于Android对于APN的网络API没有公开,不过我们可以阅读源代码,然后进行数
据库操作,系统会自动监听数据库的变化,从而实现开启或者关闭APN。
大家可以研究一下frameworks/base/core/java/android/provider
/Telephony.java这个类,
比较重要的就是 URI 和数据库字段: content://telephony/carriers
字段可以在Telephony.java中找到。
其实原理很简单 :
1 、 当开启APN的时候,设置一个正确的移动或者联通的APN
2、 关闭的时候设置一个错误APN就会自动关闭网络
看代码:Activity:

Java代码

package cc.mdev.apn;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button; 

public class Main extends Activity { 

Uri uri = Uri.parse("content://telephony/carriers");
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button open= (Button) findViewById(R.id.open);
Button close= (Button) findViewById(R.id.close);
open.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openAPN();
}
});
close.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
closeAPN();
}
});
}
public  void openAPN(){
List<APN> list = getAPNList();
for (APN apn : list) {
ContentValues cv = new ContentValues();
cv.put("apn", APNMatchTools.matchAPN(apn.apn));
cv.put("type", APNMatchTools.matchAPN(apn.type));
getContentResolver().update(uri, cv, "_id=?", new String[]{apn.id});
}
}
public void closeAPN(){
List<APN> list = getAPNList();
for (APN apn : list) {
ContentValues cv = new ContentValues();
cv.put("apn", APNMatchTools.matchAPN(apn.apn)+"mdev");
cv.put("type", APNMatchTools.matchAPN(apn.type)+"mdev");
getContentResolver().update(uri, cv, "_id=?", new String[]{apn.id});
}
}
private List<APN> getAPNList(){
String tag = "Main.getAPNList()";
//current不为空表示可以使用的APN
String  projection[] = {"_id,apn,type,current"};
Cursor cr = this.getContentResolver().query(uri, projection, null, null, null);
List<APN> list = new ArrayList<APN>();
while(cr!=null && cr.moveToNext()){
Log.d(tag, cr.getString(cr.getColumnIndex("_id")) + "  " + cr.getString(cr.getColumnIndex("apn")) + "  " + cr.getString(cr.getColumnIndex("type"))+ "  " + cr.getString(cr.getColumnIndex("current")));
APN a = new APN();
a.id = cr.getString(cr.getColumnIndex("_id"));
a.apn = cr.getString(cr.getColumnIndex("apn"));
a.type = cr.getString(cr.getColumnIndex("type"));
list.add(a);
}
if(cr!=null)
cr.close();
return list;
}
public static class APN{
String id;
String apn;
String type;
}
}

APNMatchTools.java
Java代码

package cc.mdev.apn; 

public final class APNMatchTools {
public static class APNNet{ 

public static String CMWAP = "cmwap"; 

public static String CMNET = "cmnet";
//中国联通3GWAP设置        中国联通3G因特网设置        中国联通WAP设置        中国联通因特网设置
//3gwap                 3gnet                uniwap            uninet 

public static String GWAP_3 = "3gwap"; 

public static String GNET_3="3gnet"; 

public static String UNIWAP="uniwap"; 

public static String UNINET="uninet";
}
public static String matchAPN(String currentName) {
if("".equals(currentName) || null==currentName){
return "";
}
currentName = currentName.toLowerCase();
if(currentName.startsWith(APNNet.CMNET))
return APNNet.CMNET;
else if(currentName.startsWith(APNNet.CMWAP))
return APNNet.CMWAP;
else if(currentName.startsWith(APNNet.GNET_3))
return APNNet.GNET_3;
else if(currentName.startsWith(APNNet.GWAP_3))
return APNNet.GWAP_3;
else if(currentName.startsWith(APNNet.UNINET))
return APNNet.UNINET;
else if(currentName.startsWith(APNNet.UNIWAP))
return APNNet.UNIWAP;
else if(currentName.startsWith("default"))
return "default";
else return "";
// return currentName.substring(0, currentName.length() - SUFFIX.length());
}
}

最后不要忘记加上修改APN的权限:
Xml代码

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

经过测试在G1 上联通和移动卡均是成功的。

解决方案七:

frameworksbasepackagesSystemUIsrccomandroidsystemuistatusbartabletSettingsView.java路径下

public class SettingsView extends LinearLayout implements View.OnClickListener{
  //增加数据广播实例声明
  DataEnabledController mDataEnabled;
  ...

  //在该方法下增加~
  protected void onFinishInflate() {
  ...
  mDataEnabled = new DataEnabledController(context,
(CompoundButton)findViewById(R.id.dataEnable_checkbox));
  }

}

再在SystemUIres下相应的xml布局文件内加入
<LinearLayout
  android:id="@+id/dataEnable"
  style="@style/StatusBarPanelSettingsRow"
  >
  <ImageView
  android:id="@+id/dataEnable_icon"
  style="@style/StatusBarPanelSettingsIcon"
  android:src="@drawable/ic_sysbar_data_switcher"
  />
  <TextView
  android:id="@+id/dataEnable_label"
  style="@style/StatusBarPanelSettingsContents"
  android:text="@string/status_bar_settings_data_enabled"
  />
  <Switch
  android:id="@+id/dataEnable_checkbox"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center_vertical"
  android:layout_marginRight="5dp"
  />
  </LinearLayout>
  <View style="@style/StatusBarPanelSettingsPanelSeparator" />

最后在SystemUIres下加入相应资源图片和字符串即可~ 希望对你有所帮助~

解决方案八:

4.0 以后的 Android 不在提供普通应用程序对 APN(Access Point Name) 修改的权限,如果强制修改的话,会报安全异常直接挂掉的。除非有当前设备系统应用的签名,然后打包进你修改 APN 的应用里面。

2.x 的系统可以尝试一下以下代码,

public static boolean setNETMode()
{
    ContentResolver resolver = context.getContentResolver();
    Cursor cursor =
      resolver.query(Uri.parse("content://telephony/carriers"),
      new String[] { "_id" }, "apn like '%net' and current=1", null,
      null);

    if ((cursor != null) && (cursor.moveToNext()))
    {
      ContentValues values = new ContentValues();
      values.put("apn_id", cursor.getString(0));
      resolver.update(
        Uri.parse("content://telephony/carriers/preferapn"), values,
        null, null);

      return true;
    }

    return false;
}

解决方案九:

一般的移动网络开关都是通过篡改APN实现的(真正的开关没有直接对外的api):

如接入点名称类型一般是default,当关闭的时候修改为其他的值,打开时候修改为default.

解决方案十:

是哇,可以用反射来实现吧?

时间: 2024-09-12 12:28:22

android 如何实现移动数据上网的开关?的相关文章

Android中wifi与数据流量的切换监听详解

最近在做一个wifi和移动数据的监控功能,来来回回折腾了一阵子,这个模块的主要功能是监听整个APP的wifi与数据流量的切换,让用户使用专用流量,而不是用wifi,给一个弹窗,点击确认,自动切换数据流量,关闭wifi.我的思路是写一个静态广播,监听在广播里面进行监听,启用系统弹窗,点击确认,自动切换网络,这里面有一个坑就是弹窗会在广播中多次被调用,其实只调用了一次,但是实际上多次调用系统的弹窗会一个叠加一个,搞了好久,终于搞好了,原来是系统广播导致的叠加,详情看代码: 网络封装类Connecti

android-如何在Android spinner中设置数据?

问题描述 如何在Android spinner中设置数据? 我从spinner 中获得一个值,并把它储存在一个数据库中.但是在返回时,不能在Spinner设置Text. 如何在EditText中像设置其它功能一样设置这个功能? public class MainActivity_spinner extends Activity { Button save; Button show; public void onCreate(Bundle savedInstanceState) { super.o

数据保存-android 怎样保存这些数据好?

问题描述 android 怎样保存这些数据好? 123,"aaaaa" 232,"bbbbb" 3432,"dsfsdf" 2,"sdfsdf" 43,"sdfsdfde" 这是成对出现的值,赋给什么样的类型保存好? for(....){ int id=... String str=... //保存这些数据 } 解析刚刚的数据 ... 用什么样数据类型保存能更方便遍历输出显示呢 List?ArrayList

Android编程获取GPS数据的方法详解_Android

本文实例讲述了Android编程获取GPS数据的方法.分享给大家供大家参考,具体如下: GPS是Android系统中重要的组成部分,通过它可以衍生出众多的与位置相关的应用. Android的GPS有一个专门的管理类,称为LocationManager,所有的GPS定位服务都由其对象产生并进行控制. 首先需要明确的是,LocationManager类的对象获取并不是直接创建的,而是由系统提供的,具体来说,通过如下方法,为一个LocationManager对象建立一个对象引用: 复制代码 代码如下:

共享内存-android系统进程间共享数据的同步问题

问题描述 android系统进程间共享数据的同步问题 想在android系统层写两个可执行程序(main_a,main_b),使用ndk-build编译. main_a 用来录音,main_b通过进程件套通信方式从main_a中把录音数据接收过来保存成文件.对于android来说,能想到的进程间通信方式是mmap,(匿名管道不行:命名管道有长度限制:匿名共享内存貌似得不到相同的文件句柄,而且内部也是使用mmap实现的).现在能用mmap共享数据,但是两个进程之间读写数据无法做同步.(据我了解li

数据不显示-android ListView的item数据的显示问题

问题描述 android ListView的item数据的显示问题 获取到的应该显示的数据都可以打印出来,但是界面上只有时间显示了出来,其他数据都 没有显示出来,查看布局也没发现哪儿的问题,希望各位帮帮忙喽! item的数据未显示部分布局如下: android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/rellay0&

android移动终端网络数据包的解析

问题描述 android移动终端网络数据包的解析 Android移动终端网络数据监控系统的设计与实现:网络数据包的解析,主要包括在移动终端生成网络数据包,然后将网络数据包发送给服务器端进行解析并进行资源文件(图片.文本.视频等)统计,最后将结果返回移动终端并在界面上显示. 请问该怎样实现? 解决方案 http://blog.csdn.net/carterjin/article/details/7571915

android 同步-android端如何实现数据同步问题?求思路、方法

问题描述 android端如何实现数据同步问题?求思路.方法 目前在做pad应用,应用所有数据都用sqlit保存在本地了,然后有3种同步功能,分别是: 1.立即同步 2.自动同步 3.仅在wifi下同步 现在没有好的. ** 完整 ** 的思路,请教各位.目前,在下有以下疑惑 a.是否需要服务.通知之类的还是仅仅一个定时器就可以了还是定时器写在服务中 b.如何在同步过程中有较好的用户体验,如在同步时,用户可以操作,同步完提示用户刷新页面等 有没有相关案例呢? 解决方案 如果你不是非要使用自己的同

json 数据解析-android 这样的json 数据该怎么解析

问题描述 android 这样的json 数据该怎么解析 {requestStatus"": ""success""errorCode"": ""0""errorTip"": ""操作完成""activityMemberArray"": [ {editTribe"": [ {tribeId