Read APNs in Android 4.2?

If you want to Read APN for Android 4.2 and more they are a change to do. I tested and it's work.

In Android 4.1 and below use this :

Cursor c = getContentResolver().query(Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"), null, null, null, null);

And for Android 4.2 and above use this code :

private static final String[] APN_PROJECTION = {
     Telephony.Carriers.TYPE,            // 0
     Telephony.Carriers.MMSC,            // 1
     Telephony.Carriers.MMSPROXY,        // 2
     Telephony.Carriers.MMSPORT          // 3
 };

And this line :

final Cursor apnCursor =SqliteWrapper.query(context, this.context.getContentResolver(), Uri.withAppendedPath(Carriers.CONTENT_URI, "current"), APN_PROJECTION, null, null, null);

The SQLiteWrapperClass is hidden (found this class in internet)

import android.database.sqlite.SqliteWrapper;

My English is not quite good, sorry for this.


This appears to be an intentional change. The git commit where they added this defense includes the following comment:

Since the DB may contain corp passwords, we should secure it. Using the same permission as writing to the DB as the read is potentially as damaging as a write.

It is conceivable that your issue will cause them to consider adding a separate read permission, but at least for the time being, this is a regression in 4.2.


You can read default settings from /etc/apns-conf.xml:

private boolean getSettingsFromApnsFile(Context context, String apnName) {
    FileReader reader = null;
    boolean sawValidApn = false;

    try {
        reader = new FileReader("/etc/apns-conf.xml");

        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(true);
        XmlPullParser xpp = factory.newPullParser();
        xpp.setInput(reader);

        TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
        String simOperator = telephonyManager.getSimOperator();
        if (TextUtils.isEmpty(simOperator)) {
            logger.warn("unable to get sim operator - so unable to get mms config");
            return false;
        }

        int eventType = xpp.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            if (eventType == XmlPullParser.START_TAG && xpp.getName().equals("apn")) {
                HashMap<String, String> attributes = new HashMap<String, String>();
                for (int i=0; i<xpp.getAttributeCount(); i++) {
                    attributes.put(xpp.getAttributeName(i), xpp.getAttributeValue(i));
                }
                if (attributes.containsKey("mcc") && attributes.containsKey("mnc") && simOperator.equals(attributes.get("mcc")+attributes.get("mnc"))) {
                    if (!TextUtils.isEmpty(apnName) && !apnName.trim().equals(attributes.get("apn"))) {
                        eventType = xpp.next();
                        continue;
                    }

                    if (isValidApnType(attributes.get("type"), PhoneConstants.APN_TYPE_MMS)) {
                        sawValidApn = true;

                        String mmsc = attributes.get("mmsc");
                        if (mmsc == null) {
                            eventType = xpp.next();
                            continue;
                        }

                        mServiceCenter = NetworkUtil.trimV4AddrZeros(mmsc.trim());
                        mProxyAddress = NetworkUtil.trimV4AddrZeros(
                                attributes.get("mmsproxy"));
                        if (isProxySet()) {
                            String portString = attributes.get("mmsport");
                            try {
                                mProxyPort = Integer.parseInt(portString);
                            } catch (NumberFormatException e) {
                                if (TextUtils.isEmpty(portString)) {
                                    logger.warn("mms port not set!");
                                } else {
                                    logger.error("Bad port number format: " + portString, e);
                                }
                            }
                        }
                    }

                }
            }
            eventType = xpp.next();
        }
    } catch (Exception e) {
        logger.warn("unable to get mmsc config from apns-conf file", e);
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (Exception e) {
            }
        }
    }
    return sawValidApn;
}