Unity - 在安卓设备上,WWW.text返回null

3

我正在使用Unity开发一款Android应用程序。但是我无法连接到互联网服务器。

尽管以下代码返回false,但这是好的:Application.internetReachability == NetworkReachability.NotReachable

但是当尝试执行以下代码片段时:

IEnumerator testConnection() {
    Dictionary<string, string> header = new Dictionary<string, string>();
    string userAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36";
    header.Add("User-Agent", userAgent);
    WWW www = new WWW("www.google.com", null, header);
    yield return www;
    // check for errors
    if (www.error == null) {
        util.debug("works");
    } else {
        // www.error and www.text both are empty
        util.debug("testing: WWW Error: " + www.error + www.text); 
    }
}

它可以通过Unity编辑器和Windows可执行文件运行,但在我的Android设备上(版本6)无法运行。这个问题有已知的解决方案吗?

Ping测试似乎也可以工作:

IEnumerator PingGoogle() {
    Ping googPing  = new Ping("172.217.6.195");

    while (!googPing.isDone) {
        yield return googPing;
    }
    util.debug("ping works: " + googPing.time); //I reach this point with the app
}

我认为WWW类有问题?
安卓版本:6.0.1
OxygenOS版本:3.5.6
Unity版本:5.6.0b3 Personal(64位)
编辑:我更改了PlayerSettings(据我所知,这是Android清单)的Internet Access,从Auto更改为Require。没有成功。
编辑2:看起来www.error根本不是空的。消息被截断,因为它对Unity的文本元素来说太长了(我的错误)。错误是java.net.MalformedURLException: Protocol not found: www.google.de。所以唯一缺少的就是协议,即:http://。当我尝试评论中提供的解决方案时,我发现了这个问题。

在你的问题中没有提到权限,所以我要问一下:你是否已经在你的Android清单文件中添加了使用互联网连接的权限? - mrogal.ski
@InsOp GETPOST是两种不同类型的请求,在服务器端处理时会有所区别(在大多数情况下)。两年前,我正在编写HTTP服务器,在那里我们只是丢弃了空的POST请求。这也可能是这里的情况。另一件事是,也许从编辑器和Windows二进制文件中,WWW类使用了不同的HTTP内部机制来发送请求,自动将空的POST请求转换为GET请求。 - mrogal.ski
@m.rogalski 我认为你关于最后一部分的写法是正确的。我正在通过我的服务器来弄清楚这个问题。谢谢! - InsOp
1
@m.rogalski 是协议缺失了。谢谢你的帮助。我会将问题标记为重复的。 - InsOp
显示剩余12条评论
2个回答

3

我使用了你修改后仍无法工作的代码进行了快速测试,得到了以下运行时异常:

java.net.MalformedURLException:找不到协议

在出现此类问题时使用Android Monitor总是很好的。

问题在于你没有在url前缀中添加http://https://。Android不支持这样做,所以它可以在编辑器上运行但在Android上不能运行。

当你尝试在url中嵌入用户名和密码时,也会出现相同的情况。例如:http://username:password@example.com

这将在Windows和编辑器上运行,但不会在Android上运行,不过有一个解决方案

这应该可以解决问题:

IEnumerator testConnection()
{
    Dictionary<string, string> header = new Dictionary<string, string>();
    string userAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36";
    header.Add("User-Agent", userAgent);
    WWW www = new WWW("http://www.google.com", null, header);
    yield return www;
    // check for errors
    if (www.error == null)
    {
        util.debug("works");
    }
    else
    {
        // www.error and www.text both are empty
        util.debug("testing: WWW Error: " + www.error + www.text);
    }
}

提示:

在Unity应用程序向不属于您的服务器(http://www.google.com)发出网络请求时,最好添加一个用户代理头部,否则一些设备可能会��发布您的应用程序时失败。


谢谢,我也得出了这个结论!您提到要使用Android Monitor?您能在您的帖子中提供更多信息吗? - InsOp
1
下载Android Studio。它自带Android Monitor。当您的手机连接到计算机时,它将显示Android Monitor中发生的所有事情。您将看到所有日志和异常。 - Programmer

0

如果 Android 操作系统版本大于 Oreo(Android 8,API 级别 > 26),则必须在 AndroidManifest.xml 文件中启用 usesCleartextTraffic。此外,请确保已请求互联网权限

如果您正在使用 Unity 引擎 2019+ 版本,

您可以从 文件 --> 构建设置 --> 玩家设置 --> 发布设置 --> 自定义主清单 中启用自定义清单文件。

enter image description here

现在,您将在Assets/Plugins/Android文件夹下获得AndroidManifest.xml文件。

打开该文件并从中删除以下文件。

<!-- GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN-->

然后在其中添加Internet权限请求和usesCleartextTraffic属性。

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.unity3d.player"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.INTERNET" />
    <application android:usesCleartextTraffic="true">
        <activity android:name="com.unity3d.player.UnityPlayerActivity"
                  android:theme="@style/UnityThemeSelector">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>
    </application>
</manifest>

如果您使用的是Unity Engine 2018或之前的版本,

您可以使用文本编辑器(如记事本)创建一个名为AndroidManifest.xml的文件,并将上述清单文件内容粘贴到该文件中。

然后,在Assets文件夹下创建一个名为Plugins的文件夹。同样,在Plugins文件夹下创建一个名为Android的文件夹。最后,将新创建的AndroidManifest.xml文件放入Android文件夹中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接