繁体   English   中英

将文件从资产文件夹复制到外部android内存统一

[英]Copy file from asset folder to external android memory unity

我想将我的资产文件夹中的某些文件复制到android设备。 你怎么做呢?

我尝试了几种方法,例如通过调试打开文件,它可以在PC上运行。 但是,当我将其转移到android设备后,它不起作用或将其复制了。

    public void OpenPDF(string filename) //this opens the file I have in my pc. Via debugging in Unity.
    {
        TextAsset pdfTem = Resources.Load("PDFs/" + filename, typeof(TextAsset)) as TextAsset;

        System.IO.File.WriteAllBytes(Application.persistentDataPath + "/" + filename + ".pdf", pdfTem.bytes);

        Application.OpenURL(Application.persistentDataPath + "/" + filename + ".pdf");

    }

    public void openPDFfromSD()
    {
        Application.OpenURL("/mnt/sdcard/openme.pdf"); //this doesn't open the PDF file I have in my sd card.
    }

    public void legitOpen(string nameOfFile) //this opens the file I have in my pc. Via debugging in Unity.
    {
        string realPath = Application.persistentDataPath + "/" + nameOfFile + ".pdf";
        if (!System.IO.File.Exists(realPath))
        {
            if (!System.IO.Directory.Exists(Application.persistentDataPath + "/PDFs/"))
            {
                System.IO.Directory.CreateDirectory(Application.persistentDataPath + "/PDFs/");
            }
            WWW reader = new WWW(Application.streamingAssetsPath + "/PDFs/" + realPath);
            while (!reader.isDone) { }
            System.IO.File.WriteAllBytes(realPath, reader.bytes);
        }
        Application.OpenURL(realPath);
    }

通常,您不应该直接使用字符串连接来构建系统路径。

而是始终使用Path.Combine ,它会根据您的目标平台自动使用正确的路径分隔符( /\\ )。

同样,稍后在new WWW您已经在realPath添加了领先的Application.streamingAssetsPathApplication.persistentDataPath

public void OpenPDF(string filename)
{
    TextAsset pdfTem = Resources.Load("PDFs/" + filename, typeof(TextAsset)) as TextAsset;

    var filePath = Path.Combine(Application.persistentDataPath, filename + ".pdf";

    System.IO.File.WriteAllBytes(filePath), pdfTem.bytes);

    Application.OpenURL(filePath);

}

public void legitOpen(string nameOfFile)
{
    string realPath = Path.Combine(Application.persistentDataPath, nameOfFile + ".pdf");
    if (!System.IO.File.Exists(realPath))
    {
        if (!System.IO.Directory.Exists(Path.Combine(Application.persistentDataPath, "PDFs"))
        {
            System.IO.Directory.CreateDirectory(Path.Combine(Application.persistentDataPath, "PDFs"));
        }
        WWW reader = new WWW(Path.Combine(Application.streamingAssetsPath, "PDFs", nameOfFile + ".pdf");
        while (!reader.isDone) { }
        System.IO.File.WriteAllBytes(realPath, reader.bytes);
    }
    Application.OpenURL(realPath);
}

顺便说一句,如果您想防止应用程序完全冻结直到加载完成,我建议您使用CoroutineUnityWebRequest.Get

public void legitOpen(string nameOfFile)
{
    StartCoroutine(legitOpenRoutine(nameOfFile));
}

private IEnumerator legitOpenRoutine(string nameOfFile)
{
    string realPath = Path.Combine(Application.persistentDataPath, nameOfFile + ".pdf");
    if (!System.IO.File.Exists(realPath))
    {
        if (!System.IO.Directory.Exists(Path.Combine(Application.persistentDataPath, "PDFs"))
        {
            System.IO.Directory.CreateDirectory(Path.Combine(Application.persistentDataPath, "PDFs"));
        }
        using (var reader = new UnityWebRequest.Get(Path.Combine(Application.streamingAssetsPath, "PDFs", nameOfFile + ".pdf"))
        {
            yield return reader.SendWebRequest();

            if (webRequest.isNetworkError)
            {
                Debug.Log(pages[page] + ": Error: " + webRequest.error);
                return;
            }                

            System.IO.File.WriteAllBytes(realPath, reader.bytes);
        }
    }
    Application.OpenURL(realPath);
}

甚至使用CopyToAsync完全使用异步方法

public void legitOpen(string nameOfFile)
{
    legitOpenAsync(nameOfFile);
}

private async void legitOpenAsync(string nameOfFile)
{
    var realPath = Path.Combine(Application.persistentDataPath, nameOfFile + ".pdf");

    var pdfPath = Path.Combine(Application.persistentDataPath, "PDFs");

    if (!System.IO.File.Exists(realPath))
    {
        if (!System.IO.Directory.Exists(pdfPath)
        {
            System.IO.Directory.CreateDirectory(pdfPath);
        }

        using(var sourceFile = File.Open(Path.Combine(Application.streamingAssetsPath, "PDFs", nameOfFile + ".pdf"), FileMode.Open, FileAccess.Read, FileShare.Read)
        {
            using(var targetFile = File.Open(realPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write))
            {
                await sourceFile.CopyToAsync(targetFile);
            }
        }
    }

    Application.OpenURL(realPath);
}

然而

请注意Application.OpenURL

Android :由于Android 7.0中的安全性更改( 更多信息 ), Application.OpenURL不能再用于打开本地应用程序文件 ,您需要使用FileProvider ,它允许您与其他应用程序共享文件。

iOSApplication.OpenURL 不能用于打开本地文件

因此,这根本不起作用

public void openPDFfromSD()
{
    Application.OpenURL("/mnt/sdcard/openme.pdf");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM