Read,Write Access for PDF ML2 Unity with c#

Give us as much detail as possible regarding the issue you're experiencing.

Unity Editor version: 2022.3.7f1
ML2 OS version: 1.3.1
MLSDK version: 1.4.0-dev2
Host OS: (Windows 10 64Bit)

Error messages from logs (syntax-highlighting is supported via Markdown):

I would like to create PDF files on the ML2 and save them in the file system. Unity and C# are used as the development environment.
I have tried many different things, in the meantime I can at least save .txt files in the downloads, but whenever I want to save a PDF file it is 0 bytes in size or the log says that access to the path was not possible. I have already set the permissions MLPermission.WriteExternalStorage & MLPermission.ReadExternalStorage but still it does not work. I have also tried different paths, but none of them worked for PDF files.
I would be very grateful if you could provide me with a sample code for reading and writing on Magic Leap 2 with Unity and C# that allows me to save PDF files and read this PDF file again. In a later development step I would also like to use this code to store .json files in the file system. I also read that Android uses intents to persist files, but I couldn't figure out how to convert this Java code to work with C# using ML2.

@tifarke Unfortunately, writing this type of example is out side of the scope of the forum and may be related to the path you are writing to, for example if you are writing to a directory outside of your Applications persistent path you may need to request additional permissions to write in that folder or your file name might not be formatted correctly. That said, I have submitted the request for this example as feedback to our voice of customer team.

Magic Leap 2 uses the same Android file system as a standard Android 10 device which means that you should be able to use any of the examples online that demonstrate how to save and read data from the device's storage.

Writing to an internal path that is not the SD card would also be fine.
I cannot get write permission for the PDF file on any of the paths.
I have tried the following paths:

Application.persistentDataPath ("/storage/emulated/0/Android/data/com.UnityTechnologies.com.unity.template.urpblank/files")
Application.dataPath ("data/app/com.UnityTechnologies.com.unity.template.urpblank-LrcKqmkI6Bv3vG_F2lM6SA==/base.apk")
"/sdcard/Download/output.pdf";
"/sdcard/Android/data/output.pdf";
"/storage/emulated/output.pdf";
"/storage/emulated/0/Download/output.pdf";
"/persistent/output.pdf";
"/data/local/tmp/output.pdf";

I get the following error message when the code is trying to save the file:

UnauthorizedAccessException: Access to the path "/output.pdf" is denied.
11-08 19:52:23.907  7694  7715 E Unity   :   at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x00000] in <00000000000000000000000000000000>:0
11-08 19:52:23.907  7694  7715 E Unity   :   at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode) [0x00000] in <00000000000000000000000000000000>:0
11-08 19:52:23.907  7694  7715 E Unity   :   at iText.Commons.Utils.FileUtil.GetBufferedOutputStream (System.String filename) [0x00000] in <00000000000000000000000000000000>:0
11-08 19:52:23.907  7694  7715 E Unity   :   at iText.Kernel.Pdf.PdfWriter..ctor (System.String filename) [0x00000] in <00000000000000000000000000000000>:0
11-08 19:52:23.907  7694  7715 E Unity   :   at clickCreatePDF.TaskOnClick () [0x00000] in <00000000000000000000000000000000>:0
11-08 19:52:23.907  7694  7715 E Unity   :   at clickCreatePDF.Start () [0x00000] in <00000000000000000000000000000000>:0

Any help which path should work would also be helpful.
Any guidance towards solving the issue would be helpful.

For example the MLPermissions Method is a different method than the one used by android. At least it looks like that.

I recommend using the standard android Write and read permissions. For writing files, you'll need to request the WRITE_EXTERNAL_STORAGE permission. Additionally, only the Persistent Data Path would work without requesting access to the other folders. Here is more information about the changes to the android file system:

Mainly, Handle Scoped Storage : Android 10 introduced scoped storage, which restricts your app's access to external storage. With scoped storage, you can't directly write to the external storage. You'll need to use the system file picker to create or open files using an intent, such as ACTION_CREATE_DOCUMENT or ACTION_OPEN_DOCUMENT .

Here is an example of requesting the Write Permission

using UnityEngine;
using System.Collections;
using UnityEngine.Android;

public class ExampleScript : MonoBehaviour
{
    void Start()
    {
        if (!Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite))
        {
            Permission.RequestUserPermission(Permission.ExternalStorageWrite);
        }
    }
}

and a simple way to write to application persistent data

string path = Path.Combine(Application.persistentDataPath, "output.pdf");
File.WriteAllBytes(path, pdfBytes); // where pdfBytes is a byte array containing your PDF data

Overall, I recommend reaching out on the Unity forum or Discussion as they will be able to better assist you with general development questions.

Fun fact:

I needed to store the initial configuration files before the application started and then update them.

Unfortunately, after trying all the steps above and reading other comments, This is what worked for me.

To store data on the ML2, use this C# example
try
{
strDataPath = Path.Combine(Application.persistentDataPath, "SaveFile.txt");
File.WriteAllText(strDataPath, "Hello world");
}catch (Exception ex)
{
Debug.LogWarning("Nick ::" + ex.ToString());
}


What if you want to load SaveFile.txt before you run your program?

Application.persistentDataPath path is --> /storage/emulated/0/Android/data//files

The issue is the magic leap hub doesn't allow you to see it. So, to get there, you will need an ADB.exe explorer. I used ADB Explore by AlexSSB, which I loaded from the Microsoft store.

So to upload a file.

  1. run adb explore ( may options)
  2. Set path to Application.persistentDataPath.
    In my case program was localizationanchorplacement so the full path was : /storage/emulated/0/Android/data/com.titenn.localizationanchorplacement/files
  3. Drag file in.

I hope this helps!

1 Like

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.