Android代碼設置APN

什麼是APN?

APN(Access Point Name)中文全稱叫接入點。APN指一種網絡接入技術,是通過手機上網時必須配置的一個參數,它決定瞭手機通過哪種接入方式來訪問網絡。APN用來標識GPRS的業務種類,目前分為兩大類:CMWAP(通過GPRS訪問WAP業務)、CMNET(除瞭WAP以外的服務目前都用CMNET,比如連接因特網等)。

APN手機裡的位置

不同手機可能位置不一樣,我使用的測試機是紅米3S,位置是:設置->雙卡和移動網絡->接入點名稱。或者可以直接在設置裡直接搜索“APN”。我是在測試的時候才需要來這裡看動態添加APN是否成功。

這裡需要提前說明,代碼實現設置APN需要程序擁有系統權限,如何擁有系統權限呢?你需要去找個工具給自己用AS build的apk進行系統簽名,這種系統簽名工具我之前在CSDM上看到過,如果需要的話可以去搜一下。另一點就是需要SIM卡,如果測試機沒有SIM卡的話就沒辦法進行這方面的測試瞭。

Android系統中,對於APN網絡的API是隱藏的,因此獲取手機的APN設置,需要通過ContentProvider來進行數據庫查詢,查詢的URI地址是:
取得全部的APN列表:content://telephony/carriers;
取得當前設置的APN:content://telephony/carriers/preferapn;
取得current=1的APN:content://telephony/carriers/current;

下面是代碼實現簡單介紹:
通過cr這個遊標對象可以進行手機裡面APN信息的查詢,下面代碼中的“ErrorApplication.getContext()”其實隻是一個context對象,我實際代碼中是這樣寫,把它換成其他合適的this或者你需要的context對象都可以。
// 檢查當前連接的APN

Cursor cr = ErrorApplication.getContext().getContentResolver().query(APN_URI, null, null, null, null);
        while (cr != null && cr.moveToNext()) {
    if(cr.getString(cr.getColumnIndex("apn")).equals("abc")){
                APN.hasAPN=true;
                break;
            }
        }
    }

獲取SIM卡信息:APN中的某些屬性在這些信息裡面

protected String getSIMInfo() {
    TelephonyManager iPhoneManager = (TelephonyManager) ErrorApplication.getContext()
            .getSystemService(Context.TELEPHONY_SERVICE);
    return iPhoneManager.getSimOperator();
}

添加接入點:

public int addAPN() {
        int id = -1;
        String NUMERIC = getSIMInfo();
        if (NUMERIC == null) {
            return -1;
        }
        ContentResolver resolver = ErrorApplication.getContext().getContentResolver();
        ContentValues values = new ContentValues();
        values.put("name", "專用APN");                                  //apn中文描述
        values.put("apn", "unim2m.njm2mapn1");                                     //apn名稱
        values.put("type", "default");                            //apn類型
        values.put("numeric", NUMERIC);
        values.put("mcc", NUMERIC.substring(0, 3));
        values.put("mnc", NUMERIC.substring(3, NUMERIC.length()));
        values.put("proxy", "");                                        //代理
        values.put("port", "");                                         //端口
        values.put("mmsproxy", "");                                     //彩信代理
        values.put("mmsport", "");                                      //彩信端口
        values.put("user", "");                                         //用戶名
        values.put("server", "");                                       //服務器
        values.put("password", "");                                     //密碼
        values.put("mmsc", "");                                          //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;
    }

設置接入點:

public void SetAPN(int id) {
ContentResolver resolver = ErrorApplication.getContext().getContentResolver();
ContentValues values = new ContentValues();
values.put(“apn_id”, id);
resolver.update(CURRENT_APN_URI, values, null, null);
}

下面是封裝成一個工具類的完整代碼:

public class APN {
    public static boolean hasAPN;
    // 新增一個cmnet接入點
    public void APN(){
        checkAPN();
    }
    public int addAPN() {
        int id = -1;
        String NUMERIC = getSIMInfo();
        if (NUMERIC == null) {
            return -1;
        }
        ContentResolver resolver = ErrorApplication.getContext().getContentResolver();
        ContentValues values = new ContentValues();
        values.put("name", "專用APN");                                  //apn中文描述
        values.put("apn", "abc");                                     //apn名稱
        values.put("type", "default");                            //apn類型
        values.put("numeric", NUMERIC);
        values.put("mcc", NUMERIC.substring(0, 3));
        values.put("mnc", NUMERIC.substring(3, NUMERIC.length()));
        values.put("proxy", "");                                        //代理
        values.put("port", "");                                         //端口
        values.put("mmsproxy", "");                                     //彩信代理
        values.put("mmsport", "");                                      //彩信端口
        values.put("user", "");                                         //用戶名
        values.put("server", "");                                       //服務器
        values.put("password", "");                                     //密碼
        values.put("mmsc", "");                                          //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;
    }

    protected String getSIMInfo() {
        TelephonyManager iPhoneManager = (TelephonyManager) ErrorApplication.getContext()
                .getSystemService(Context.TELEPHONY_SERVICE);
                return iPhoneManager.getSimOperator();
    }
    // 設置接入點
    public void SetAPN(int id) {
        ContentResolver resolver = ErrorApplication.getContext().getContentResolver();
        ContentValues values = new ContentValues();
        values.put("apn_id", id);
        resolver.update(CURRENT_APN_URI, values, null, null);
        }
    public void checkAPN() {
        // 檢查當前連接的APN
        Cursor cr = ErrorApplication.getContext().getContentResolver().query(APN_URI, null, null, null, null);
        while (cr != null && cr.moveToNext()) {
         if(cr.getString(cr.getColumnIndex("apn")).equals("abc")){
                APN.hasAPN=true;
                break;
            }
        }
    }
}

在主活動的調用:

APN apn=new APN();
apn.checkAPN();
if (!APN.hasAPN) {
    apn.SetAPN(apn.addAPN());
}

補充解釋,一開始實現功能之後,發現每次打開程序,都會創建一個APN出來,想一想就很不舒服,幾次操作之後設置那裡APN的列表就會一大串。於是添加瞭一點改進,設置各靜態變量hasAPN,每次主活動創建後,先通過checkAPN裡面查找,看有沒有已存在的我們需要的APN,然後改變hasAPN的值,如果沒有我們才去創建。

You May Also Like