Skip to content

Conversation

samnyan
Copy link
Contributor

@samnyan samnyan commented May 6, 2022

PR for #22
Allow targeting SDK to Android 12

A preview build can download here.
https://github.com/samnyan/techmania/releases/tag/1.0.2-android

samnyan added 6 commits April 25, 2022 21:18
* Move critical System.IO call to UniversalIO.
* Add custom Android storage access plugin.
* Support content:// uri
Add support for track editor saving.
Hide track create when enabling custom location, since it won't work.
Copy link
Member

@macmillan333 macmillan333 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like TECHMANIA/Assets/Plugins/AndroidNativeIO/lib-release.aar is a compiled Android library.

  • Is this the library that cn.samnya.nativeandroid.io refers to?
  • Is the source code of this library available?

@samnyan
Copy link
Contributor Author

samnyan commented May 7, 2022

Looks like TECHMANIA/Assets/Plugins/AndroidNativeIO/lib-release.aar is a compiled Android library.

  • Is this the library that cn.samnya.nativeandroid.io refers to?
  • Is the source code of this library available?

Yes, and the source code was released here
https://github.com/samnyan/UnityNativeAndroidIO

Copy link
Member

@macmillan333 macmillan333 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This project is getting very complex in terms of I/O and this worries me. I hope you don't mind some high-level questions, so I can understand your code better.

  • Where do content:// paths come from?
  • What exactly does UniversalIO.GetRealPathFromUri do? What does the output look like?
  • Could the method names in UniversalIO be improved? For example, instead of UniversalIO.DirectoryCreateDirectory, just UniversalIO.CreateDirectory. Or create subclasses inside UniversalIO so we can say UniversalIO.Directory.CreateDirectory.
  • Some methods in UniversalIO handle content:// but some don't. Are those checks added on a case-by-case basis? Is this an easy way to tell which methods handle content:// at a glance?
  • Do you plan to handle streaming assets on Android with AndroidNativeIO? BetterStreamingAssets? Or something else entirely?

At the same time, could you attach a license to your UnityNativeAndroidIO repo? So we can properly depend on it.

@samnyan
Copy link
Contributor Author

samnyan commented May 9, 2022

Content URI

content:// paths is Android Content Provider URI and basically, it provides an application layer file access.

For example, the Google Drive app can provide a URI like content://google.drive/someFilePath.jpg. Any application access to this file will be handled by the Google Drive app itself without downloading to some public folder and reading from there.

By using the file picker provided by Android when setting the custom data location, it returns a URI looks like
content://com.android.externalstorage.documents/tree/primary%3ATechmania%2FTracks.

This means the file access is provided by com.android.externalstorage.documents, a system application.

UniversalIO.GetRealPathFromUri

The URI provided by com.android.externalstorage.documents can be translated back to a real file path most of the time, UniversalIO.GetRealPathFromUri does exactly that.
From the URI content://com.android.externalstorage.documents/tree/primary%3ATechmania%2FTracks

  • primary:Techmania/Tracks was the URL decoded result of that URI result.
  • primary means the primary storage device, mounted at /storage/emulated/0/
  • Techmania/Tracks is the relative path

So the resulting output will look like /storage/emulated/0/Techmania/Tracks

The old Fantom plugin will return this real path as the file picker result.
But using C# file access on the real path has huge limitations after Android 11.
It only provided access to media files with with ".mp4 .jpg .mp3" extension for example.
And listing files with C# enumeratefiles won't see any other file at all.

This is why most of the file access will be handled by the plugins.
And because media files can be accessed directly, assets like eye catch and key sound were converted back to the real path and then handle by Unity.

About the UniversalIO

I will create a subclass inside UniversalIO for a better method name.
The reason some method doesn't handle content URI is that it doesn't provide an equivalent method in Android, and I may remove those methods in UniversalIO. (Most of them were for unzipping the track)

For the streaming assets, I don't think it will handle by this native io. I'm still working on that.

Copy link
Member

@macmillan333 macmillan333 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really appreciate the reply, I learned a lot! While you update UniversalIO method names I gave your PR an initial round of review. Some are just comments that I ask you to add to the code.

{
public class Constants
{
public const string ANDROID_PACKAGE = "cn.samnya.nativeandroid.io";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// This points to a compiled library at Assets/Plugins/AndroidNativeIO/lib-release.aar
// Source code: https://github.com/samnyan/UnityNativeAndroidIO

kTrackFolderName);
Directory.CreateDirectory(trackRootFolder);
streamingTrackRootFolder = Path.Combine(
UniversalIO.DirectoryCreateDirectoryCSharp(trackRootFolder);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does DirectoryCreateDirectoryCSharp work on Android?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a folder with full path doesn't support on content uri. I will replace it with the parentPath and childName one.

if (fullPath.StartsWith(UniversalIO.ANDROID_CONTENT_URI))
{
return UniversalIO.GetRealPathFromUri(fullPath)
.Replace(UniversalIO.GetRealPathFromUri(Paths.GetTrackRootFolder()), "Tracks");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please handle "Skins" as well. IIRC some error dialogs will show skin folders.


#region Path

public static string PathGetDirectoryName(string path, bool returnToTreeUri = true)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it was my oversight that there are 2 ways to get the directory name (DirectoryInfo.Name and Path.GetDirectoryName). Could you test if it's okay to replace the former with latter?

Remove UniversalIO.DirectoryCreateDirectoryCSharp.
Cleanup Debug message.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants