1

I am currently making an application for the Android SDK that will allow me to open/copy a database already made outside of the application. I was having trouble getting my program to read the table in my database. Following some advice on a question I posted earlier, I wrote a class that would directly call up SQLiteDatabase as well as make my database in the version of sqlite3 that comes with the Android SDK. Now, for some reason, my program can't even open the database. It seems to recognize that it is there, but Logcat (I am using Eclipse Juno with the ADT plug-in) keeps telling me now that it "Could not open database". Anyone know what the problem might be?

Here is all of my code (for the sake of being thorough):

public class MyDatabase
{
private static final String TABLE_OS = "OregonState";
private static final String COLUMN_ID = "_id";
private static final String COLUMN_NAME = "Name";
private static final String COLUMN_FIELD = "Field";

SQLiteDatabase database;
String path;

public MyDatabase()
{
        File file = new File("/scratch/android-sdk-linux/tools/os.sqlite");
        database = SQLiteDatabase.openOrCreateDatabase(file, null);
        path = database.getPath();
        database.close();
}

public long insert(ContentValues values, String name, String field)
{
    database = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READWRITE);
    values.put("Name", name);
    values.put("Field", field);
    long id = database.insert(TABLE_OS, null, values);
    database.close();
    return id;
}

public long insert(ContentValues values, String name)
{
    database = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READWRITE);
    values.put("Name", name);
    long id = database.insert(TABLE_OS, null, values);
    database.close();
    return id;
}

public int delete(int id)
{
    database = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READWRITE);
    database.delete(TABLE_OS, COLUMN_ID + "=" + id, null);
    database.close();
    return 1;
}

public int update(ContentValues values, int id, String name, String field)
{
    database = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READWRITE);
    values.put("Name", name);
    values.put("Field", field);
    database.update(TABLE_OS, values, COLUMN_ID + "=" + id, null);
    database.close();
    return 1;
}

public int update(ContentValues values, int id, String name)
{
    database = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READWRITE);
    values.put("Name", name);
    database.update(TABLE_OS, values, COLUMN_ID + "=" + id, null);
    database.close();
    return 1;
}

public Cursor get(int id)
{
    return database.query(TABLE_OS, new String[] {COLUMN_ID, COLUMN_NAME, COLUMN_FIELD}, COLUMN_ID + "=" + id, null, null, null, null);
}

public Cursor getAll()
{
    return database.query(TABLE_OS, new String[] {COLUMN_ID, COLUMN_NAME, COLUMN_FIELD}, null, null, null, null, null);
}
}


public class SQLTest extends Activity
{
SQLAdapter adapter;
MyDatabase database;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sqltest);
    database = new MyDatabase();
    database.getAll();
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    getMenuInflater().inflate(R.menu.activity_sqltest, menu);
    return true;
} 

public long insert(String name, String field)
{
    ContentValues values = new ContentValues();
    long id = database.insert(values, name, field);
    return id;
}

public long insert(String name)
{
    ContentValues values = new ContentValues();
    long id = database.insert(values, name);
    return id;
}

public int delete(int id)
{
    int rowsDeleted = database.delete(id);
    return rowsDeleted;
}

public int update(int id, String name, String field)
{
    ContentValues values = new ContentValues();
    int rowsUpdated = database.update(values, id, name, field);
    return rowsUpdated;
}

public int update(int id, String name)
{
    ContentValues values = new ContentValues();
    int rowsUpdated = database.update(values, id, name);
    return rowsUpdated;
}

public void get(int id)
{
    Cursor cursor = database.get(id);
    TextView tv = new TextView(this);
    String table = "";
    if (cursor.moveToFirst())
        table += "\n" + cursor.getString(0) + " " + cursor.getString(1) + " " + cursor.getString(2);
    else
        table += "No hall found with ID: " + id;
    tv.setText(table);
    setContentView(tv);
    cursor.close();
}

public void getAll()
{
    TextView tv = new TextView(this);
    String table = "";
    try
    {
        Cursor cursor = database.getAll();
        if (cursor.moveToFirst())
        {
            do
            {
                table += "\n" + cursor.getString(0) + " " + cursor.getString(1) + " " + cursor.getString(2);
            } while (cursor.moveToNext());
        }
        cursor.close();
    } catch (Exception e) {}
    tv.setText(table);
    setContentView(tv);
}
}

Here is also my Logcat log:

07-16 15:27:08.364: E/Trace(810): error opening trace file: No such file or directory (2)
07-16 15:27:08.504: E/SQLiteLog(810): (14) cannot open file at line 30174 of [00bb9c9ce4]
07-16 15:27:08.504: E/SQLiteLog(810): (14) os_unix.c:30174: (2) open(/scratch/android-sdk-linux/tools/os.sqlite) - 
07-16 15:27:08.524: E/SQLiteDatabase(810): Failed to open database '/scratch/android-sdk-linux/tools/os.sqlite'.
07-16 15:27:08.524: E/SQLiteDatabase(810): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:709)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:702)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at com.example.sql2.MyDatabase.<init>(MyDatabase.java:26)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at com.example.sql2.SQLTest.onCreate(SQLTest.java:20)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.app.Activity.performCreate(Activity.java:5008)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.app.ActivityThread.access$600(ActivityThread.java:130)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.os.Handler.dispatchMessage(Handler.java:99)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.os.Looper.loop(Looper.java:137)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at android.app.ActivityThread.main(ActivityThread.java:4745)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at java.lang.reflect.Method.invokeNative(Native Method)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at java.lang.reflect.Method.invoke(Method.java:511)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
07-16 15:27:08.524: E/SQLiteDatabase(810):  at dalvik.system.NativeStart.main(Native Method)
07-16 15:27:08.524: D/AndroidRuntime(810): Shutting down VM
07-16 15:27:08.524: W/dalvikvm(810): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
07-16 15:27:08.534: E/AndroidRuntime(810): FATAL EXCEPTION: main
07-16 15:27:08.534: E/AndroidRuntime(810): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sql2/com.example.sql2.SQLTest}: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
07-16 15:27:08.534: E/AndroidRuntime(810):  at   android.app.ActivityThread.access$600(ActivityThread.java:130)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.os.Handler.dispatchMessage(Handler.java:99)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.os.Looper.loop(Looper.java:137)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.app.ActivityThread.main(ActivityThread.java:4745)
07-16 15:27:08.534: E/AndroidRuntime(810):  at java.lang.reflect.Method.invokeNative(Native Method)
07-16 15:27:08.534: E/AndroidRuntime(810):  at java.lang.reflect.Method.invoke(Method.java:511)
07-16 15:27:08.534: E/AndroidRuntime(810):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
07-16 15:27:08.534: E/AndroidRuntime(810):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
07-16 15:27:08.534: E/AndroidRuntime(810):  at dalvik.system.NativeStart.main(Native Method)
07-16 15:27:08.534: E/AndroidRuntime(810): Caused by: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
07-16 15:27:08.534: E/AndroidRuntime(810):  at  android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:709)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:702)
07-16 15:27:08.534: E/AndroidRuntime(810):  at com.example.sql2.MyDatabase.<init>(MyDatabase.java:26)
07-16 15:27:08.534: E/AndroidRuntime(810):  at com.example.sql2.SQLTest.onCreate(SQLTest.java:20)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.app.Activity.performCreate(Activity.java:5008)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
07-16 15:27:08.534: E/AndroidRuntime(810):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
07-16 15:27:08.534: E/AndroidRuntime(810):  ... 11 more
Community
  • 1
  • 1
NioShobu
  • 775
  • 2
  • 10
  • 21

5 Answers5

2

Add this permission to your project

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
saeed khalafinejad
  • 1,139
  • 9
  • 22
1

Logcat shows the directory doesn't exist. Which is no surprise as there typically isn't a scratch directory under root on android devices.

It's also best to avoid using absolute path names as well as you can't be certain that they'll always exist on the different devices your app may run on. The correct way to access files for your application would be to use Environment when opening a file. For example:

File file = new File(Environment.getExternalStorageDirectory() + "/scratch/os.sqlite");

This would typically exist on the sdcard or a soft linked directory designated as the "sd card" on internal memory. So this example would open a file on the sdcard under the scratch directory.

How to get your database file on to the device or emulator is up to you. You can use the file explorer to push the file into the appropriate directory if you're using the emulator.

TJ Thind
  • 784
  • 5
  • 17
1

Android by default compresses files with the size greater than 1MB. Older versions of Android OS has a bug, which causes compressed resource files to be read incorrectly.The easiest solution is to use resource file extensions, for example, ".mp3"

Carlos Mayoral
  • 313
  • 3
  • 12
0

As far as I can remember, there is no "scratch" directory in the Android filesystem. When you call

File file = new File("/scratch/android-sdk-linux/tools/os.sqlite");
database = SQLiteDatabase.openOrCreateDatabase(file, null);

I believe that the second statement would throw some error as the /scratch/android-sdk-linux/tools/os.sqlite filepath doesn't exist. Try calling file.mkdirs() or file.createNewFile().

Jason L
  • 1,812
  • 2
  • 22
  • 43
  • On my machine, /scratch does exist. – NioShobu Jul 16 '12 at 23:17
  • Also, I don't want to create a new file. I'm trying to open and copy a database already made. – NioShobu Jul 16 '12 at 23:22
  • Are you talking about your development machine or your Android device? – tiguchi Jul 16 '12 at 23:22
  • What do you mean? I am not using a real Android device, but an emulator that is running the applications I develop in Eclipse. – NioShobu Jul 16 '12 at 23:25
  • I assume that you are trying to access a file from your app that resides on your dev PC. The emulator and your PC are virtually two different devices. The emulator doesn't have access to your PC's file system, therefore you cannot open the SQlite database file from your app like that. You need to bundle the database file with your app as an asset and when you start your app for the first time you need to copy that asset to Android's internal or external storage. – tiguchi Jul 16 '12 at 23:29
  • In your app project should be a folder called "assets" (if not you need to create it). Copy your database file into that folder. It will be bundled with your app now. When your app starts up it has to check for the existence of the database file in the Android device file system. Use Context.getExternalFile or Context.getDatabasePath for retrieving a valid file path on the emulator / device. If that file does not exist yet, you have to [copy the asset file](http://developer.android.com/reference/android/content/res/AssetManager.html) to the database file location. – tiguchi Jul 16 '12 at 23:36
0

I responded to an answer given to me on another question and rewrote my code using two separate classes, and Adapter and a Helper, which turned out to work perfectly. I am providing the link to the code in case anyone else is having trouble with developing an SQLiteDatabase like I did.

Community
  • 1
  • 1
NioShobu
  • 775
  • 2
  • 10
  • 21