0

I have a sqlite db in SD card. I am trying to open it from an activity but getting the below error.

Failed to open database '/storage/sdcard1/deltalearn/deltalearn.db'.
                                                      android.database.sqlite.SQLiteException: not an error (code 0): Could not open the database in read/write mode.
                                                          at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
                                                          at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:214)
                                                          at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:198)
                                                          at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
                                                          at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)

Below is the code I am using to open DB. I am not able to use Environment.getExternalStorageDirectory() as this is pointing to internal storage in few phones.

DatabaseHandler databaseHandler = new DatabaseHandler(this);
public DatabaseHandler(Context context) {
super(context, AndroidUtils.getExternalStoragePath()
        + File.separator + Constants.DATABASE_FOLDER_NAME
        + File.separator + DATABASE_NAME, null, DATABASE_VERSION);
Log.d("DatabaseHandler::","public DatabaseHandler(Context context)");

File dbFile=new File(AndroidUtils.getExternalStoragePath()
        + File.separator + Constants.DATABASE_FOLDER_NAME
        + File.separator + DATABASE_NAME);

SQLiteDatabase.openOrCreateDatabase(dbFile, null);

Log.d("DatabaseHandler::", "path: route:" + AndroidUtils.getExternalStoragePath()
        + File.separator + Constants.DATABASE_FOLDER_NAME
        + File.separator + DATABASE_NAME);
}

public static String getExternalStoragePath() {
String removableStoragePath = "";
//working in Moto, but not working in Samsung S3
File fileList[] = new File("/storage/").listFiles();
for (File file : fileList) {
    if (!file.getAbsolutePath().equalsIgnoreCase(Environment.getExternalStorageDirectory().getAbsolutePath()) && file.isDirectory() && file.canRead()) {
        removableStoragePath = file.getAbsolutePath();
    }
}
Log.d("AndroidUtils:: ", "getExternalStoragePath: removableStoragePath:" + removableStoragePath);
if (removableStoragePath.contains("emulated")) {
    //working in Samsung s3, but not working in Moto
    String path = "";
    File file = new File("/system/etc/vold.fstab");
    FileReader fr = null;
    BufferedReader br = null;

    try {
        fr = new FileReader(file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    try {
        if (fr != null) {
            br = new BufferedReader(fr);
            String s = br.readLine();
            while (s != null) {
                if (s.startsWith("dev_mount")) {
                    String[] tokens = s.split("\\s");
                    path = tokens[2]; //mount_point
                    if (!Environment.getExternalStorageDirectory().getAbsolutePath().equals(path)) {
                        break;
                    }
                }
                s = br.readLine();
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (fr != null) {
                fr.close();
            }
            if (br != null) {
                br.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    Log.d("AndroidUtils::", "getExternalStoragePath: path:" + path);
    return path;
} else {
    //working in Moto, but not working in Samsung galaxy S3
    return removableStoragePath;
}
}

But the same Db works if it is copied to internal storage.

Arbaz Alam
  • 1,172
  • 1
  • 14
  • 24
madhuri H R
  • 699
  • 1
  • 10
  • 26

1 Answers1

0

You should verify that you use getWriteableDatabase().
AlsoEnvironment.getExternalStorageDirectory() does not always point to the SD card, it may point to the internal storage as well, it varies from device to device so you can't really rely on it. As far as I know there is no certain way or method to always get an SD card. And that is probably why it doesn't work on some devices for you. Why not store your database in internal storage? Where only your app can access it. If you are saving images as a blob you can instead store their paths.

Suleyman
  • 2,765
  • 2
  • 18
  • 31
  • Is it possible to copy files from SD card to internal and vice versa ? – madhuri H R Apr 23 '18 at 09:08
  • @madhuriHR Yeah you can copy them, I believe it's explained [here](https://stackoverflow.com/questions/31094071/copy-file-from-the-internal-to-the-external-storage-in-android), but the problem is that it won't always be SD card. The problem here is that there are so many different configurations with different devices, that you do not know if you will get an SD card with `ExternalStorage` or you will get an internal storage of the device. – Suleyman Apr 23 '18 at 09:14
  • @madhuriHR So for Android there is internal storage, which means that it's private to your app package, and external which means it's not private to your package and is accessible to other apps. So it doesn't correspond directly to "external" and "internal" memory on a physical device. – Suleyman Apr 23 '18 at 09:16
  • Thanks. Yes I am facing issues with the path in MI phones. I am able to copy the file from SD card but copying back to sd card is a problem. Is there no other option for this ? Can we do it using content resolver? – madhuri H R Apr 23 '18 at 09:18
  • @madhuriHR I am not sure, but I think you can get the content resolver and call a query l, provided you have the URI, I'm not sure about it though – Suleyman Apr 23 '18 at 09:56