1

I am developing a cross-platform app using Xamarin Forms PCL project. In this I need to write a file in Android's internal storage so that I can access it. I have given Write to External Storage permissions but when I try to write the file it says Access is denied.

Here is what I tried:

Java.IO.File DataDirectoryPath = Android.OS.Environment.DataDirectory;
string dirPath = DataDirectoryPath.AbsolutePath + "/MyFolder";
bool exists = Directory.Exists(dirPath);
string filepath = dirPath + "/test.txt";
if (!exists)
{
    Directory.CreateDirectory(dirPath);
    if (!File.Exists(filepath))
    {
        File.Create(filepath).Dispose();
        using (TextWriter tw = new StreamWriter(filepath))
        {
            tw.WriteLine("The very first line!");
            tw.Close();
        }
    }
}
wonea
  • 4,783
  • 17
  • 86
  • 139
Sonali
  • 2,223
  • 6
  • 32
  • 69
  • It is generally recommended (and secure) to use app's sandbox to store files. If you store file in to device storage instead your file can be modified / deleted easily... – Milen May 12 '17 at 08:02
  • `Directory.CreateDirectory(dirPath);` Should not you check return value? Or check if the directory exists before trying to put a file in it? – greenapps May 12 '17 at 08:20
  • on that particular line it says "Access is denied" – Sonali May 12 '17 at 08:20
  • For use of internal storage you do not need any permission at all. – greenapps May 12 '17 at 08:20
  • Android version? – greenapps May 12 '17 at 08:21
  • `I have given Write to External Storage permissions` What are the things you did exactly? – greenapps May 12 '17 at 08:21
  • If you run your code again and the directory exists, the code to create a file is not executed. Intentionally? – greenapps May 12 '17 at 08:25
  • `dirPath + "/test.txt"` You have that three times. Bad coding. Do it only once and use on following places. string filePath = dirPath + "/test.txt" – greenapps May 12 '17 at 08:27
  • android Version is 4.4.4 and by `I have given Write to External Storage permissions` I mean in android manifest file I have allowed WRITE.EXTERNAL.STORAGE. – Sonali May 12 '17 at 08:43

1 Answers1

5

In this I need to write a file in android's internal storage so that i can acccess it. I have given Write to External Storage permissions but when I try to write the file it says Access is denied.

First of all, the permission <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> is for external storage, hence it doesn't work for the internal storage.

Based on your code:

Java.IO.File DataDirectoryPath = Android.OS.Environment.DataDirectory; 

You used Data Directory for your writing, this directory is owned by system and there is no permission for writing to it, there're several discussions about this issue on SO, for example: Data directory has no read/write permission in Android .

So, as it suggested in the answer there, you can use getFilesDir() to write in internal storage, in Xamarin, it is Android.Content.Context.FilesDir Property.

Update:

I wrote some code based on your code, it should be the same, for example:

var dirPath = this.FilesDir + "/MyFolder";
var exists = Directory.Exists(dirPath);
var filepath = dirPath + "/test.txt";
if (!exists)
{
    Directory.CreateDirectory(dirPath);
    if (!System.IO.File.Exists(filepath))
    {
        var newfile = new Java.IO.File(dirPath, "test.txt");
        using (FileOutputStream outfile = new FileOutputStream(newfile))
        {
            string line = "The very first line!";
            outfile.Write(System.Text.Encoding.ASCII.GetBytes(line));
            outfile.Close();
        }
    }
}

I also checked this file by DDMS, it can be seen under the folder: data\data\yourAPP\files\MyFolder\test.txt:

enter image description here

I just test Xamarin.Android project, didn't tried to use DependencyService for Xamarin.Forms, if you're trying to do that, just replace the word this in the code above to your android context.

Community
  • 1
  • 1
Grace Feng
  • 16,564
  • 2
  • 22
  • 45
  • Do you have any sample code to use this property. Please share. – Sonali May 16 '17 at 05:04
  • @Sonali, I wrote some code based on your code, please check my updated answer. And if you find this helpful, could you please mark this answer? – Grace Feng May 16 '17 at 05:58
  • 2
    I replaced `this` by `Android.App.Application.Context.FilesDir`. Is it correct? – Sonali May 16 '17 at 06:06
  • 1
    @Sonali, yes, exactly, sorry for the late response, I was in a meeting. Just tested with Xamarin.Forms, and it works fine. – Grace Feng May 16 '17 at 08:12
  • how can I see this file in device? – Sonali May 16 '17 at 08:47
  • @Sonali, as I said, use DDMS, and check the file path I wrote in my updated answer, for DDMS, you can check my [other answer](http://stackoverflow.com/questions/43538453/how-to-add-an-image-to-android-emulator-directly-or-through-visual-studio-xamar/43606792#43606792). – Grace Feng May 16 '17 at 08:49
  • I have connected my android device in VS. Will it work for device also? – Sonali May 16 '17 at 08:52
  • While Debugging I tried opening it but nothing is happening?\ – Sonali May 16 '17 at 08:54
  • @Sonali, maybe you can open a new case to ask about DDMS, but are you sure your device can be detected by VS while you debugging? If so, it should be found by DDMS. – Grace Feng May 16 '17 at 08:57