前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android开发(12) 无线网络和GPRS连接

Android开发(12) 无线网络和GPRS连接

作者头像
张云飞Vir
发布2020-03-16 15:04:21
1.6K0
发布2020-03-16 15:04:21
举报
文章被收录于专栏:写代码和思考写代码和思考

概述

启用gprs连接?难道说不是自动就调用网络了么?是呀,android 会默认调用当前的活动的网络. 那么什么是活动的网络呢? 看如下代码:

代码语言:javascript
复制
  ConnectivityManager cm = (ConnectivityManager) m_context
  .getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();

使用服务方式获得连接管理器,然后获得当前的活动网络信息.那么这个网络信息都可能是什么呢? 我在说使用中发现,如果wifi打开的话,那么当前的活动网络指向wifi.如果未打开,那么指向默认的apn.

什么是APN?

看下来自百度百科的解释:APN(Access Point Name),即“接入点名称”,是您在通过手机上网时必须配置的一个参数,它决定了您的手机通过哪种接入方式来访问网络,用来标识GPRS的业务种类,目前分为两大类:CMWAP/UNIWAP/3GWAP(通过GPRS访问WAP业务)、CMNET/UNINET/3GNET(除了WAP以外的服务目前都用CMNET,比如连接因特网等)。<摘自:http://baike.baidu.com/view/668.htm>

简单来说: APN 就是一个连接的设置.通过apn可以设置一个拨号连接,通过该拨号连接可以连接到 "网络提供商" 的服务器,由网络 提供商为你提供接入互联网的服务.这个网络提供商,可能是中国移动,联通,电信.

那么这个活动网络的优先级别可能是: 1.如果wifi打开,则指向wif 2.指向一个默认的(活动的,或者'当前的')apn.

APN怎么设置?

一般是用户设置好的.如果你是中国移动的手机卡,那你就要设置 中国移动提供的apn地址.这个地址一般都是固定的,网上也都能搜索到.


那么切入正题,我们在开发软件的时候,有时候需要调用网络连接.可能我们已经写好一个程序,比如说.我们写一个发送EMAIL的程序, 该程序会接入互联网,将EMAIL发送出去.那么在我们的这个应用程序中,我们如何写代码调用当前的网络么?其实...

答案是: 什么都不用写? 吓,开玩笑是吧? 玩我的是吧? 怎么能不写? 我们在本文开头大概了解了,活动网络.实际上android或默认 通过 当前的活动的网络 来为应用程序提供网络的使用服务.也就是说你的 应用程序在调用网络时,会默认使用 android系统默认的活动网络连接.那么,我们如果开启了wifi正常,如果没开启wifi,那就是用默认的apn.实际上,你的应用程序可以仅仅做到这一步. 网络连接的方式交给用户自己去连接,使用者决定使用是wifi,或者自己切换apn.android系统提供了移动网络的设置功能。

问题是: 这样真的行么? 我们看看实际使用环境会出现的问题,apn有很多中,可能是 中国移动的wmwap,wmnet,3g,联通的,电信的等. 由于网络运行商不同,提供的apn接入方式也不同..那可咋办?如果我是移动用户,我的apn指向wap方式,而我的应用程序是需要wmnet方式的.那我的程序就不能用了,必须让用户手动切换APN才行,而用户自己可能根本不懂apn(也可能懂,但很麻烦).

我的解决方案:

1.先获得当前活动的网络,尝试连接,如果可用(通畅),那么就用当前的. 2.如果不可能,活动默认的apn,再次尝试连接,如果通畅,则用当前的. 3.遍历apn列表,尝试连接,如果可能,则用.

也就是.尝试多个方式,直到找到一个可以用的为止.方法很笨,但是能解决问题.

APN相关的操作

android提供了contentProvider来提供apn的数据.我们直接操作这个就行了.切换apn时,使用content://telephony/carriers/preferapn, 更改这个内容就行了. 如果遍历apn? 数据存储在 content://telephony/carriers.同样用contentProvider来操作数据. 更多的操作数据的和contentProvider的使用,请阅读开发文档和google

贴出我的代码.我写了两个类,一个操作apn的,一个用于多次尝试连接网络的类.使用多次尝试连接 http://www.baidu.com/ 来确定是否连接到互联网.

代码语言:javascript
复制
  package surveySys.Core;
    
    import java.util.ArrayList;
    import java.util.List;
    import android.content.BroadcastReceiver;
    import android.content.ContentResolver;
    import android.content.ContentValues;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.database.Cursor;
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import android.net.Uri;
    import android.util.Log;
    
    public class APNHelper {
     public static final Uri CURRENT_APN_URI = Uri
       .parse("content://telephony/carriers/preferapn");
    
     public static final Uri APN_URI = Uri.parse("content://telephony/carriers");
    
     private Context m_context;
     private ContentResolver m_ContentResolver;
    
     public APNHelper(Context ctx) {
      super();
      if (ctx == null) {
       throw new NullPointerException("m_context");
      }
      m_context = ctx;
      m_ContentResolver = m_context.getContentResolver();
     }
    
     /*
      * 获得当前的apn编号
      */
     public String getCurrentApnId() {
      Cursor cur = null;
      try {
       cur = m_ContentResolver.query(CURRENT_APN_URI, null, null, null,
         null);
       if (cur != null && cur.moveToFirst()) {
        String apnID = cur.getString(cur.getColumnIndex("_id"));
        cur.close();
        return apnID;
       }
       return null;
      } catch (Exception e) {
       e.printStackTrace();
       return null;
      } finally {
       if (cur != null) {
        cur.close();
       }
      }
    
     }
    
     /*
      * 获得当前的apn
      */
     public APN getCurrentAPN() {
      List<APN> lst = getApnList();
      String id = getCurrentApnId();
      APN tmp = null;
      for (APN apn : lst) {
       if (apn._id.equals(id)) {
        tmp = apn;
        break;
       }
      }
      return tmp;
     }
    
     /*
      * 设置当前的apn
      */
     public boolean setCurrentAPN(String apnId) {
      try {
       ContentValues values = new ContentValues();
       values.put("apn_id", apnId);
       m_ContentResolver.update(CURRENT_APN_URI, values, null, null);
    
       return true;
      } catch (Exception e) {
       e.printStackTrace();
       return false;
      }
     }
    
     /*
      * 获得apn列表
      */
     public List<APN> getApnList() {
      return query(null);
     }
    
     /*
      * 获得有效的apn列表
      */
     public List<APN> getValidApnList() {
      return query("current=1");
     }
    
     public class APN {
      public String name;
      public String numeric;
      public String _id;
      public String mcc;
      public String mnc;
      public String apn;
      public String user;
      public String server;
      public String password;
      public String proxy;
      public String port;
      public String mmsproxy;
      public String mmsport;
      public String mmsc;
      public String authtype;
      public String type;
      public String current;
    
      public APN(String name, String numeric, String id, String mcc,
        String mnc, String apn, String user, String server,
        String password, String proxy, String port, String mmsproxy,
        String mmsport, String mmsc, String authtype, String type,
        String current) {
       super();
       this.name = name;
       this.numeric = numeric;
       _id = id;
       this.mcc = mcc;
       this.mnc = mnc;
       this.apn = apn;
       this.user = user;
       this.server = server;
       this.password = password;
       this.proxy = proxy;
       this.port = port;
       this.mmsproxy = mmsproxy;
       this.mmsport = mmsport;
       this.mmsc = mmsc;
       this.authtype = authtype;
       this.type = type;
       this.current = current;
      }
    
      public APN() {
       super();
      }
    
      public String toString() {
    
       return String
         .format(
           "name=%s,numeric=%s,_id=%s,mcc=%s,mnc=%s,apn=%s,user=%s,server=%s,password=%s,proxy=%s,port=%s,mmsproxy=%s,mmsport=%s,mmsc=%s, authtype=%s,type=%s,current=%s,",
           name, this.numeric, _id, mcc, mnc, apn, user,
           server, password, proxy, port, mmsproxy, mmsport,
           mmsc, authtype, type, current);
      }
     }
    
     /*
      * 查找
      */
     public List<APN> query(String query) {
      List<APN> lst = new ArrayList<APN>();
      Cursor cur = null;
      try {
       cur = m_ContentResolver.query(APN_URI, null, query, null, null);
       while (cur != null && cur.moveToNext()) {
        APN apn = new APN();
        apn.name = cur.getString(cur.getColumnIndex("name"));
        apn.numeric = cur.getString(cur.getColumnIndex("numeric"));
        apn._id = cur.getString(cur.getColumnIndex("_id"));
        apn.mcc = cur.getString(cur.getColumnIndex("mcc"));
        apn.mnc = cur.getString(cur.getColumnIndex("mnc"));
        apn.apn = cur.getString(cur.getColumnIndex("apn"));
        apn.user = cur.getString(cur.getColumnIndex("user"));
        apn.server = cur.getString(cur.getColumnIndex("server"));
        apn.password = cur.getString(cur.getColumnIndex("password"));
        apn.proxy = cur.getString(cur.getColumnIndex("proxy"));
        apn.port = cur.getString(cur.getColumnIndex("port"));
    
        apn.mmsproxy = cur.getString(cur.getColumnIndex("mmsproxy"));
        apn.mmsport = cur.getString(cur.getColumnIndex("mmsport"));
        apn.mmsc = cur.getString(cur.getColumnIndex("mmsc"));
        apn.authtype = cur.getString(cur.getColumnIndex("authtype"));
        apn.type = cur.getString(cur.getColumnIndex("type"));
        apn.current = cur.getString(cur.getColumnIndex("current"));
        lst.add(apn);
       }
       return lst;
      } catch (Exception e) {
       e.printStackTrace();
       return null;
      } finally {
       if (cur != null) {
        cur.close();
       }
      }
     }
    
    }

代码:

代码语言:javascript
复制
    package surveySys.Core;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.List;
    
    import surveySys.Core.APNHelper.APN;
    import surveySys.Dev.TestModule.ActTest;
    
    import android.content.Context;
    import android.content.Intent;
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import android.net.NetworkInfo.State;
    import android.provider.Settings;
    
    public class NetHelper {
    
     private Context m_context;
     // private static final String URLNameForTry = "http://www.google.com/";
    
     public String URL_ForTry = "http://www.baidu.com/";
    
     public NetHelper(Context context) {
      super();
      if (context == null) {
       throw new NullPointerException("context");
      }
      m_context = context;
     }
    
     private boolean open(String urlForTry) {
      
      this.URL_ForTry = urlForTry;
      if (checkNetworkState(m_context)) {
       if (tryGetURL(m_context, urlForTry)) {
        return true;
       }
      }
      // 判断网络是否可用,不可用,尝试启用 gprs APN
      if (trySwitchToValidApn(m_context, urlForTry)) {
       return true;
      }
      return false;
     }
    
     public static boolean TryConnect(Context ctx, String urlForTry) {
      if (ctx == null) {
       throw new NullPointerException("Context");
      }
      if(!urlForTry.startsWith("http://"))
      {
       throw new IllegalArgumentException("测试使用的网址参数参数必须以http://开头");
      }
      NetHelper scope = null;
      scope = new NetHelper(ctx);
      return scope.open(urlForTry);
     }
    
     /*
      * 无线网络配置界面
      */
     public static void OpenActivityWIRELESS_SETTINGS(Context ctx) {
      // startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
      // //进入手机中的wifi网络设置界面
      ctx.startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));// 进入无线网络配置界面
     }
    
     /*
      * 进入手机中的wifi网络设置界面
      */
     public static void OpenActivityWIFI_SETTINGS(Context ctx) {
      ctx.startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
     }
    
     /*
      * 检测网络设置
      */
     private boolean checkNetworkState(Context context) {
    
      ConnectivityManager conMan = (ConnectivityManager) context
        .getSystemService(Context.CONNECTIVITY_SERVICE);
    
      NetworkInfo[] infoArray = conMan.getAllNetworkInfo();
      for (int i = 0; i < infoArray.length; i++) {
       NetworkInfo var = infoArray[i];
       System.out.println(String.format("%s", var));
      }
    
      // mobile 3G Data Network
      State mobile = conMan.getNetworkInfo(ConnectivityManager.TYPE_MOBILE)
        .getState();
    
      State wifi = conMan.getNetworkInfo(ConnectivityManager.TYPE_WIFI)
        .getState();
    
      if (wifi == State.CONNECTED || wifi == State.CONNECTING) {
       return true;
      }
    
      // 如果3G网络和wifi网络都未连接,且不是处于正在连接状态 则进入Network Setting界面 由用户配置网络连接
      if (mobile == State.CONNECTED || mobile == State.CONNECTING) {
       return true;
      }
    
      return false;
     }
    
     public static String getCurrentNetInfo(Context ctx) {
      ConnectivityManager cm = (ConnectivityManager) ctx
        .getSystemService(Context.CONNECTIVITY_SERVICE);
      NetworkInfo info = cm.getActiveNetworkInfo();
      String str = "无";
      if (info != null) {
    
       str = info.getState().name();
      }
      return String.format("%s,%s,%s", info.getTypeName(), info
        .getExtraInfo(), info.getState());
     }
    
     /*
      * 超时时间10秒
      */
     public boolean tryGetURL(Context ctx, String urlStr) {
      try {
       URL url = new URL(urlStr);
       HttpURLConnection urlConn = (HttpURLConnection) url
         .openConnection();
    
       // 使用HttpURLConnection打开连接
       HttpURLConnection urlConn1 = (HttpURLConnection) url
         .openConnection();
       // 得到读取的内容(流)
    
       InputStreamReader in = new InputStreamReader(urlConn
         .getInputStream());
       // 为输出创建BufferedReader
    
       String resultData = "";
       BufferedReader buffer = new BufferedReader(in);
       String inputLine = null;
       // 使用循环来读取获得的数据
       while (((inputLine = buffer.readLine()) != null)) {
        // 我们在每一行后面加上一个"\n"来换行
        resultData += inputLine + "\n";
       }
       // 关闭InputStreamReader
       in.close();
       // 关闭http连接
       urlConn.disconnect();
    
       return resultData != null;
      } catch (Exception e) {
       e.printStackTrace();
       String str = e.getMessage();
       return false;
      }
     }
    
     private boolean trySwitchToValidApn(Context context, String urlForTry) {
      try {
       APNHelper helper = new APNHelper(context);
       APN currentApn = helper.getCurrentAPN();
       boolean isConnectied = false;
       if (currentApn != null) {
        isConnectied = tryGetURL(context, urlForTry);
        if (isConnectied) {
         return true;
        }
       }
       List<APN> lst = helper.getValidApnList();
       for (APN apnTemp : lst) {
        if (apnTemp == null) {
         continue;
        }
        if (currentApn != null) {
         if (apnTemp._id.equals(currentApn._id)) {
          continue;
         }
        }
        helper.setCurrentAPN(apnTemp._id);
        try {
         Thread.sleep(11000);
        } catch (Exception e) {
        }
    
        ConnectivityManager cm = (ConnectivityManager) m_context
          .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = cm.getActiveNetworkInfo();
        String str = "无";
        if (info != null) {
         int i = 0;
         while (info.getState() != State.CONNECTED) {
          try {
           Thread.sleep(1000);
          } catch (Exception e) {
          }
          if (i++ > 3) {
           break;
          }
         }
        }
        isConnectied = tryGetURL(context, urlForTry);
        String st1 = String.format("apn=%s,type=%s,canConnected=%s",
          apnTemp.apn, apnTemp.type, isConnectied);
        System.out.println(st1);
        if (isConnectied) {
         return true;
        }
       }
       return false;
      } catch (Exception e) {
       e.printStackTrace();
       return false;
      }
     }
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 什么是APN?
    • APN怎么设置?
      • 我的解决方案:
        • APN相关的操作
        相关产品与服务
        数据保险箱
        数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档