Android v4.2でAPNを読み取る際に問題が発生しました(APNSの書き込みではなく、読み取りが可能です)。セキュリティ例外がスローされます。
APN設定を書き込む権限がありません:ユーザー10068も現在のプロセスにもandroid.permission.WRITE_APN_SETTINGSがありません。
以前のすべてのプラットフォームで動作するために使用されたのと同じコードですが、これを回避する方法を知っている人はいますか?
ありがとう!
Android 4.2以降のAPNを読みたい場合は、変更が必要です。私はテストしました、そしてそれは働きます。
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;
私の英語はあまり上手ではありません。ごめんなさい。
これは意図的な変更のようです。この防御を追加したgitcommitには、次のコメントが含まれています。
DBにはcorpパスワードが含まれている可能性があるため、保護する必要があります。読み取りと同じ権限をDBへの書き込みと同じように使用すると、書き込みと同じくらい損傷を与える可能性があります。
あなたの問題により、彼らは別の読み取り許可を追加することを検討するようになると考えられますが、少なくとも当面は、これは4.2でのリグレッションです。
/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;
}
私にも状況があります。私の解決策は、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");
}
それがあなたを助けることを願っています!