Android APN Enforcement

Paz picture Paz · Oct 23, 2011 · Viewed 11k times · Source

Someone know if there's a programmatically way to use a specific defined APN on the device which is not the default one?

Thanks.

Answer

patthoyts picture patthoyts · Oct 23, 2011

You can programmatically query and set the preferred APN using the uri content://telephony/carriers/preferapn. To set a new preferred APN you have to pass in the database ID of an existing APN entry. The following function can do this if you pass in the display name of the APN (eg: setPreferredApn(context, "Giffgaff");)

public static final Uri APN_TABLE_URI = Uri.parse("content://telephony/carriers");
public static final Uri APN_PREFER_URI = Uri.parse("content://telephony/carriers/preferapn");

public static boolean setPreferredApn(Context context, String name) {
    boolean changed = false;
    String columns[] = new String[] { Carriers._ID, Carriers.NAME };
    String where = "name = ?";
    String wargs[] = new String[] {name};
    String sortOrder = null;
    Cursor cur = context.getContentResolver().query(APN_TABLE_URI, columns, where, wargs, sortOrder);
    if (cur != null) {
        if (cur.moveToFirst()) {
            ContentValues values = new ContentValues(1);
            values.put("apn_id", cur.getLong(0));
            if (context.getContentResolver().update(APN_PREFER_URI, values, null, null) == 1)
                changed = true;
        }
        cur.close();
    }
    return changed;
}

I guess I should add that you need WRITE_APN_SETTINGS permission and need to import android.provider.Telephony and android.provider.Telephony.Carriers

UPDATE FOR 4.0+

This facility became disabled with the release of Android 4.0 (ICS). Enabling the WRITE_APN_SETTINGS permission has no effect on allowing you to set the APN any more. See this question for some relevant links. On the API page it now states explicitly this permission is not for external use and this is enforced internally.