阅读Android 4.2中的APN?

在Android v4.2中读取APN时遇到问题(是读,不写APNS) ,这是抛出一个安全exception:

无权写入APN设置:用户10068或当前进程都没有android.permission.WRITE_APN_SETTINGS。

用于在以前的所有平台上工作的相同的代码,有没有人知道任何解决这个问题?

谢谢!

Solutions Collecting From Web of "阅读Android 4.2中的APN?"

这似乎是一个有意的改变。 他们添加了这个防御的git提交包括以下评论:

由于数据库可能包含公司密码,我们应该保护它。 使用与写入数据库相同的权限作为读取操作可能与写入操作一样具有破坏性。

可以想象的是,你的问题会使他们考虑增加一个单独的读取权限,但至less在目前这是4.2中的一个回归。

如果你想阅读APN的Android 4.2和更多,他们是一个改变。 我testing过,这是工作。

在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是隐藏的(在网上find这个类)

 import android.database.sqlite.SqliteWrapper; 

我的英语不太好,对不起。

您可以从/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; } 

我也有这种情况,我的解决scheme是不访问AsyncTask中的android_assets。 “ 确保只有你的主线程有权访问你的应用程序的资产目录

当我这样编码时,我遇到了问题:

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

希望能帮到你!