www request not completing on Android 9 (Pie) Unity3d - c#

I have a simple script which creates a www request in game to check which country this apk running. It was working fine before android 9 OS devices but failed on android 9 OS devices. My www.error is giving an unknown error string.
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class GeoData : MonoBehaviour
{
private void Start()
{
StartCoroutine(GetText());
}
IEnumerator GetText()
{
UnityWebRequest www = UnityWebRequest.Get("http://ip-api.com/json");// I also changed www string but all in vein
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
//above Android 8 os devices, its comes here and debug "Unknow error"
Debug.Log("Done with Error: " + www.error);
}
else
{
Debug.Log("Final data is ="+ www.text);
string stringToSplit = www.text;
char[] splitters = { ',', ':', '"' };
string[] splittedString = stringToSplit.Split(splitters, System.StringSplitOptions.RemoveEmptyEntries);
foreach (var item in splittedString)
{
Debug.Log(item); // Country is at 6th index
}
}
}
}

Ok I have figured out what was the problem..
A non-secure URL, and it's now prohibited in Android 9 Pie.
you can't request.
so URL must be sure like this (https)

Related

Unity, MacOS, cannot load audio from StreamingAssets using www.SendWebRequest()

I am working on an app targeting Windows, built in Unity.
All the audio files are in streamingAssets so the client can replace them and customize the app.
I have the following code loading the audio files into Audio Sources and it's working fine on Windows.
void SetAudioFromStreamingAssets()
{
if (string.IsNullOrEmpty(StreamingAssetFilePath)) return;
string fullpath = Application.streamingAssetsPath + "/" + StreamingAssetFilePath;
if (!File.Exists(fullpath)) return;
StartCoroutine(SetAudioClipFromFile(source,fullpath));
}
IEnumerator SetAudioClipFromFile(AudioSource audioSource, string path)
{
using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(path, AudioType.UNKNOWN))
{
yield return www.SendWebRequest();
if (www.isNetworkError)
{
VisDebug.AppendTxt("ERROR. Could not load music file: " + www.error, true);
}
else
{
AudioClip myClip = DownloadHandlerAudioClip.GetContent(www);
audioSource.clip = myClip;
}
}
}
A colleage of mine is trying to work on the project but he only has a mac. And the audio is not loading on his mac.
The code is reaching this line..
VisDebug.AppendTxt("ERROR. Could not load music file: " + www.error, true);
So File.Exists is true, and also www.isNetworkError is true.
and the www.error is...
Cannot connect to destination host
EDIT
The answer below is correct and just fyi here is an example of what the path needs to look like on macos.
file:///Users/spoopy/Documents/GitHub/Thing/Assets/StreamingAssets/GameLoad.wav
You have to prefix your path with file:// on MacOS and Linux.
You could put something like this after your variable definition.
#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
fullpath ="file://" + path);
#endif
Source

XAMPP becomes super slow after some time

Does anyone ever encounter the MYSQL in XAMPP being super slow after sometime?
I have a unity application that asking a string to be downloaded with this php script.
<?php
include 'Config.php'; // Just a normal mysqli connection setup
//the post from Unity.
$var_uniqueID = $_POST['uniqueID_Post'];
$conn = OpenCon(); // open connection
//create a query
$sql = "SELECT
var_name,
var_value
FROM variable_current_values
WHERE uniqueID = '".$var_uniqueID."' ";
$result = mysqli_query($conn, $sql);
if( mysqli_num_rows($result) > 0)
{
//show data for each row
while($row = mysqli_fetch_assoc($result))
{
echo "".$row['var_name'] .
"|".$row['var_value'] . "";
}
}
CloseCon($conn); // close the connection
?>
This PHP script is being called with c# script of UnityWebRequest
//www variable
private UnityWebRequest unityWebRequest;
void Update ()
{
if (unityWebRequest == null)
{
//fetch The data Widget
StartCoroutine(RealDataFetchWhere(this.name));
}
}
private IEnumerator RealDataFetchWhere(string _uniqueIDPost)
{
//gives the unique key
WWWForm fetchingForm = new WWWForm();
fetchingForm.AddField("uniqueID_Post", _uniqueIDPost);
//load and wait until the data is downloaded
unityWebRequest = UnityWebRequest.Post(**thePHPLink**, fetchingForm);
yield return unityWebRequest.SendWebRequest();
string data = unityWebRequest.downloadHandler.text;
print("the Data is : " + data);
}
At first everything seems to be fine. Data is downloaded perfectly(almost in realtime speed).
However after like more than 10 minutes, the XAMPP mySQL starting to slow down considerably. I try to modified the data manually in XAMPP and it takes about 5 - 8 seconds until the "row is affected"
If i leave them longer without closing my unity program, XAMPP start to freeze and disconnected.
Does anyone know the solutions to counter this problem ?

CAn't connect to a local server (XAMPP) from HoloLens

I'm trying to build a connection between the HoloLens and XAMMP server.
when i test the app on unity, it works fine but it doesn't work on the device.
Ps: you can access the server when writing the IP address of the server In Microsoft Edge.
Windows defender firewall is disabled
Network capabilities are checked (publishing settings)
XAMPP server is reconfigured to be accessible to all devices
what am I missing here ? how can I make this work ?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class test : MonoBehaviour
{
public Text playerDisplay;
public Text score;
public Button submit;
public InputField nameField;
public GameObject bb;
public Text Error;
public void CallLogIn()
{
StartCoroutine(Loginplayer());
}
IEnumerator Loginplayer()
{
WWWForm form = new WWWForm();
form.AddField("name", nameField.text);
WWW www = new WWW("http://192.168.1.100/sqlconnect/test.php", form);
yield return www;
if (www.text[0] == '0')
{
DBManager.username = nameField.text;
DBManager.score = int.Parse(www.text.Split('\t')[1]);
playerDisplay.text = "player: " + DBManager.username;
score.text = "score: " + DBManager.score;
bb.SetActive(true);
}
else
{
Error.text = "save failes. Error #" + www.error;
bb.SetActive(false);
}
DBManager.logedOut();
}
}
I encountered this kind of issue as well. I tried to connect the HoloLens to different entities (MySQL DB, OPCUA Server) but it always fails on the HoloLens (working fine in the editor). Searching on google only revealed similar problems from other people, but no solutions.
So my solution is to use the WWW class to receive data from a HTML-Webserver that hosts plain text. This server (I used nodejs and python) executes the query to the database depending on the GET-request it receives from the HoloLens.

Writing to a Text file on a server from Unity

Hi I have been making an app in Unity and I have been trying to add code that will log User actions i.e. they have made a certain game object appear. What I am trying to do is write to a .txt file stored on a server I have the following code which is based on:
http://answers.unity3d.com/questions/984290/upload-txt-file-to-server-using-php.html
and they suggest it works, for me it is not writing anything to the file.
Here is my PHP code (SaveData.php):
<?php
$Action = $_GET["action"];
$Date = date('Y/m/d H:i:s');
$myFile = "TestingData.txt";
$fh = fopen($myFile, 'a') or die("can't open file");
fwrite($fh,$Action . "," . $Date . "\n");
fclose($fh);
?>
And here is the C# (SaveData.cs) I am attaching to the game objects I change the Action value in the inspector window:
using UnityEngine;
using System.Collections;
public class SaveData : MonoBehaviour {
public string postDataURL = "http://arinstructionman.byethost7.com/SaveData.php?"; //add a ? to your url
public string Action;
void Start()
{
StartCoroutine(PostData(Action));
}
IEnumerator PostData(string action)
{
string post_url = postDataURL + "action=" + WWW.EscapeURL(action);
WWW data_post = new WWW(post_url);
yield return data_post;
if (data_post.error != null)
{
print("There was an error saving data: " + data_post.error);
}
}
}
If I copy the post_url value and run it in the browser it seems to work fine, can anyone advise what I am doing wrong?
post_url output:
http://arinstructionman.byethost7.com/SaveData.php?action=Plane+Visible
Any help is much appreciated.
I would suggest trying this with $_POST instead of $_GET and see if you get a different response.
Also, you can use file_put_contents to open, write, and close the file all in one line, and using the FILE_APPEND flag to prevent overwriting the existing file. If the file does not exist, this will also create the file for you.
<?php
if(!isset($_POST["action"]))
{
echo ("NO DATA RECIEVED");
return;
}
$action = $_POST["action"];
$date = date('Y/m/d H:i:s');
$data = "{$action},{$date}\n";
$myFile = "TestingData.txt";
if(file_put_contents($myFile, $data, FILE_APPEND))
echo ("success");
else
echo ("failed to write file);
?>
And use WWWform to POST data to the PHP file:
public string postDataURL = "http://arinstructionman.byethost7.com/SaveData.php";
public string Action = "some action";
void Start()
{
StartCoroutine(PostData(Action));
}
IEnumerator PostData(string action)
{
WWWForm form = new WWWForm();
form.AddField("action", action);
WWW dataPost = new WWW(postDataURL, form);
yield return dataPost;
if (dataPost.error != null)
print("There was an error saving data: " + data_post.error);
else
print(dataPost.text);
}
)
Just in case someone is trying to implement that and it doesn't work like it was the case for me.
I found a fix, for sure is not the best implementation, but at least it works for the moment :
If your server doesn't use PHP5 you will have to use PHP4 function
(coming from : http://memo-web.fr/categorie-php-126/ ):
function file_put_contents_PHP4($myFile, $data) {
$f = #fopen($myFile, 'w');
if (!$f) {
echo ("failed to write file");
return false;
} else {
$resultat= fwrite($f, $data);
fclose($f);
echo ("success");
return $resultat;
}
}
For sure we could test if PHP5 is available with something like, but my php knowledge is kind of bad ahah :
if (!function_exists('file_put_contents'))
{
function file_put_contents_PHP4...
{
The Scripts :
SaveData.php, in your server online:
<?php
$action = $_POST["action"];
$data = "{$action}";
$myFile = "TestingData.txt";
if($action == "")
{
echo ("NO DATA RECIEVED");
return;
}
else
file_put_contents_PHP4($myFile, $data);
function file_put_contents_PHP4($myFile, $data) {
$f = #fopen($myFile, 'w');
if (!$f) {
echo ("failed to write file");
return false;
} else {
$resultat= fwrite($f, $data);
fclose($f);
echo ("success");
return $resultat;
}
}
?>
Unity c# Script :
[SerializeField] private string postDataURL = "http://yourebsite.com/SaveData.php";
[SerializeField] private string Action = "some action";
void Start()
{
StartCoroutine(PostData(Action));
}
IEnumerator PostData(string action)
{
WWWForm form = new WWWForm();
form.AddField("action", action);
WWW dataPost = new WWW(postDataURL, form);
yield return dataPost;
if (dataPost.error != null)
print("There was an error saving data: " + dataPost.error);
else
print(dataPost.text);
}
Don't forget to put an empty text file "TestingData.txt" next to "SaveData.php" into the server.
Don't forget as well to add the correct adress to SaveData.php in the Inspector.
I uploaded them to an old personal server using Filezilla and everything is working as intended.
Cheers :-)

How to stream/download&play an audio from URL?

I need to stream or download and play an audio getted from an URL in Unity3D, running on iOS.
The Audio comes from a text-to-audio service and I need to play it on Unity:
http://api.ispeech.org/api/rest?apikey=...&action=convert&voice=eurspanishfemale&text=hola+que+tal
I've been googling all the morning and not found a valid solution...
There is a code snippet in the Unity3D documentation (WWW-audioClip,WWW.GetAudioClip), but is not working, I have debugged and the error says it couldn't open the file.
using UnityEngine;
using System.Collections;
public class AudioURLScript : MonoBehaviour {
public string url = "http://api.ispeech.org/api/rest?apikey=...&action=convert&voice=eurspanishfemale&text=hola+que+tal";
public AudioSource source;
void Start() {
WWW www = new WWW("file://"+url);
source = GetComponent<AudioSource>();
source.clip = www.GetAudioClip(false,true);
}
void Update() {
if (!source.isPlaying && source.clip.isReadyToPlay)
source.Play();
}
}
Thanks
SOLUTION
This is my working solution right now.
void Start(){
StartCoroutine(DownloadAndPlay("http://api.ispeech.org/api/rest?apikey=...&action=convert&voice=eurspanishfemale&text=Hola+que+tal"));
}
IEnumerator DownloadAndPlay(string url)
{
WWW www = new WWW(url);
yield return www;
AudioSource audio = GetComponent<AudioSource>();
audio.clip = www.GetAudioClip(false, true,AudioType.MPEG);
audio.Play();
}
You don't mention the platform you are on, so I'm going to assume Windows.
Unity Windows runtime only supports WAV or OGG. The link to the audio service file you provided is downloading as a MP2 Audio File (common in broadcasting). Unity will not be able to play that (or MP3).
For reference, Android and iOS platforms do support MP3 (but not MP2).
So, you're first issue is to make sure your audio source is in compatible format.
The code sample is incorrect for 3 reasons;
the URL is https: (which tells unity to download from the internet) but then you pre-pend file: to it (which tells unity to load from the local file system). So you should pick one or the other.
it wouldn't work if you picked https because that particular link (I know it's just an example) but it requires a user to be logged in to the service (and using cookies to know that), so it doesn't send you an audio file, it sends you a HTML page telling the user to login or register.
As #fafase says, the WWW must be placed within a co-routine, so that it can download over multiple frames.
OK, here's what I suggest.
If you can know the audio files a head of time, download them and transcode to OGG (if windows) or MP3 (if mobile) and upload them to your own server (say Amazon S3, or a $10 a month unlimited website).
Then, use this code to download and play it:
StartCoroutine(DownloadAndPlay("http://myserver.com/audio/test.ogg"));
IEnumerator DownloadAndPlay(string url)
{
WWW www = new WWW(url);
yield return www;
AudioSource audio = GetComponent<AudioSource>();
audio.clip = www.GetAudioClip(false, false);
audio.Play();
}
A WWW object is a wrapper for a HTTP request, containing the creation of the connection, the transfer of the data and the closing of the connection (and some extra actions).
This does not happen in one frame and requires a coroutine.
void Start() {
StartCoroutine(GetAudio(url));
}
private IEnumerator GetAudio(string url)
{
WWW www = new WWW("file://"+url);
yield return www;
if(string.IsNullOrEmpty(www.error) == false)
{
Debug.Log("Did not work");
yield break;
}
source = GetComponent<AudioSource>();
source.clip = www.GetAudioClip(false,true);
}
The WWW package got deprecated and Unity3D recommended using the UnityWebRequest package for API communications.
Try the following code snippet to download audio from a URL and play it using the AudioSource gameObject.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class DownloadAndPlay : MonoBehaviour
{
public AudioSource audioSource;
// Start is called before the first frame update
void Start()
{
string URL = "http://api.ispeech.org/api/rest?apikey=...&action=convert&voice=eurspanishfemale&text=hola+que+tal";
StartCoroutine(DownloadAudio(URL));
}
// Update is called once per frame
void Update()
{
}
IEnumerator DownloadAudio(string URL) {
using (UnityWebRequest www_audio = UnityWebRequestMultimedia.GetAudioClip(URL, AudioType.MPEG)) {
yield return www_audio.SendWebRequest();
if (www_audio.isNetworkError) {
Debug.Log(www_audio.error);
} else {
AudioClip clip = DownloadHandlerAudioClip.GetContent(www_audio);
audioSource.clip = clip;
audioSource.Play();
}
}
}
}
For more: https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequest.html

Categories