WWW on PC OK but android failed

i use www to get microsoft speech recongnize like this:

 public IEnumerator IERecSound(AudioClip _clip, RecRes _res)
    {
        debugLog = new StringBuilder();
        byte[] bClip = null;
        try
        {
            bClip = SavWav.getByte(_clip);
        }
        catch (Exception _ex)
        {
            debugLog.AppendFormat("读取错误:{0}\n", _ex.ToString());
        }
        debugLog.AppendFormat("读取成功,len={0}\n",bClip.Length);
        Dictionary<string, string> headers = new Dictionary<string, string>();
        headers.Add("ContentType", "application/x-www-form-urlencoded");
        headers.Add("Ocp-Apim-Subscription-Key", key);
        WWW postData = new WWW(logInUrl, new byte[] { 0 }, headers);
        while (!postData.isDone)
        {
            yield return new WaitForSeconds(0.1f);
        }
        if (!string.IsNullOrEmpty(postData.error))
        {
            Debug.LogError(postData.error);
            debugLog.AppendFormat("授权错误:{0}\n", postData.error);
            yield break;
        }
        debugLog.AppendFormat("授权成功\n");
        string kAu = postData.text;
        headers = new Dictionary<string, string>();
        headers.Add("ContentType", "audio/wav; codec=audio/pcm; samplerate=16000");
        headers.Add("Transfer-Encoding", "chunked");
        headers.Add("User-Agent", "VirtualShopping");
        headers.Add("Authorization", "Bearer " + kAu);

        WWW recTex = new WWW(recUrl, bClip, headers);
        while (!recTex.isDone)
        {
            yield return new WaitForSeconds(0.1f);
        }
        if (!string.IsNullOrEmpty(recTex.error))
        {
            Debug.LogError(recTex.error);
            debugLog.AppendFormat("获取错误:{0}\n", recTex.error);
            yield break;
        }
        debugLog.AppendFormat("获取成功\n");
        //_res.text = recTex.text;
        JObject jo = JObject.Parse(recTex.text);
        if (((string)jo["RecognitionStatus"]).Contains("Success"))
        {
            _res.text = (string)jo["DisplayText"];
        }
        else
        {
            _res.text = "";
        }
    }

on PC it is ok. i recongnize my clipok.but when i make a “*.apk”, it is failed. www.erro = “400 bad requirest”!

i also make a text to speech test. it is run pc and andriod ok!

how can i do? unitors thanks!

text to speech code like this:

 private IEnumerator IEGetSound(string _text, AdClip _clip)
    {
        //string key = "89e8b92180c743e2af527d3aa7b2fe8b";
        Dictionary<string, string> headers = new Dictionary<string, string>();
        headers.Add("ContentType", "application/x-www-form-urlencoded");
        headers.Add("Ocp-Apim-Subscription-Key", key);
        WWW postData = new WWW(logInUrl, new byte[] { 0 }, headers);
        while (!postData.isDone)
        {
            yield return new WaitForSeconds(0.1f);
        }
        if (!string.IsNullOrEmpty(postData.error))
        {
            Debug.LogError(postData.error);
            yield break;
        }
        string kAu = postData.text;
        headers = new Dictionary<string, string>();
        headers.Add("ContentType", "application/ssml+xml");
        headers.Add("X-Microsoft-OutputFormat", "riff-16khz-16bit-mono-pcm");
        headers.Add("User-Agent", "VirtualShopping");
        headers.Add("Authorization", "Bearer " + kAu);
      
        string postdata = string.Format("{0}{1}{2}{3}", rStr, vStr, _text, eStr);
        WWW getSound = new WWW(e2pUrl, Encoding.UTF8.GetBytes(postdata), headers);
        while (!getSound.isDone)
        {
            yield return new WaitForSeconds(0.1f);
        }
        if (!string.IsNullOrEmpty(getSound.error))
        {
            Debug.LogError(getSound.error);
            yield break;
        }
        _clip.ac = getSound.GetAudioClip(true, false, AudioType.WAV);
        //AudioSource ads = ProcBasic.AddIndependentComponent<AudioSource>(gameObject);
    }

it is run ok on pc and andriod!

Can you tell which of your WWW requests fail?
My suspect is that failure happens because of this line:
headers.Add(“Transfer-Encoding”, “chunked”);

Try removing it, if it is of course the failing requests, as you do multiple requests.

i removed “headers.Add(“Transfer-Encoding”, “chunked”);” . it is failed on PC.

i upload my script, can you help me to check it!
thank you !

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

[System.Serializable]
public class BVData : System.Object
{
    public string str;
    [System.NonSerialized]
    public AudioClip clip;
    public string fileName;
}

[System.Serializable]
public class BVDtCtrl : System.Object
{
    public string path;
    public string resPath;
    public List<BVData> bvdts;
    public BVDtCtrl()
    {
        bvdts = new List<BVData>();
    }
}

public class BingVoice : MonoBehaviour
{
    // Use this for initialization
    void Start()
    {
        if (load)
        {
            preloadDVDtCtrl();
        }
        else if (text != null)
        {
            loadDataBVDCtrl();
            StartCoroutine(IEPlay(text));
        }
        //testRes = new RecRes();
        //yield return StartCoroutine(IERecSound(testClip, testRes));
        //Debug.Log(testRes.text);
    }
    StringBuilder debugLog;
    //string testTx;
    RecRes testRes;
    public bool isDebug=true;
    public GUIStyle debugStyle;
    public GUIStyle infoStyle;
    public GUIStyle uiStyle;
    void OnGUI()
    {
        if (isDebug)
        {
            if (GUILayout.Button("rectTest", uiStyle))
            {
                testRes = new RecRes();
                StartCoroutine(IERecSound(testClip, testRes));
            }
            if (testRes != null && testRes.text != null)
            {
                GUILayout.Label(testRes.text, infoStyle);
            }
            //GUI.color = Color.red;
            if (debugLog != null)
            {
                GUILayout.Label(debugLog.ToString(), debugStyle);
            }
        }
        //GUI.color = Color.white;
    }

    public string key = "89e8b92180c743e2af527d3aa7b2fe8b";
    public bool load;

    public BVDtCtrl dtCtrl;

    public void loadDataBVDCtrl()
    {
        for (int i = 0; i < dtCtrl.bvdts.Count; i++)
        {
            BVData dt = dtCtrl.bvdts[i];
            if (!string.IsNullOrEmpty(dt.fileName))
            {
                string path = dt.fileName;
                if (!string.IsNullOrEmpty(dtCtrl.resPath))
                {
                    path = string.Format("{0}/{1}", dtCtrl.resPath, dt.fileName);
                }
                UnityEngine.Object obj = Resources.Load(path);
                if (obj != null && obj is AudioClip)
                {
                    dt.clip = obj as AudioClip;
                    //Debug.LogFormat("load {0} ok", dt.str);
                }
            }
        }
       
    }

    public void preloadDVDtCtrl()
    {
        if (dtCtrl != null && !string.IsNullOrEmpty(dtCtrl.path) && Directory.Exists(dtCtrl.path))
        {
            StartCoroutine(IEPreLoadBVDtCtrl());
        }
    }
   
    private IEnumerator IEPreLoadBVDtCtrl()
    {
        for (int i = 0; i < dtCtrl.bvdts.Count; i++)
        {
            BVData dt = dtCtrl.bvdts[i];
            if (!string.IsNullOrEmpty(dt.str) &&
                !string.IsNullOrEmpty(dt.fileName))
            {
                string fp = string.Format("{0}.wav", Path.Combine(dtCtrl.path, dt.fileName));
               
                if (!File.Exists(fp))
                {
                    AdClip clip = new AdClip();
                    yield return StartCoroutine(IEGetSound(dt.str, clip));
                    if (clip.ac != null)
                    {
                        SavWav.Save(fp, clip.ac);
                        Debug.LogFormat("load {0} success!", dt.str);
                    }
                    else
                    {
                        Debug.LogFormat("load {0} failed!", dt.str);
                    }
                    yield return new WaitForSeconds(0.2f);
                }
                else
                {
                    Debug.LogFormat("{0} existed!", dt.str);
                }
            }
        }
        yield return new WaitForSeconds(0.1f);
    }
    // Update is called once per frame
    void Update()
    {

    }
    public string text;
    public string rStr;
    public string vStr;
    public string eStr;
    public string logInUrl = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";
    public string e2pUrl= "https://speech.platform.bing.com/synthesize";
    public string recUrl= "https://speech.platform.bing.com/speech/recognition/interactive/cognitiveservices/v1?language=zh-CN";
    public AudioSource ads;
    public AudioClip testClip;

    public class AdClip
    {
        public AudioClip ac;
    }

    public class RecRes
    {
        public string text;
    }

    public void play(string _text, bool _isTitle = false)
    {
        StartCoroutine(IEPlay(_text, _isTitle));
    }

    public IEnumerator IEPlay(string _text, bool _isTitle = false)
    {
        BVData b = null;
        if (!_isTitle)
        {
            b = dtCtrl.bvdts.Find(element => element.str == _text);
        }
        else
        {
            b = dtCtrl.bvdts.Find(element => element.fileName == _text);
        }
        if (b != null && b.clip != null)
        {
            ads.clip = b.clip;
            ads.Play();
            Debug.LogFormat("play {0} from res", _text);
        }
        else if(!_isTitle)
        {
            AdClip clip = new AdClip();
            yield return StartCoroutine(IEGetSound(_text, clip));
            if (clip.ac != null)
            {
                ads.clip = clip.ac;
                ads.Play();
                //添加到下载记录
                BVData newDt = new BVData();
                newDt.clip = clip.ac;
                newDt.str = _text;
                dtCtrl.bvdts.Add(newDt);
            }
        }
    }

    //https://docs.microsoft.com/zh-cn/azure/cognitive-services/Speech/api-reference-rest/bingvoiceoutput 参考资料
    //string postdata = "<speak version='1.0' xml:lang='zh - CN'><voice name='Microsoft Server Speech Text to Speech Voice(zh - CN, HuihuiRUS)' xml:gender='Female' xml:lang='zh - CN'>" + text + "</voice></speak>";

    private IEnumerator IEGetSound(string _text, AdClip _clip)
    {
        //string key = "89e8b92180c743e2af527d3aa7b2fe8b";
        Dictionary<string, string> headers = new Dictionary<string, string>();
        headers.Add("ContentType", "application/x-www-form-urlencoded");
        headers.Add("Ocp-Apim-Subscription-Key", key);
        WWW postData = new WWW(logInUrl, new byte[] { 0 }, headers);
        while (!postData.isDone)
        {
            yield return new WaitForSeconds(0.1f);
        }
        if (!string.IsNullOrEmpty(postData.error))
        {
            Debug.LogError(postData.error);
            yield break;
        }
        string kAu = postData.text;
        headers = new Dictionary<string, string>();
        headers.Add("ContentType", "application/ssml+xml");
        headers.Add("X-Microsoft-OutputFormat", "riff-16khz-16bit-mono-pcm");
        headers.Add("User-Agent", "VirtualShopping");
        headers.Add("Authorization", "Bearer " + kAu);
      
        string postdata = string.Format("{0}{1}{2}{3}", rStr, vStr, _text, eStr);
        WWW getSound = new WWW(e2pUrl, Encoding.UTF8.GetBytes(postdata), headers);
        while (!getSound.isDone)
        {
            yield return new WaitForSeconds(0.1f);
        }
        if (!string.IsNullOrEmpty(getSound.error))
        {
            Debug.LogError(getSound.error);
            yield break;
        }
        _clip.ac = getSound.GetAudioClip(true, false, AudioType.WAV);
        //AudioSource ads = ProcBasic.AddIndependentComponent<AudioSource>(gameObject);
    }

    public IEnumerator IERecSound(AudioClip _clip, RecRes _res)
    {
        debugLog = new StringBuilder();
        byte[] bClip = null;
        try
        {
            bClip = SavWav.getByte(_clip);
        }
        catch (Exception _ex)
        {
            debugLog.AppendFormat("读取错误:{0}\n", _ex.ToString());
        }
        debugLog.AppendFormat("读取成功,len={0}\n",bClip.Length);
        Dictionary<string, string> headers = new Dictionary<string, string>();
        headers.Add("ContentType", "application/x-www-form-urlencoded");
        headers.Add("Ocp-Apim-Subscription-Key", key);
        WWW postData = new WWW(logInUrl, new byte[] { 0 }, headers);
        while (!postData.isDone)
        {
            yield return new WaitForSeconds(0.1f);
        }
        if (!string.IsNullOrEmpty(postData.error))
        {
            Debug.LogError(postData.error);
            debugLog.AppendFormat("授权错误:{0}\n", postData.error);
            yield break;
        }
        debugLog.AppendFormat("授权成功\n");
        string kAu = postData.text;
        headers = new Dictionary<string, string>();
        headers.Add("ContentType", "audio/wav; codec=audio/pcm; samplerate=16000");
        //headers.Add("Transfer-Encoding", "chunked");
        headers.Add("User-Agent", "VirtualShopping");
        headers.Add("Authorization", "Bearer " + kAu);

        WWW recTex = new WWW(recUrl, bClip, headers);
        while (!recTex.isDone)
        {
            yield return new WaitForSeconds(0.1f);
        }
        if (!string.IsNullOrEmpty(recTex.error))
        {
            Debug.LogError(recTex.error);
            debugLog.AppendFormat("获取错误:{0}\n", recTex.error);
            yield break;
        }
        debugLog.AppendFormat("获取成功\n");
        //_res.text = recTex.text;
        JObject jo = JObject.Parse(recTex.text);
        if (((string)jo["RecognitionStatus"]).Contains("Success"))
        {
            _res.text = (string)jo["DisplayText"];
        }
        else
        {
            _res.text = "";
        }
    }
}

It looks more like a server-side issue. Your server does not support non-chunked requests?

You should probably remove your API key/s from your post

Otherwise someone might copypasta your code and reuse it (and perhaps if their app/use is badly behaved your app would be penalised)

Anyway if the server needs chunked data saying you will send it chunked data with a header and then not actually sending chunked data seems like the kind of thing that will fail randomly. Might be down to payload size of tests rather than platform perhaps?

For troubleshoot networking issues capturing what is sent and comparing it can be helpful.