user8412072
user8412072

Reputation:

Xamarin.Forms FileStream - Could not find file

Currently I am trying to load file "json" from my Android project, using Xamarin.Forms.

Here is my code:

var path = @"client_secret.json";
using (var stream = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
}

For path I tried many different cases to place "client_secret.json" in project root folder, assets folder, bin, bin>Debug, bin>Release as well for ".Droid" project and PCL too. I tried also to change file build action to "Content", "Embedded Resource", "Additional Files", "AndroidResource" and "AndroidEnvironment". I tried also to change "client_secret.json" and use physical path (D:\Apps....\Project.Android\client_secret.json) and try to find it in different folders:

Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath

Directory.GetFiles(Directory.GetCurrentDirectory())

Directory.GetFiles(Android.OS.Environment.RootDirectory.AbsolutePath)

Directory.GetFiles(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal))

And still nowhere I find it. "Copy to output" file property is changed to "Copy always" and still no result.

Does anybody know what I am doing wrong in that case to make FileStream on this file?

Thanks in advance

Upvotes: 4

Views: 3626

Answers (2)

Sharada
Sharada

Reputation: 13591

1. In order to use FileStream - you will most probably need the absolute file path name; which is not possible for an asset file (there are cases where you can use URL syntax file:///android_asset/... like in WebView etc. but not in FileStream);

What you can do is get access to InputStream using AssetManager, which should be compatible with GoogleClientSecrets.Load() method.

using(var stream = this.Assets.Open(@"client_secret.json"))
{
     var secrets = GoogleClientSecrets.Load(stream).Secrets;
     ...

2. Another option would be to copy your asset file to storage and then try and access in FileStream using destination path.

var path = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), @"client_secret.json");
using (var asset = Assets.Open("client_secret.json"))
    using (var dest = System.IO.File.Create(path))
         asset.CopyTo(dest);

using (var stream = new System.IO.FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
    var secrets = GoogleClientSecrets.Load(stream).Secrets;
    ...

Note: For option 1, and 2; make sure that you follow the steps to add this json file as an asset to android app

3. The next option would be to use embedded resources - and you can access file using Assembly.GetManifestResourceStream().

var assembly = typeof(MainActivity).GetTypeInfo().Assembly;
using (var stream = assembly.GetManifestResourceStream("AssemblyNamespace.client_secret.json"))
{
    var secrets = GoogleClientSecrets.Load(stream).Secrets;
    ...

Note: For option 3; make sure to follow the steps to add this json file as an embedded resource to android app or assembly

Upvotes: 2

Jason
Jason

Reputation: 89082

Using Android Assets

AssetManager assets = this.Assets;
using (StreamReader sr = new StreamReader (assets.Open ("client_secret.json")))
{
    content = sr.ReadToEnd ();
}

Upvotes: 2

Related Questions