Android通过APN进行网络连接

简介:

APN(Access Point Name),即“接入点名称”,用来标识GPRS的业务种类,目前分为两大类:CMWAP(通过GPRS访问WAP业务)、CMNET(除了WAP以外的服务目前都用CMNET,比如连接因特网等)。你 在通过手机上网时必须配置的一个参数,它决定了你的手机通过哪种接入方式来访问网络。有的中国移动的业务需要走CMWAP接入点才能够连接网络的,在做这类应用的时候,不可避免地需要判断当前APN, 切换APN,以及成功连接到网络后连接到服务器。

由于Android对于APN的网络API没有公开,不过可以通过对数据库操作,系统会自动监听数据库的变化,从而实现开启或者关闭APN。

首先要声明相关的Uri:

 
  1. Java 代码复制内容到剪贴板  
  2.       
  3. Uri uri = Uri.parse("content://telephony/carriers");        
  4. public static final Uri PREFERRED_APN_URI = Uri.parse("content://telephony/carriers/preferapn");    

判断是否存在可用的网络连接:

 

 
  1. Java 代码复制内容到剪贴板  
  2.       
  3. /**       
  4.      * 判断是否有可用的wifi网络       
  5.      *        
  6.      * @return       
  7.      */        
  8.     public boolean isWIFIAvailable() {        
  9.         for (int i = 0; i < 5; i++) {        
  10.             ConnectivityManager cwjManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);        
  11.             NetworkInfo wifiInfo = cwjManager.getActiveNetworkInfo();        
  12.             if (wifiInfo == null) {        
  13.                 try {        
  14.                     Thread.sleep(1000);        
  15.                 } catch (InterruptedException e) {        
  16.                     e.printStackTrace();        
  17.                 }        
  18.                 continue;        
  19.             } else {        
  20.                 if (wifiInfo.getType() == ConnectivityManager.TYPE_WIFI)        
  21.                     return true;        
  22.             }        
  23.         }        
  24.         return false;        
  25.     }        
  26.         
  27.     /**       
  28.      * 判断是否有可用的网络连接       
  29.      * @return       
  30.      */        
  31.     public boolean isNetWorkAvailable() {        
  32.         for (int i = 0; i < 5; i++) {        
  33.             ConnectivityManager cwjManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);        
  34.             NetworkInfo netInfo = cwjManager.getActiveNetworkInfo();        
  35.             if (netInfo == null) {        
  36.                 try {        
  37.                     Thread.sleep(1000);        
  38.                 } catch (InterruptedException e) {        
  39.                     e.printStackTrace();        
  40.                 }        
  41.                 continue;        
  42.             } else {        
  43.                 if (netInfo.isAvailable()) {        
  44.                     return true;        
  45.                 } else        
  46.                     continue;        
  47.             }        
  48.         }        
  49.         return false;        
  50.     }    

获取MMC、MNC、SimOperator的相关方法(设置APN的时候都有这样的选项):

 

 
  1. Java 代码复制内容到剪贴板  
  2.       
  3. public String getMCC() {        
  4.         TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);        
  5.         String numeric = tm.getSimOperator();        
  6.         String mcc = numeric.substring(03);        
  7.         return mcc;        
  8.     }        
  9.         
  10.     public String getMNC() {        
  11.         TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);        
  12.         String numeric = tm.getSimOperator();        
  13.         String mnc = numeric.substring(3, numeric.length());        
  14.         return mnc;        
  15.     }        
  16.         
  17.     public String getSimOperator() {        
  18.         TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);        
  19.         String SimOperator = tm.getSimOperator();        
  20.         return SimOperator;        
  21.     }    

新建一个APN:

 

 
  1. Java 代码复制内容到剪贴板  
  2.       
  3. public String bulidAPN() {        
  4.         ContentResolver resolver = getContentResolver();        
  5.         ContentValues values = new ContentValues();        
  6.         values.put("name""AndroidNet_APN");        
  7.         values.put("apn""#777");        
  8.         values.put("user""ctnet@mycdma.cn");        
  9.         values.put("password""vnet.mobi");        
  10.         values.put("mcc", getMCC());        
  11.         values.put("mnc", getMNC());        
  12.         values.put("numeric", getSimOperator());        
  13.         Cursor c = null;        
  14.         String defaultAPNId = "";        
  15.         try {        
  16.             Uri newRow = resolver.insert(uri, values);        
  17.             if (newRow != null) {        
  18.                 c = resolver.query(newRow, nullnullnullnull);        
  19.                 int idindex = c.getColumnIndex("_id");        
  20.                 c.moveToFirst();        
  21.                 defaultAPNId = c.getString(idindex);        
  22.             }        
  23.         } catch (SQLException e) {        
  24.             defaultAPNId = "";        
  25.         }        
  26.         if (c != null)        
  27.             c.close();        
  28.         return defaultAPNId;        
  29.     }    

通过判断,获取一个可用的网络连接:

 

 
  1. Java 代码复制内容到剪贴板  
  2.       
  3. /**       
  4.      * 获取网络连接       
  5.      * @param url       
  6.      * @return       
  7.      */        
  8.     public HttpURLConnection getConnection(URL url) {        
  9.         /** 当前APN的id*/        
  10.         String currentAPNId;        
  11.         /**当前APN的用户名*/        
  12.         String currentAPNUser;        
  13.         /**当前APN的密码*/        
  14.         String currentAPNPassword;        
  15.         HttpURLConnection conn = null;        
  16.         /**判断wifi是否可用*/        
  17.         if (isWIFIAvailable()) {        
  18.             try {        
  19.                 conn = (HttpURLConnection) url.openConnection();        
  20.                 /**连接超时时间*/        
  21.                 conn.setConnectTimeout(100000);        
  22.                 conn.setReadTimeout(100000);        
  23.             } catch (IOException e) {        
  24.                 e.printStackTrace();        
  25.                 conn = null;        
  26.                 return conn;        
  27.             }        
  28.             return conn;        
  29.         }        
  30.         
  31.         Cursor mCursor_APN = getContentResolver().query(PREFERRED_APN_URI,        
  32.                 nullnullnullnull);        
  33.         if (mCursor_APN == null || !mCursor_APN.moveToNext()) {        
  34.             return null;        
  35.         } else {        
  36.             currentAPNId = mCursor_APN.getString(mCursor_APN        
  37.                     .getColumnIndex("_id"));        
  38.             currentAPNUser = mCursor_APN.getString(mCursor_APN        
  39.                     .getColumnIndex("user"));        
  40.             currentAPNPassword = mCursor_APN.getString(mCursor_APN        
  41.                     .getColumnIndex("password"));        
  42.             mCursor_APN.close();        
  43.         }        
  44.         
  45.         if (!(currentAPNUser.equals("ctnet@mycdma.cn")        
  46.                 && currentAPNPassword.equals("vnet.mobi") || currentAPNUser        
  47.                 .equals("ctwap@mycdma.cn")        
  48.                 && currentAPNPassword.equals("vnet.mobi"))) {        
  49.             /**既不是wap又不是net上网方式需要指定上网方式*/        
  50.             Cursor mCursor_APN_Defalut = getContentResolver().query(uri, null,        
  51.                     " user=? and password=?",        
  52.                     new String[] { "ctnet@mycdma.cn""vnet.mobi" }, null);        
  53.             if (mCursor_APN_Defalut == null        
  54.                     || !mCursor_APN_Defalut.moveToNext()) {        
  55.                 /** 不存在ctnet则重新建立一个连接*/        
  56.                 mCursor_APN_Defalut.close();// 关闭连接        
  57.                 String DefalutAPNId = bulidAPN();        
  58.                 if (DefalutAPNId == null || DefalutAPNId.equals("")        
  59.                         || DefalutAPNId.equals(" "))// 创建新的APN失败        
  60.                 {        
  61.                     return null;        
  62.                 }        
  63.                 ContentResolver resolver = getContentResolver();        
  64.                 ContentValues values = new ContentValues();        
  65.                 values.put("apn_id", DefalutAPNId);        
  66.                 resolver.update(PREFERRED_APN_URI, values, nullnull);        
  67.             } else {// 使用系统默认的APN连接        
  68.                 String DefalutAPNId = mCursor_APN_Defalut        
  69.                         .getString(mCursor_APN_Defalut.getColumnIndex("_id"));        
  70.                 ContentResolver resolver = getContentResolver();        
  71.                 ContentValues values = new ContentValues();        
  72.                 values.put("apn_id", DefalutAPNId);        
  73.                 resolver.update(PREFERRED_APN_URI, values, nullnull);        
  74.                 mCursor_APN_Defalut.close();        
  75.             }        
  76.             try {        
  77.                 Thread.sleep(8000L);        
  78.             } catch (InterruptedException e) {        
  79.                 e.printStackTrace();        
  80.             }        
  81.         }        
  82.         
  83.         /** wap需要代理*/        
  84.         if ((android.net.Proxy.getDefaultHost()) != null) {        
  85.             try {        
  86.                 java.net.Proxy p = new java.net.Proxy(java.net.Proxy.Type.HTTP,        
  87.                         new InetSocketAddress(        
  88.                                 android.net.Proxy.getDefaultHost(),        
  89.                                 android.net.Proxy.getDefaultPort()));        
  90.                 conn = (HttpURLConnection) url.openConnection(p);        
  91.                 conn.setConnectTimeout(100000);        
  92.                 conn.setReadTimeout(100000);        
  93.             } catch (Exception e) {        
  94.                 conn = null;        
  95.             }        
  96.             return conn;        
  97.         }        
  98.         /**net不需要代理*/        
  99.         if ((android.net.Proxy.getDefaultHost()) == null) {        
  100.             try {        
  101.                 conn = (HttpURLConnection) url.openConnection();        
  102.                 conn.setConnectTimeout(100000);        
  103.                 Log.v("http""nohttpdaili");        
  104.             } catch (Exception e) {        
  105.                 conn = null;        
  106.             }        
  107.             return conn;        
  108.         }        
  109.         return conn;        
  110.         
  111.     }    

 



     本文转自06peng 51CTO博客,原文链接:http://blog.51cto.com/06peng/962791,如需转载请自行联系原作者



相关文章
|
2月前
|
网络协议 Shell 网络安全
解决两个 Android 模拟器之间无法网络通信的问题
让同一个 PC 上运行的两个 Android 模拟器之间能相互通信,出(qiong)差(ren)的智慧。
28 3
|
4月前
|
安全 网络安全 Android开发
安卓与iOS开发:选择的艺术网络安全与信息安全:漏洞、加密与意识的交织
【8月更文挑战第20天】在数字时代,安卓和iOS两大平台如同两座巍峨的山峰,分别占据着移动互联网的半壁江山。它们各自拥有独特的魅力和优势,吸引着无数开发者投身其中。本文将探讨这两个平台的特点、优势以及它们在移动应用开发中的地位,帮助读者更好地理解这两个平台的差异,并为那些正在面临选择的开发者提供一些启示。
127 56
|
7月前
|
Android开发
Android网络访问超时
Android网络访问超时
56 2
|
4月前
|
安全 网络安全 Android开发
探索安卓开发之旅:从新手到专家网络安全与信息安全:防范网络威胁,保护数据安全
【8月更文挑战第29天】在这篇技术性文章中,我们将踏上一段激动人心的旅程,探索安卓开发的世界。无论你是刚开始接触编程的新手,还是希望提升技能的资深开发者,这篇文章都将为你提供宝贵的知识和指导。我们将从基础概念入手,逐步深入到安卓开发的高级主题,包括UI设计、数据存储、网络通信等方面。通过阅读本文,你将获得一个全面的安卓开发知识体系,并学会如何将这些知识应用到实际项目中。让我们一起开启这段探索之旅吧!
|
4月前
|
Java Android开发 Kotlin
Android项目架构设计问题之要在Glide库中加载网络图片到ImageView如何解决
Android项目架构设计问题之要在Glide库中加载网络图片到ImageView如何解决
39 0
|
4月前
|
Java Android开发 开发者
Android项目架构设计问题之使用Retrofit2作为网络库如何解决
Android项目架构设计问题之使用Retrofit2作为网络库如何解决
72 0
|
6月前
|
缓存 JSON 网络协议
Android面试题:App性能优化之电量优化和网络优化
这篇文章讨论了Android应用的电量和网络优化。电量优化涉及Doze和Standby模式,其中应用可能需要通过用户白名单或电池广播来适应限制。Battery Historian和Android Studio的Energy Profile是电量分析工具。建议减少不必要的操作,延迟非关键任务,合并网络请求。网络优化包括HTTPDNS减少DNS解析延迟,Keep-Alive复用连接,HTTP/2实现多路复用,以及使用protobuf和gzip压缩数据。其他策略如使用WebP图像格式,按网络质量提供不同分辨率的图片,以及启用HTTP缓存也是有效手段。
92 9
|
6月前
|
缓存 网络协议 安全
Android网络面试题之Http基础和Http1.0的特点
**HTTP基础:GET和POST关键差异在于参数传递方式(GET在URL,POST在请求体),安全性(POST更安全),数据大小限制(POST无限制,GET有限制),速度(GET较快)及用途(GET用于获取,POST用于提交)。面试中常强调POST的安全性、数据量、数据类型支持及速度。HTTP 1.0引入了POST和HEAD方法,支持多种数据格式和缓存,但每个请求需新建TCP连接。**
55 5
|
6月前
|
安全 网络协议 算法
Android网络基础面试题之HTTPS的工作流程和原理
HTTPS简述 HTTPS基于TCP 443端口,通过CA证书确保服务器身份,使用DH算法协商对称密钥进行加密通信。流程包括TCP握手、证书验证(公钥解密,哈希对比)和数据加密传输(随机数加密,预主密钥,对称加密)。特点是安全但慢,易受特定攻击,且依赖可信的CA。每次请求可能复用Session ID以减少握手。
64 2
|
6月前
|
缓存 网络协议 Android开发
Android网络面试题之Http1.1和Http2.0
HTTP/1.1 引入持久连接和管道机制提升效率,支持分块传输编码和更多请求方式如PUT、PATCH。Host字段指定服务器域名,RANGE用于断点续传。HTTP/2变为二进制协议,实现多工处理,头信息压缩和服务器推送,减少延迟并优化资源加载。HTTP不断发展,从早期的简单传输到后来的高效交互。
75 0
Android网络面试题之Http1.1和Http2.0