SoleR
SoleR

Reputation: 13

How to Open a PDF in an Android-Unity3D App?

I'm developing an Android app in Unity3D to be used in classrooms, it has buttons to display some webs and videos related to the current lesson, but now I would like to have a button that open the default-pdf-viewer in the Android Tablet and loads a PDF file that I have in a folder in my project assets.

The thing is I have been trying a lot of code from different people from StackOverflow posts and Unity community Threads, but nothing works for me.

I have already tried:

Unity Answers 1

Unity Answers 2

Unity Answers 3

My minimum android API level is set 22 (in relation to this reddit post)

Here's my code so far:

IEnumerator openPDF() {
     var path = "jar:file://" + Application.dataPath + "!/assets/test.pdf";
     var savePath = Application.persistentDataPath;

     WWW www = new WWW(path);
     yield return www;
     var error = www.error;

     byte[] bytes = www.bytes;
     var result = "File size : "+bytes.Length;

     try{
         System.IO.File.WriteAllBytes(savePath+"/test.pdf", bytes);
         error = "No Errors so far";
     }catch(Exception ex){
         error = ex.Message;
     }

     Application.OpenURL(savePath+"/test.pdf");
}

When I print the www.error string I get a "404 not Found".

Here's what I get when I print the path variable: jar:file:///data/[MY APP PACKAGE NAME]/base.apk!/assets/test.pdf

Upvotes: 1

Views: 5860

Answers (2)

If your app target level API 24 or more, you need to use FileProvide API, otherwise you get FileUriExposedException, as described here.

To interact with FileProvider from С# code, you need to know how to interact with AndroidJavaClass and AndroidJavaObject to work with Java libraries (namely android.support.v4). Also you need to know how to declares a content provider component by adding the <provider> attribute to your AndroidManifest.xml in your project and some more points that are listed here.

In the answer of this post you can find a solution to the problem, but stumble upon the following troubles:

1) The android.support.v4 library is no longer available on the path "AndroidSDK/extras/android/support/v4/android-support-v4.jar", since now it is part of another library.

2) You can find this library in some archives on the Internet, but when you download them you will find that the res folder in Plugins/Android is no longer supported and you need to create a .aar binary file in which you need to put AndroidManifest.xml and android.support.v4 library.

3) When specifying the attribute <provider> in AndroidManifest.xml, you need to additionally specify <meta-data> in which to specify the path, where in your .aar archive the provider_paths.xml file is located, otherwise your application will crash at startup.

You can try to go this long way yourself, or download my asset, which already has all the necessary code for working with the android.support.v4 library via AndroidJavaClass and AndroidJavaObject, and which is also able to rewrite package name in AndroidManifest.xml and providers_paths.xml when you will change it in the project settings. A demo is also included there.

Link on github: https://github.com/Mihail5412/Unity-Android-Files-Opener

Upvotes: 1

SoleR
SoleR

Reputation: 13

Ok, finally I got the solution! As you can read here Android permissions changed in Nougat (v.7) so that's why I wasnt able to open the pdf, the sistem was blocking it.

The solution was simple, I just lowered the target API level to 23 (Android 6.0 'Marshmallow').

Here's my code if someone is interested:

void openPDF(){ string namePDF = "test"; TextAsset pdfTem = Resources.Load("PDFs/"+namePDF, typeof(TextAsset)) as TextAsset; System.IO.File.WriteAllBytes(Application.persistentDataPath + "/"+namePDF+".pdf", pdfTem.bytes); Application.OpenURL(Application.persistentDataPath+"/"+namePDF+".pdf"); }

Upvotes: 0

Related Questions