• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by DoctorWhy · May 08, 2017 at 10:48 PM · androidfiledataexternalintent

Convert Android URI to a file path Unity can read

I have an external app sending me a URI of a .zip file I need to access. Here is my attempt to convert the uri:

 AndroidJavaClass UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
 AndroidJavaObject currentActivity = UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
 
 AndroidJavaObject intent = currentActivity.Call<AndroidJavaObject>("getIntent");
 AndroidJavaObject data = intent.Call<AndroidJavaObject>("getData");
 
 AndroidJavaObject fileObject = new AndroidJavaObject("java.io.File", data);
 Debug.Log(fileObject.Call<string>("getPath"));

I am getting the uri correctly. But the constructor for the File class is getting this error:

 UnityEngine.AndroidJavaException: java.lang.NoSuchMethodError: no non-static method "Ljava/io/File;.<init>(Landroid.net.Uri$HierarchicalUri;)V"
 05-08 16:26:54.997 30011 30026 I Unity   : java.lang.NoSuchMethodError: no non-static method "Ljava/io/File;.<init>(Landroid.net.Uri$HierarchicalUri;)V"

How do I pass the uri to the java File class so I can get the proper path to the zip file?

Thanks for the help!

Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Guy-Corbett · May 30, 2017 at 08:19 PM 0
Share

Have you had any luck with this? I'm encountering a similar problem.

Show more comments
avatar image Guy-Corbett · May 31, 2017 at 07:18 PM 0
Share

So I found a way to work around this. What I'm doing is using the URI to read the file as an input stream. By doing that you can read the file byte by byte, or wrap the input reader in something more sophisticated extract strings. In the absolute laziest case you could read all the bytes to memory, write them out to a known file location and then read that file as you normally would. That code would look something like this;

 AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
 AndroidJavaObject activityObject = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");
 AndroidJavaObject intent = activityObject.Call<AndroidJavaObject>("getIntent");
 AndroidJavaObject intentURI = intent.Call<AndroidJavaObject>("getData");
 AndroidJavaObject contentResolver = activityObject.Call<AndroidJavaObject>("getContentResolver");
 AndroidJavaObject inputStream = contentResolver.Call<AndroidJavaObject>("openInputStream", intentURI);
 List<byte> bytes = new List<byte>();
 int nextByte = inputStream.Call<int>("read");
 while (nextByte != -1)
 {
     bytes.Add((byte)nextByte);
     nextByte = inputStream.Call<int>("read");
 }
 
 inputStream.Call("close");
 
 File.WriteAllBytes(my$$anonymous$$nownPath, bytes.ToArray());
 $$anonymous$$yFileReadingFunction(my$$anonymous$$nownPath);

Show more comments

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by liortal · Jun 05, 2017 at 06:48 AM

Your original code is fine, but this is a limitation with how JNI finds and invokes methods from C# (well, technically from C++, but Mono is using the same infrastructure).

See the following (related) question on Stack overflow.

The problem is you're trying to find a method that has a signature that is different than the actual File class constructor, and so it fails.

The easiest solution you can do is create a simple plugin (fancy name for a small .jar containing helper methods), then call these Java helper methods from your C# code to achieve what you want.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Guy-Corbett · Jun 05, 2017 at 05:21 PM

So found a way to do this without writing a plugin or resorting to reading byte by byte. Seems to run pretty fast. Here's the function I've written which copies the whole of any file given with the intent to another location;

         private void ImportFromIntent(string importPath)
         {
             try
             {
                 // Get the current activity
                 AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
                 AndroidJavaObject activityObject = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");
 
                 // Get the current intent
                 AndroidJavaObject intent = activityObject.Call<AndroidJavaObject>("getIntent");
 
                 // Get the intent data using AndroidJNI.CallObjectMethod so we can check for null
                 IntPtr method_getData = AndroidJNIHelper.GetMethodID(intent.GetRawClass(), "getData", "()Ljava/lang/Object;");
                 IntPtr getDataResult = AndroidJNI.CallObjectMethod(intent.GetRawObject(), method_getData, AndroidJNIHelper.CreateJNIArgArray(new object[0]));
                 if (getDataResult.ToInt32() != 0)
                 {
                     // Now actually get the data. We should be able to get it from the result of AndroidJNI.CallObjectMethod, but I don't now how so just call again
                     AndroidJavaObject intentURI = intent.Call<AndroidJavaObject>("getData");
 
                     // Open the URI as an input channel
                     AndroidJavaObject contentResolver = activityObject.Call<AndroidJavaObject>("getContentResolver");
                     AndroidJavaObject inputStream = contentResolver.Call<AndroidJavaObject>("openInputStream", intentURI);
                     AndroidJavaObject inputChannel = inputStream.Call<AndroidJavaObject>("getChannel");
 
                     // Open an output channel
                     AndroidJavaObject outputStream = new AndroidJavaObject("java.io.FileOutputStream", importPath);
                     AndroidJavaObject outputChannel = outputStream.Call<AndroidJavaObject>("getChannel");
 
                     // Copy the file
                     long bytesTransfered = 0;
                     long bytesTotal = inputChannel.Call<long>("size");
                     while (bytesTransfered < bytesTotal)
                     {
                         bytesTransfered += inputChannel.Call<long>("transferTo", bytesTransfered, bytesTotal, outputChannel);
                     }
 
                     // Close the streams
                     inputStream.Call("close");
                     outputStream.Call("close");
                 }
             }
             catch (System.Exception ex)
             {
                 // Handle error
             }
         }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

127 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Open another app with intent url on Android 1 Answer

External Saves for android games 1 Answer

android file open 0 Answers

How to access a text file from a built unity generated android application 0 Answers

Faster way to Pass data from C# to Java (Android) 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges