Android设备设置Apn相关

什么是Apn

Apn,Access Point Name,接入点名称,是手机上网必须要配置的一个参数,他决定了手机通过什么方式访问哪种网络环境。对于手机用户来讲,可以访问的网络类型有英特网,WAP网络,集团企业内部网络。而WAP网络估计现在已经被遗忘的差不多了,WAP是专门针对早期性能比较差的手机设计的精简版的网络协议,看下图相信大家就会有所记忆,尤其是80,90后,随着智能手机的发展,由于WAP不能满足智能手机强大的浏览器,所以很多WAP网站陆陆续续被关停。
Android设备设置Apn相关_第1张图片
移动手机默认两种CMWAP和CMNET,一些使用移动办公的大客户,通常会使用专用APN,其接入点随意定义,只要和该省运营商其他APN不冲突即可。

CMWAP也叫移动梦网,通过该接入点可接入一个比较大的移动私网,网内有大量的手机应用下载及资源访问。因为CMWAP不接入互联网,只接入移动运营商的私网,所以流量费用比较低廉。

CMNET也叫GPRS连接互联网,通常每个省的运营商会提供若干个Internet出口以供CMNET拨号用户使用。其流量费用较CMWAP要高一些。

目前国内销售的手机,如果是非智能机,通常已配置好CMWAP连接,智能机通常会配置CMWAP和CMNET连接。如需手动添加这些配置,请参考手机说明书。
 

代码设置Apn

private Uri APN_URI = Uri.parse("content://telephony/carriers");
private Uri CURRENT_APN_URI = Uri.parse("content://telephony/carriers/preferapn");
//新增Apn节点
private int addApn(Context context, String apnName) {
        int id = -1;
        String simInfo = getSimInfo(context);
        Log.e("SetApnReceiver", "simInfo " + simInfo);

        if (TextUtils.isEmpty(simInfo)) {
            return -1;
        }

        ContentResolver resolver = context.getContentResolver();
        ContentValues values = new ContentValues();
        //apn中文描述
        values.put("name", apnName);
        //apn名称
        values.put("apn", apnName);
        //apn类型
        values.put("type", "default");
        values.put("numeric", simInfo);

        values.put("mcc", simInfo.substring(0, 3));
        values.put("mnc", simInfo.substring(3, 5));
        //代理
        values.put("proxy", "");
        //端口
        values.put("port", "");
        //彩信代理
        values.put("mmsproxy", "");
        //彩信端口
        values.put("mmsport", "");
        //用户名
        values.put("user", "");
        //服务器
        values.put("server", "");
        //密码
        values.put("password", "");
        //MMSC
        values.put("mmsc", "");
        Cursor c = null;
        Uri newRow = resolver.insert(APN_URI, values);
        if (newRow != null) {
            c = resolver.query(newRow, null, null, null, null);
            int idIndex = c.getColumnIndex("_id");
            c.moveToFirst();
            id = c.getShort(idIndex);
        }

        if (c != null) {
            c.close();
        }

        return id;
    }
 //获取SIM卡的IMSI码,由MCC、MNC、MSIN组成
 //网上很多人使用的是getSimOperator()方法,但是本人使用时获取为空,
 //所以使用getSubscriberId()方法
@SuppressLint("MissingPermission")
public static String getSimInfo(Context context) 
    //https://blog.csdn.net/love_xsq/article/details/50420433
    TelephonyManager iPhoneManager = (TelephonyManager)        	   context.getSystemService(Context.TELEPHONY_SERVICE);
    return iPhoneManager.getSubscriberId();
 }
// 设置接入点
public void setAPN(Context context, int id) {
    ContentResolver resolver = context.getContentResolver();
    ContentValues values = new ContentValues();
    values.put("apn_id", id);
    resolver.update(CURRENT_APN_URI, values, null, null);
 }
//获取apn的id
public int getAPN(Context context, String apnName) {
    ContentResolver resolver = context.getContentResolver();
    Cursor c = resolver.query(APN_URI, new String[]{"_id", "name",
         "apn"}, "apn like '%" + apnName + "%'", null, null);

    // 该项APN存在
    if (c != null && c.moveToNext()) {
       int id = c.getShort(c.getColumnIndex("_id"));
       String name = c.getString(c.getColumnIndex("name"));
       String apn = c.getString(c.getColumnIndex("apn"));

       Log.e("SetApnReceiver", "APN has exist " + id + name + apn);
       return id;
     } else {
        Log.e("SetApnReceiver", "APN has not exist ");
     }

     return -1;
 }
//获取当前Apn
public int getCurrentAPN(Context context) {
    ContentResolver resolver = context.getContentResolver();
    Cursor c = resolver.query(CURRENT_APN_URI, null, null, null, null);

    // 该项APN存在
    if (c != null && c.moveToNext()) {
       int id = c.getShort(c.getColumnIndex("_id"));
       String name = c.getString(c.getColumnIndex("name"));
       String apn = c.getString(c.getColumnIndex("apn"));
       String user = c.getString(c.getColumnIndex("user"));
       String pass = c.getString(c.getColumnIndex("password"));
       Log.e("SetApnReceiver", "current APN " + id + name + apn);
       Log.e("SetApnReceiver", "current APN " + user + pass);
       return id;
  } else {
       Log.e("SetApnReceiver", "current APN is null");
  }

  return -1;
}

使用如下

int id = getAPN(context, apnName);
//如果在apn列表中存在则直接设置
if (id == -1) {
    id = addApn(context, apnName);
 }

 setAPN(context, id);

需要开启权限

<!-- 开关APN的权限 --> 
<uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />

 

注意

1.设置Apn的对象是手机(或者其他android终端设备)系统,而不是4G卡,系统中/system/etc路径下apns-conf.xml文件记录了大量详细的国内apn节点,也就是说getAPN()方法里查询到的apn节点内容也是来自这里。

2.如果用户使用自己专用的APN节点不存在设备系统中,则手机卡插入设备中不能访问该节点网络。

3.MCC=移动国家号码,由3位数字组成,唯一地识别移动用户所属的国家,我国为460。
MNC=移动网号,一般大多由2位数字组成,中国移动的是00或02,中国联通的是01。
运营商号码就是MCC+MNC
46000, “CHINA MOBILE”, “CN” 中国移动
46001, “CHN-CUGSM”, “CN” 中国联通
46002, “CHINA MOBILE”, “CN” 中国移动
 

参考文献

1.https://www.cnblogs.com/hanyonglu/archive/2012/03/29/2423298.html
2.https://www.cnblogs.com/zhangkeyu/p/6647382.html
3.https://blog.csdn.net/glunoy/article/details/108535191

你可能感兴趣的:(java,android,android,网络,java)