Android9.0以后不允许HTTP访问的解决方案

本文介绍了如何在Android9.0及以上版本中通过XML布局设置和代码反射技术解决因默认禁止HTTP访问而引发的错误,包括创建`network_security_config.xml`文件和使用`ReflectionUtil`动态设置`CleartextTrafficPermitted`。
摘要由CSDN通过智能技术生成

背景

自 Android 9.0 起,默认禁止使用 HTTP 进行访问。当尝试使用 HTTP 链接时,将会收到以下错误信息:

"Cleartext HTTP traffic to " + host + " not permitted"

为了解决这一问题,下面介绍两种破解方法:

XML布局设置

在 Android 9.0 及以上版本,需要通过以下配置允许 HTTP 访问。在 android/app/res 目录下新建 network_security_config.xml 文件,内容如下:

<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

然后在 android/app 目录下的 AndroidManifest.xml 文件中的 application 标签内声明文件:

android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"

其实只需在 AndroidManifest.xml 文件中的 application 标签内声明 android:usesCleartextTraffic="true" 就可以了。如果还有特殊的配置,则需要配置 networkSecurityConfig 文件。另外需要说明的是,networkSecurityConfig 文件中的 cleartextTrafficPermitted 属性会优先于 application 标签内的 usesCleartextTraffic,这意味着,即使在 application 标签中设置了 android:usesCleartextTraffic="false",但在 networkSecurityConfig 文件中设置了 cleartextTrafficPermitted="true",仍然会开启明文传输。

代码设置

为了验证结果,首先需要在 AndroidManifest.xml 文件中的 application 标签内声明文件:

android:usesCleartextTraffic="false"

接下来编写反射工具类,用于调用对象的指定方法:

import android.util.Log;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 反射工具类,用于调用对象的指定方法
 */
public class ReflectionUtil {

    private static final String TAG = "ReflectionUtil"; // 日志标签

    /**
     * 调用对象的指定方法
     * 
     * @param owner      方法所属的对象实例
     * @param methodName 方法名
     * @param b          方法参数,boolean类型
     * @return 方法的返回值,如果调用失败则返回null
     */
    public static Object invokeMethod(Object owner, String methodName, boolean b) {
        if (owner == null) {
            Log.e(TAG, methodName + " not invoked, owner is null"); // 记录错误日志:对象为空无法调用方法
            return null;
        }
        try {
            Class<?> ownerClass = owner.getClass(); // 获取对象的类
            Method method = ownerClass.getDeclaredMethod(methodName, boolean.class); // 获取指定方法
            method.setAccessible(true); // 设置方法为可访问
            return method.invoke(owner, b); // 调用方法
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            Log.e(TAG, methodName +
                " not invoked, InvocationTargetException or NoSuchFieldException or IllegalAccessException: " +
                e.getMessage()); // 记录错误日志:方法调用失败
        }
        return null;
    }
}

最后,通过以下代码设置:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    boolean permittedOld = NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted(); // 获取旧的 cleartext 流量是否允许
    Log.i("TAG", "onCreate, permittedOld: " + permittedOld); // 记录旧的 cleartext 流量是否允许的日志

    // 动态设置 setCleartextTrafficPermitted 方法
    ReflectionUtil.invokeMethod(NetworkSecurityPolicy.getInstance(), "setCleartextTrafficPermitted", true);

    boolean permittedNew = NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted(); // 获取新的 cleartext 流量是否允许
    Log.i("TAG", "onCreate, permittedNew: " + permittedNew); // 记录新的 cleartext 流量是否允许的日志
}

简而言之,通过 XML 布局和反射设置,可以绕过 Android 9.0 的 HTTP 访问限制。

在React Native中,遇到Android 9.0以上版本无法进行HTTP请求的问题,可以尝试以下解决方法: 1. 添加网络安全配置文件:Android 9.0以后,Google要求所有的网络请求必须使用HTTPS,为了解决这个问题,需要在应用的res目录下创建一个XML文件,命名为`network_security_config.xml`。文件内容如下: ``` <?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true" /> </network-security-config> ``` 2. 在AndroidManifest.xml文件中添加网络安全配置:在`application`标签内添加以下代码: ``` <application ... android:networkSecurityConfig="@xml/network_security_config" ...> ``` 这样做将允许应用发送非加密的HTTP请求。 3. 检查资源文件路径:尽管Android称之为资源文件路径问题相对不太常见,但是有时候路径的问题可能导致HTTP请求无法正常工作。因此,请确保在代码中使用的资源文件的路径是正确的。 4. 检查网络连接权限:确保在AndroidManifest.xml文件中已经添加了网络连接的权限,代码如下: ``` <uses-permission android:name="android.permission.INTERNET" /> ``` 5. 检查网络连接状态:有时候,即使在代码中正确地设置了HTTP请求,但是如果设备没有连接到互联网,仍然无法发送或接收请求。因此,请确保设备在进行HTTP请求时连接到有效的网络。 希望以上解决方法能够帮助到你,使你能够在React Native中成功进行HTTP请求。如果问题仍然存在,请进一步检查相关代码和日志以寻找其他潜在问题。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿界新星蔡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值