Чтение APN в Android 4.2?

У меня есть проблема чтения APN в Android v4.2 (Да, чтение, а не запись APNS), это бросает исключение безопасности:

Нет разрешения на запись настроек APN: ни пользователь 10068, ни текущий процесс имеет android.permission.WRITE_APN_SETTINGS.

Тот же код, используемый для работы на всех предыдущих платформах, знает ли кто-нибудь о какой-либо работе вокруг этого?

Спасибо!

Ответ 1

Это, по-видимому, преднамеренное изменение. Команда git, где они добавили эту защиту, включает следующий комментарий:

Поскольку БД может содержать пароли corp, мы должны ее защитить. Использование того же разрешения, что и запись в БД, поскольку чтение потенциально опасно как запись.

Вполне возможно, что ваша проблема заставит их рассмотреть возможность добавления отдельного разрешения на чтение, но по крайней мере пока это регрессия в 4.2.

Ответ 2

Если вы хотите прочитать APN для Android 4.2 и более, это изменение. Я тестировал, и он работает.

В Android 4.1 и ниже используйте это:

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

А для Android 4.2 и выше используйте этот код:

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

И эта строка:

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

SQLiteWrapperClass скрыт (найден этот класс в Интернете)

import android.database.sqlite.SqliteWrapper;

Мой английский не совсем хорошо, извините за это.

Ответ 3

Вы можете прочитать настройки по умолчанию из /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;
}

Ответ 4

У меня тоже ситуация, мое решение не имеет доступа к android_assets в AsyncTask. " Убедитесь, что только ваш основной поток имеет разрешение на доступ к вашим ресурсам app dir"

У меня возникла проблема при кодировании следующим образом:

@Override
protected void onResume() {
    super.onResume();
    //mWebView.loadUrl("file:///android_asset/95306.html");
    new LoadUrlTask().execute("file:///android_asset/95306.html");
}

...

class LoadUrlTask extends AsyncTask<String, Integer , String> {
    // progressDialog = new ProgressDialog(LoadActivity.this);

    @Override
    protected String doInBackground(String... strings) {
        mWebView.loadUrl(strings[0]);
        return "";
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        //progressDialog.dismiss();
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //progressDialog.setMessage("loading...");
        //progressDialog.show();
    }
}

и я исправляю его:

@Override
protected void onResume() {
    super.onResume();
    mWebView.loadUrl("file:///android_asset/95306.html");
    //new LoadUrlTask().execute("file:///android_asset/95306.html");
}

надеюсь, что это поможет вам!