Android指定專用APN

 在一個車載android系統定製開發項目中,客戶提出有時候要使用廠家的專用網絡,訪問請求廠家提供的互聯網服務;而在普通的網絡請求時使用普通SIM卡本身能識別的APN來上網。

項目用的是全志T3 Android4.4平臺,首先在系統中增加專用apn,在android\out\target\product\XXX\system\etc目錄下,可以看到apns-conf.xml配置文件,這就是android系統裏面的默認所有apn列表,源碼則在android/device/softwinner/common/rild/apns-conf_sdk.xml 中修改,將新增的專用apn增加到這文件裏即可。源碼中加載所有apn是在android/package/providers/TelephonyProvider/src/com/android/providers/telephony/TelephonyProvider.java加載:

        /*
         * Loads apns from xml file into the database
         *
         * @param db the sqlite database to write to
         * @param parser the xml parser
         *
         */
        private void loadApns(SQLiteDatabase db, XmlPullParser parser) {
            if (parser != null) {
                try {
                    db.beginTransaction();
                    XmlUtils.nextElement(parser);
                    while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
                        ContentValues row = getRow(parser);
                        if (row == null) {
                            throw new XmlPullParserException("Expected 'apn' tag", parser, null);
                        }
                        insertAddingDefaults(db, CARRIERS_TABLE, row);
                        XmlUtils.nextElement(parser);
                    }
                    db.setTransactionSuccessful();
                } catch (XmlPullParserException e) {
                    Log.e(TAG, "Got XmlPullParserException while loading apns.", e);
                } catch (IOException e) {
                    Log.e(TAG, "Got IOException while loading apns.", e);
                } catch (SQLException e) {
                    Log.e(TAG, "Got SQLException while loading apns.", e);
                } finally {
                    db.endTransaction();
                }
            }
        }

 這方法將解釋出一個個apn,然後能過insertAddingDefaults把apn存儲到數據庫中,也就是我們可以在使用專用網絡的時候,在這方法做動作,除專用網絡對應的apn入庫,其餘不入庫即可:

private void insertAddingDefaults(SQLiteDatabase db, String table, ContentValues row) {
            // Initialize defaults if any
            if (row.containsKey(Telephony.Carriers.AUTH_TYPE) == false) {
                row.put(Telephony.Carriers.AUTH_TYPE, -1);
            }
            if (row.containsKey(Telephony.Carriers.PROTOCOL) == false) {
                row.put(Telephony.Carriers.PROTOCOL, "IP");
            }
            if (row.containsKey(Telephony.Carriers.ROAMING_PROTOCOL) == false) {
                row.put(Telephony.Carriers.ROAMING_PROTOCOL, "IP");
            }
            if (row.containsKey(Telephony.Carriers.CARRIER_ENABLED) == false) {
                row.put(Telephony.Carriers.CARRIER_ENABLED, true);
            }
            if (row.containsKey(Telephony.Carriers.BEARER) == false) {
                row.put(Telephony.Carriers.BEARER, 0);
            }
            if (row.containsKey(Telephony.Carriers.MVNO_TYPE) == false) {
                row.put(Telephony.Carriers.MVNO_TYPE, "");
            }
            if (row.containsKey(Telephony.Carriers.MVNO_MATCH_DATA) == false) {
                row.put(Telephony.Carriers.MVNO_MATCH_DATA, "");
            }

            //add by likai start
            String custApn = Settings.Secure.getString(mContext.getContentResolver(), "key_custom_apn");
            if(custApn != null) {
               if (row.containsKey(Telephony.Carriers.APN)) {
                  String apn = row.getAsString(Telephony.Carriers.APN);

                  if(apn != null && !"".equals(custApn) && !apn.equalsIgnoreCase(custApn)) {
                     //Log.d(TAG, "apn not equals");
                     return;
                  }else{
                     Log.d(TAG, "apn equals, custom apn = " + custApn);
                  }
               }
            }
            //add by likai end
            db.insert(CARRIERS_TABLE, null, row);
        }

 然後,在接收到要更新使用專有網絡apn的時候,進入重置apn列表即可:

public static final Uri RESTORE_APN_URI = Uri.parse("content://telephony/carriers/restore"); 

if("NULL".equalsIgnoreCase(newAPN)){
            Settings.Secure.putString(mContext.getContentResolver(), "key_custom_apn", "");
        }else {
            Settings.Secure.putString(mContext.getContentResolver(), "key_custom_apn", newAPN);
        }
        try {
            resolver.delete(RESTORE_APN_URI, null, null);//restore apn data
        } catch (Exception e1) {
            e1.printStackTrace();
        }

}

 重置apn後,系統將會重新選擇apn,些時數據庫中有且僅有專有網絡一條記錄,如果些記錄與正在使用的SIM是匹配的,那麼些是使用的就會是專有網絡。

此方法僅是個人的一種投機方法,高手勿噴,如有高見請賜教。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章