0

I've successfully read a pdf from the project and displayed in a WebView. What I want to do is to get the pdf file path from my project and check if it exists to display it, and if not, to give it another URI to open with. Anyone knows how I can get the path of the pdf and it works for both Android and iOS.

Here is my C# code:

 string internalstorageurl = string.Format("file:///android_asset/Content/{0}", WebUtility.UrlEncode("Conctionprofile.pdf"));
        public pdfviewer ()
        {
            InitializeComponent ();
            PDFReading();
        }
        private void PDFReading()
        {

                pdfwebview.Uri = internalstorageurl;

        }

XAML:

    <?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:AppXamarin.CustomRenders"
             x:Class="AppXamarin.Pages.pdfviewer"
             Padding="0,20,0,0">
    <ContentPage.Content>
        <local:CustomWebView x:Name="pdfwebview" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
    </ContentPage.Content>
</ContentPage>

I'm checking if the file exist in my project with this code:

 [assembly: Dependency(typeof(GetPdfFilePath_Android))]
namespace AppXamarin.Droid.CustomRender
{
    public class GetPdfFilePath_Android : Java.Lang.Object, IGetPdfFilePath
    {
        public string filePath(string fileName)
        {      
                string internalstorageurl = string.Format("file:///android_asset/Content/{0}", WebUtility.UrlEncode(fileName));
            if (File.Exists(internalstorageurl))
                return internalstorageurl;
            else
                return "not found";
        }
    }
}

The if statement is always false

mohammad anouti
  • 171
  • 2
  • 18
  • 2
    You can't do it both in the same way. The paths will differ between the platforms, so you will need an implementation per platform for that. – Gerald Versluis Mar 25 '19 at 07:29

1 Answers1

1

You can use dependencyService to get pdf file path from both iOS and Android app.

The interface:

public interface IGetPdfFilePath
{
    string filePath(string fileName);
}

Get the file path in Xamarin.forms:

string pdfPath = DependencyService.Get<IGetPdfFilePath>().filePath("myPdf.pdf");
                Console.WriteLine(pdfPath);

In iOS, the path is depending on where you store the file:

[assembly: Dependency (typeof (GetPdfFilePath_iOS))]

namespace UsingDependencyService.iOS
{
    public class GetPdfFilePath_iOS : IGetPdfFilePath
    {
        public GetPdfFilePath_iOS ()
        {
        }

        public string filePath(string fileName)
        {
            // 1. if your store your pdf in DocumentDirectory
            //string directories = NSSearchPath.GetDirectories(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.All)[0];
            //string pathBundle = directories + "/" + fileName;
            ////bool fileExists = NSFileManager.DefaultManager.FileExists(pathBundle);
            //return pathBundle;

            //2.pdf file in your project
            string pathBundle = Path.Combine(NSBundle.MainBundle.ResourcePath, fileName);

            return pathBundle;
        }
    }
}

In Android:

[assembly: Dependency(typeof(GetPdfFilePath_Android))]
namespace UsingDependencyService.Android
{
    public class GetPdfFilePath_Android : Java.Lang.Object, IGetPdfFilePath
    {

        public string filePath(string fileName)
        {

            string internalstorageurl = string.Format("file:///android_asset/Content/{0}", WebUtility.UrlEncode(fileName));

            return internalstorageurl;

        }
    }
}

Update:

Add this line: [assembly: Dependency(typeof(GetPdfFilePath_Android))] to your Android class. GetPdfFilePath_Android here is your class name.

Another way is to create a custom renderer of your webview, you can have a look at this project.

Update to check file:, I add this method in the Android to check if the file exist inside Assets/Content.

public bool fileExist (string fileName) {

            AssetManager assets = MainActivity.Instance.Assets;        
            string[] names = assets.List("Content");

            for (int i = 0; i < names.Length; i++)
            {
                if (names[i] == fileName)
                {
                    return true;
                }
            }

            return false;
        }

Note: You have to change the build action of pdf file to AndroidAsset if you can't find the file inside Assets.

nevermore
  • 15,432
  • 1
  • 12
  • 30
  • your answer is perfect, except I'm always getting an exception "Object reference not set to an instance of an object." which I guess that is not reaching the pdf file, although when I try to open the file in the pdf viewer and give it the same path, the file opens successfully – mohammad anouti Mar 28 '19 at 06:37
  • @mohammadanouti Under which line did you get this exception? I guess you get this exception on iOS only? Are you using `string pathBundle = Path.Combine(NSBundle.MainBundle.ResourcePath, fileName);`? – nevermore Mar 28 '19 at 07:00
  • Actually, for now, I'm testing it on Android. I'm getting the exception on this line from xamarin forms "string pdfPath = DependencyService.Get().filePath("myPdf.pdf");" and on debugging it is always popping on this and not passing the breakpoint in the "GetPdfFilePath_Android" class – mohammad anouti Mar 28 '19 at 07:33
  • @mohammadanouti Add `[assembly: Dependency(typeof(GetPdfFilePath_Android))]` in your Android Class. See my edit in my answer. – nevermore Mar 28 '19 at 07:45
  • yeah exactly I should have noticed that this is missing, Thank you!! – mohammad anouti Mar 28 '19 at 08:27
  • I'm trying to do something like checking if the file exists or not, the thing is that in the case of your answer, the path is returning whether the pdf file is in the path or not. Do you know how can I check if the path is found or not? – mohammad anouti Mar 28 '19 at 09:37
  • @mohammadanouti Try [this](https://stackoverflow.com/questions/16237950/android-check-if-file-exists-without-creating-a-new-one)? Add the code in the Android class to check if the file exists or not. – nevermore Mar 28 '19 at 09:55
  • You can check if the file exists or not in the dependence service. If exist, return the filePath. If no, you can return a empty string like "", and In the Xamarin.forms, check if the pdfPath is "" to know if the file path exist. – nevermore Mar 28 '19 at 09:58
  • I'm already doing this, I updated my question please check it out – mohammad anouti Mar 28 '19 at 10:06
  • @mohammadanouti ok,I will check it tomorrow. – nevermore Mar 28 '19 at 11:20
  • @mohammadanouti Try the solution I edited in my answer. – nevermore Mar 29 '19 at 08:26