I want to download a song from an online server and save it in the device memory. Then recall the saved song from the device memory.
This is done correctly with the following code in Windows, but in the Android platform, only the file is saved correctly, but the file is not called and executed from the device memory and gives an error.
private void Start()
{
Adress = new WWW("**WebAdress**");
}
public void DownloadButton()
{
StartCoroutine(LoadMp3FromWeb());
}
IEnumerator LoadMp3FromWeb()
{
WWW www = Adress;
Adress = www;
yield return www;
System.IO.File.WriteAllBytes((Application.persistentDataPath + ".mp3"), www.bytes);
}
public void LoadButton()
{
StartCoroutine(LoadAudioClip());
}
IEnumerator LoadAudioClip()
{
using (UnityWebRequest uwr = UnityWebRequestMultimedia.GetAudioClip((Application.persistentDataPath + ".mp3"), AudioType.MPEG))
{
yield return uwr.SendWebRequest();
Musics = DownloadHandlerAudioClip.GetContent(uwr);
myClip.clip = Musics;
myClip.Play();
}
}
}
For loading the clip from memory you don't need to send WebRequests to the persistent data path. As that path doesn't exist in the web, it exists on your device only. use System.IO.File.ReadAllBytes instead.
Related
Using Xamarin.Forms, has the way to write to file changed since Android 8.0?
I updated an existing project of mine, which includes a very simple function to write a text file to local storage, but after running the app and testing the write to file part, it just freezes and crashes out. There are no errors in the console or even evidence of it doing anything.
My function is as such:
public void Submit_Clicked(object sender, EventArgs e)
{
{
string text = NameEntry.Text;
string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string filename = Path.Combine(path, "DeviceProfile.txt");
File.WriteAllText(filename, text);
}
catch(Exception ex)
{
DisplayAlert("Error:", ex.Message.ToString(), "Ok");
}
}
I cant see why this shouldn't work. Does someone know any reason why this wouldn't?
Like Jason said, the code below and the code you provided both work to write a text file to local storage.
string text = NameEntry.Text;
var path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "DeviceProfile.txt");
using (var writer = File.CreateText(backingFile))
{
await writer.WriteLineAsync(text);
}
You could read the text from the file to check.
public async Task<string> ReadCountAsync()
{
var backingFile = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "DeviceProfile.txt");
if (backingFile == null || !File.Exists(backingFile))
{
return null;
}
var text = string.Empty;
using (var reader = new StreamReader(backingFile, true))
{
var str = await reader.ReadToEndAsync();
text = str;
}
return text;
}
The path Environment.SpecialFolder.Personal you used to save the file is internal storage.
In Internal Storage, you couldn't see the files without root permission. If you want to view it, you could use adb tool. Please check the way in link.
How to write the username in a local txt file when login success and check on file for next login?
I am trying run a local server for a Xamarin.Forms WebView. This is to get around CORS, and so the html can be structured like a normal page. This works for UWP and iOS, but Android always comes up with an ERR_CONNECTION_REFUSED. Some further details/things I have tried:
The App is running it's own server, so it is not the case of trying to access a server on a separate device.
Internet permission is enabled.
The path to the files do exist, otherwise the Webserver would fail to start.
Link to the local server nuget package: https://github.com/unosquare/embedio
Below is an outline of the code I'm using. In practise, I'm using a custom renderer, injecting Javascript to access platform features, etc. but this should simplify it:
The class that creates and starts the WebServer with EmbedIO:
public class LocalWebServer: IDisposable
{
public static string Url = "http://localhost:8787/";
private readonly string _filePath;
private WebServer _server;
public LocalWebServer(string filePath)
{
_filePath = filePath;
}
public void StartWebServer()
{
_server = new WebServer(Url);
_server.RegisterModule(new LocalSessionModule());
_server.RegisterModule(new StaticFilesModule(_filePath));
_server.Module<StaticFilesModule>().UseRamCache = true;
_server.Module<StaticFilesModule>().DefaultExtension = ".html";
_server.Module<StaticFilesModule>().DefaultDocument = "index.html";
_server.Module<StaticFilesModule>().UseGzip = false;
Task.Factory.StartNew(async ()=>
{
Debug.WriteLine("Starting Server");
await _server.RunAsync();
});
}
public void Dispose()
{
_server?.Dispose();
}
}
Code which starts the server and displays the webview:
public App()
{
InitializeComponent();
//Create and display a Webview
_webView = new WebView();
MainPage = new ContentPage()
{
Content = _webView,
};
}
protected override async void OnStart()
{
//Service which can initialize app for first time use, and stores
//the folder location for the html page on each platform
var htmlService = DependencyService.Get<IHandleHtmlContentService>();
//Local webserver
var localWebServer = new LocalWebServer(htmlService.DirectoryPath);
//This is just a function that loads the html content from the
//bundle resource or assets into a folder. Will only really
//matter during the first time the App boots up.
await htmlService.InitializeHtmlContent();
//Start the Webserver
localWebServer.StartWebServer();
//Navigate to the webserver
_webView.Source = LocalWebServer.Url;
}
I'v been bashing my head on this for a while, so any help would be appreciated. If you need any more details, let me know.
Turns out, Android has no concept of "localhost" (at least from what I can read). Instead, I need to find the IP Address of my device. I have done this with the following code:
public class LocalWebServer: IDisposable
{
public readonly string Url;
...
public LocalWebServer(string filePath)
{
_filePath = filePath;
Url = "http://" + GetLocalIpAddress() + ":8787/";
}
...
private static string GetLocalIpAddress()
{
var listener = new TcpListener(IPAddress.Loopback, 0);
try
{
listener.Start();
return ((IPEndPoint)listener.LocalEndpoint).Address.ToString();
}
finally
{
listener.Stop();
}
}
}
Code was found on this Xamarin Forums post: https://forums.xamarin.com/discussion/42345/simple-android-http-listener-not-working
I am trying to load an object at run time from downloaded assetbundle in android local storage but no result is found. Though the assetbundle exists in local storage of my android device.
Please somebody help me to do so, following is the code which I have written:
public GameObject obj;
IEnumerable LoadObject()
{
AssetBundle bundle = AssetBundle.CreateFromFile(Application.persistentDataPath + "/androidassetbundle4");
yield return bundle;
AssetBundleRequest request = bundle.LoadAssetAsync("boat", typeof(GameObject));
yield return request;
obj = request.asset as GameObject;
obj.transform.position = new Vector3(0.08f, -2.345f, 297.54f);
obj.transform.Rotate(350.41f,400f,20f);
obj.transform.localScale = new Vector3(1.0518f, 0.998f, 1.1793f);
Instantiate(obj);
bundle.Unload(false);
}//end of Method LoadObject
CreateFromFile is deprecated. LoadFromFile and LoadFromFileAsync are the new functions to use. Not sure if that is the problem but the code below should do it.
IEnumerator LoadObject()
{
AssetBundleCreateRequest bundle = AssetBundle.LoadFromFileAsync(System.IO.Path.Combine(Application.streamingAssetsPath, "assetbundlename"));
yield return bundle;
AssetBundle myLoadedAssetBundle = bundle.assetBundle;
if (myLoadedAssetBundle == null)
{
Debug.Log("Failed to load AssetBundle!");
yield break;
}
AssetBundleRequest request = myLoadedAssetBundle.LoadAssetAsync<GameObject>("boat");
yield return request;
obj = request.asset as GameObject;
obj.transform.position = new Vector3(0.08f, -2.345f, 297.54f);
obj.transform.Rotate(350.41f, 400f, 20f);
obj.transform.localScale = new Vector3(1.0518f, 0.998f, 1.1793f);
Instantiate(obj);
myLoadedAssetBundle.Unload(false);
}
you can't access file in local storage via CreateFromFile or LoadFromFile in android,instead use LoadFromCacheOrDownload and in android this is the address of your StreamingAssets : "jar:file://" + Application.dataPath + "!/assets/"
as mentioned in unity docs : StreamingAssets
I have been trying to download and load the texture or other models from a WEB at run time by using WWW class.
The app works well on Unity Editor but when I deploy it on android device it doesn't load/download the texture.
Please somebody guide me.
I have used the following code in script.
void Start()
{
StartCoroutine(loadMovie());
}
IEnumerator loadTexture()
{
WWW www = new WWW("http://images.earthcam.com/ec_metros/ourcams/fridays.jpg");
yield return www;
// Debug.Log(www.movie.duration + " <--- wwww");
if (www.error != null)
{
Debug.Log("Error: Can't load texture! - " + www.error);
yield break;
}
else
{
Texture2D texture = www.texture as Texture2D;
Debug.Log("Texture loaded");
Debug.Log(www.texture);
gameObject.GetComponent<Renderer>().material.mainTexture = texture;
}
}
First of all, remove Debug.Log(www.texture); from the code, then re-try your code.
You have IEnumerator loadTexture() but you are calling StartCoroutine(loadMovie()); . This means that you are likely calling another function or maybe that's a type in your question.
void Start()
{
StartCoroutine(loadTexture());
}
IEnumerator loadTexture()
{
WWW www = new WWW("http://images.earthcam.com/ec_metros/ourcams/fridays.jpg");
//Wait for download to finish
while(!www.isDone){
Debug.Log("Progress: "+www.progress);
yield return null;
}
if ((www==null) || (www.error != null))
{
Debug.Log("Error: Can't load texture! - " + www.error);
yield break;
}
gameObject.GetComponent<Renderer>().material.mainTexture = www.texture;
}
Not compiled but should work.
EDIT:
From the file you sent, change the Minimum API Level to 4.1.
I am making an application in Unity3D and I have a problem with the file .obb. After downloading the file .obb from my dropbox try to open the next scene and tells me I can not find it. If I close the application and return open functioning OK. What can be?
using UnityEngine;
using System.Collections;
using System.IO;
using System;
using UnityEngine.UI;
public class DownloadFile : MonoBehaviour {
private string path;
private string url = "";
private float m_CurrentValue = 0;
public GameObject btnStart;
private string nextScene = "Splash";
void log( string t )
{
print("MYLOG " + t);
}
// Use this for initialization
void Start ()
{
CheckObb ();
}
// Update is called once per frame
void Update () {
}
void CheckObb()
{
if (!GooglePlayDownloader.RunningOnAndroid())
{
log ( "Use GooglePlayDownloader only on Android device!");
return;
}
string expPath = GooglePlayDownloader.GetExpansionFilePath();
if (expPath == null)
{
log("External storage is not available!");
}
else
{
string package = GooglePlayDownloader.Package();
int version = GooglePlayDownloader.Version();
path = String.Format("{0}/main.{1}.{2}.obb", expPath, version, package);
url = String.Format("https://www.dropbox.com/s/xxxxxxxxxxxxxx/main.{0}.{1}.obb?dl=1", version, package);
if (File.Exists(path))
{
// After downloading the file if you close the game and you become open, OK ¿?
Application.LoadLevel(nextScene);
}
else
{
//check if directory doesn't exit
if(!Directory.Exists(expPath))
{
//if it doesn't, create it
Directory.CreateDirectory(expPath);
}
btnStart.SetActive(true);
}
}
}
// Click Start button download obb
public void ClickStart()
{
btnStart.SetActive(false);
StartCoroutine(DownloadObb());
}
// Download obb
IEnumerator DownloadObb() {
WWW download = new WWW(url);
while( !download.isDone ) {
m_CurrentValue = download.progress * 100;
yield return null;
}
if (!string.IsNullOrEmpty(download.error)) {
//Error
} else
{
// success!
File.WriteAllBytes (path, download.bytes);
// Here says that there is the scene
Application.LoadLevel(nextScene);
}
}
}
I tried to upload the apk and obb as alpha version in the developer console but when I go to download the .obb tells me this:
"Download failed because the resources could not be found"
Thanks.
I follow this tutorial in order to split my Unity app into *.obb file. It help me a lot.
Now, when I was performing my test in GooglePlay as an Alpha version everything goes OK, the download of the obb file and the process in the app but it doesn`t load my first scene.
It took me a lot to notice that when I put the loader as the scene 0 my index to load the next Scene was wrong. I know it is a poor error but thats the History behind my 10 hours research.
Hope you'll find useful.