usniyo
usniyo
2012-10-09 06:23
采纳率: 82.6%
浏览 30.5k
已结题

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

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

  • 点赞
  • 收藏

10条回答 默认 最新

  • usniyo
    usniyo 2012-10-09 15:25
    已采纳

    感谢名位的回答,虽然没有用到,但也是学到了些东西的。本人已经找到了解决办法,也在此分享吧:
    解决办法中使用到了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;
        }
    }
    
    点赞 评论
  • yizhenbeifeng
    yizhenbeifeng 2012-10-09 06:34

    设置-》流量使用情况

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

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

    点赞 评论
  • niangzhi
    niangzhi 2012-10-09 06:45

    这个是一种方法,但是对有些手机可能无法实现,我的可以,你可以试一下
    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);
        }
    
    点赞 评论
  • liangchichexin
    liangchichexin 2012-10-09 06:57

    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 上联通和移动卡均是成功的。

    点赞 评论
  • Sueyexin
    Sueyexin 2012-10-09 07:04

    frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\tablet\SettingsView.java路径下

    public class SettingsView extends LinearLayout implements View.OnClickListener{
      //增加数据广播实例声明
      DataEnabledController mDataEnabled;
      ...
    
      //在该方法下增加~
      protected void onFinishInflate() {
      ...
      mDataEnabled = new DataEnabledController(context,
    (CompoundButton)findViewById(R.id.dataEnable_checkbox));
      }
    
    }
    
    
    再在SystemUI\res下相应的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" />
    

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

    点赞 评论
  • Baby_Bonnie
    Baby_Bonnie 2012-11-20 01:50

    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;
    }
    
    点赞 评论
  • yongyong_21
    yongyong_21 2012-11-20 03:05

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

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

    点赞 评论
  • HuiGeZhang
    HuiGeZhang 2013-01-10 09:14

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

    点赞 评论
  • Tibib
    pobi 2013-01-11 05:37

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

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

    点赞 评论
  • liuxiang7831223
    Eleanor丶默默 2014-01-09 04:09

    用我这个方法绝对好使,适用于任何手机。不需要放到系统里编译,也不需要导入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();  
           }  
      }  
    
    点赞 评论

相关推荐