Leer APNs en Android 4.2?

Tengo un problema al leer APNs en Android v4.2 (Sí leer, no escribir APNS) , está lanzando una excepción de seguridad:

No permission to write APN settings: Ni el usuario 10068 ni el proceso actual tiene android.permission.WRITE_APN_SETTINGS.

El mismo código utilizado para trabajar en todas las plataformas anteriores, ¿alguien sabe de algún trabajo alrededor de esto?

¡Gracias!

Esto parece ser un cambio intencional. El git commit donde agregaron esta defensa incluye el siguiente comentario:

Debido a que el DB puede contener contraseñas corporales, deberíamos asegurarlo. Utilizar el mismo permiso que escribir en la base de datos como la lectura es potencialmente tan perjudicial como una escritura.

Es concebible que su problema les haga considerar agregar un permiso de lectura separado, pero al menos por el momento, esto es una regresión en 4.2.

Si desea leer APN para Android 4.2 y más que son un cambio que hacer. He probado y es trabajo.

En Android 4.1 y versiones posteriores, utiliza esto:

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

Y para Android 4.2 o superior utilice este código:

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

Y esta línea:

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

El SQLiteWrapperClass está oculto (encontró esta clase en Internet)

 import android.database.sqlite.SqliteWrapper; 

Mi inglés no es muy bueno, lo siento por esto.

Puede leer la configuración predeterminada desde /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; } 

Tengo la situación también, mi solución es no tener acceso android_assets en AsyncTask. " Asegúrese de que sólo su hilo principal tenga el permiso para acceder al directorio de activos de su aplicación "

Tengo el problema cuando la codificación como este:

 @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(); } } 

Y lo arreglo por:

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

¡Espero que te ayude!

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.