Read APNs in Android 4.2?

前端 未结 4 702
情书的邮戳
情书的邮戳 2020-11-27 21:49

I have a problem reading APNs in Android v4.2 (Yes reading, not writing APNS), it is throwing a security exception:

相关标签:
4条回答
  • 2020-11-27 22:11

    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.

    0 讨论(0)
  • 2020-11-27 22:24

    I have the situation too, my solution is don't access android_assets in AsyncTask. "Make sure that only your main thread have the permission to access you app's assets dir"

    I got the problem when I coding like this:

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

    and I fix it by:

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

    hope that will help you!

    0 讨论(0)
  • 2020-11-27 22:27

    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;
    }
    
    0 讨论(0)
  • 2020-11-27 22:32

    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.

    0 讨论(0)
提交回复
热议问题