progrAmmar
progrAmmar

Reputation: 2670

Creating SQLite database on Internal storage ANDROID

I am trying to create a SQLIte database on Internal Storage in my Xamarin application. I am creating a system for an offline environment where at least 3 applications are inter-connected with shared data. So if one application creates some data the other application should be able to read that.

The Database project is a Portable Class Library which I plan to include in all three applications.

My DbHelper is as follows:

public Database()
{
    string folder = "/data/data/Anchor.Main";
    _dbPath = System.IO.Path.Combine(folder, "Anchor.db");

    try
    {
        if (!System.IO.Directory.Exists(folder))
        {
            System.IO.Directory.CreateDirectory(folder); //Getting error here
        }

        _connection = new SQLiteConnection(_dbPath);
        _connection.CreateTable<Orders>();
        _connection.CreateTable<Items>();    

    }
    catch(Exception ex)
    {  }

}

I get error which says

Access to the path "/data/data/Anchor.Main" is denied.

Following is the stack trace

at System.IO.Directory.CreateDirectoriesInternal (System.String path) [0x0004b] in <3fd174ff54b146228c505f23cf75ce71>:0 at System.IO.Directory.CreateDirectory (System.String path) [0x00075] in <3fd174ff54b146228c505f23cf75ce71>:0 at anchorapp.db.Helper.Database..ctor () [0x0002e]

I understand this is because of the permissions, but what permissions do I need to set in order to write to the Internal storage from a PCL?

Upvotes: 1

Views: 2099

Answers (3)

progrAmmar
progrAmmar

Reputation: 2670

I did this by creating a sharedId within my projects and using the SharedContext to access the databases created by other apps

Upvotes: 0

tequila slammer
tequila slammer

Reputation: 2881

Android and iOS does not work that way. Each platform keeps apps in a sandboxed environment. If you want to create and store data in your app you need to create the path like the following sample:

var docFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
_dbPath = System.IO.Path.Combine(docFolder, "Anchor.db");

Also set the permissions ReadExternalStorage and WriteExternalStorage in your Android project

Instead of writing to a private folder, you could create the database in a public one. To do so the docFolder would change to:

var docFolder = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, "YourDirectoryName");

Please be advised, that if you go that way everyone can see and open the database.

Upvotes: 1

lowleetak
lowleetak

Reputation: 1382

You are accessing Android system folder of "/data/data/Anchor.Main". Your app internal storage will be in

/data/data/@PACKAGE_NAME@/files

You can use the following code to get the folder to store the database:

// Equal to /data/data/@PACKAGE_NAME@/files
var homePath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
_dbPath = System.IO.Path.Combine(homePath, "Anchor.db");
_connection = new SQLiteConnection(_dbPath);

Upvotes: 2

Related Questions