Note that there are some explanatory texts on larger screens.

plurals
  1. POclose() was never explicitly called on database
    text
    copied!<p>I need to store sms in a sqlite database, when one is received. I'm using these classes:</p> <p><strong>DBHelper.java</strong></p> <pre><code>public class DBHelper extends SQLiteOpenHelper { private static final String DB_NAME = "my_db"; private static final int DB_VERSION = 1; public DBHelper(Context context, String name, CursorFactory factory, int version) { super(context, DB_NAME, factory, DB_VERSION); } public DBHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } public String getName(){ return DB_NAME; } @Override public void onCreate(SQLiteDatabase db) { String sql=""; sql+="CREATE TABLE sms ( "; sql+="_id INTEGER PRIMARY KEY AUTOINCREMENT, "; sql+="mit TEXT NOT NULL, "; sql+="dest TEXT NOT NULL, "; sql+="text TEXT NOT NULL, "; sql+="date DATETIME NOT NULL )"; db.execSQL(sql); } </code></pre> <p><strong>DBManager.java</strong></p> <pre><code>public class DBManager { private DBHelper dbh; SQLiteDatabase dbr; SQLiteDatabase dbw; DBManager(DBHelper dbh){ this.dbh=dbh; dbr=dbh.getReadableDatabase(); //line 24 dbw=dbh.getWritableDatabase(); } DBManager(Context ctx){ this.dbh=new DBHelper(ctx); dbr=dbh.getReadableDatabase(); dbw=dbh.getWritableDatabase(); } public long insert(String table, ContentValues values){ return dbw.insert(table, null, values); } public long insertSMS(Sms sms){ if(sms.getSender().length()&gt;0 &amp;&amp; sms.getReceiver().length()&gt;0 &amp;&amp; sms.getText()!=null){ String sql="INSERT INTO sms VALUES ( null, \""+sms.getSender()+"\", \""+sms.getReceiver()+"\", \""+sms.getText()+"\", datetime())"; dbw.execSQL(sql); return 0; } return -1; } public Sms getSmsById(int id){ String[] columns = { "mit","dest","text","date" }, selectionArgs={ Integer.toString(id) }; String selection="_id = ?"; Cursor c=dbr.query("sms", columns, selection, selectionArgs, null, null, "_id ASC"); if(c.moveToFirst()) return new Sms(c.getString(0),c.getString(1), c.getString(2),c.getString(3)); return null; } public Sms[] getAllSms(){ String[] columns = { "mittente","destinatario","testo","dataora" }; Cursor c=dbr.query("sms", columns, null, null, null, null, "_id ASC"); ArrayList&lt;Sms&gt; al=new ArrayList&lt;Sms&gt;(); if(c.moveToFirst()) do{ al.add(new Sms(c.getString(0),c.getString(1),c.getString(2),c.getString(3))); }while(c.moveToNext()); return (Sms[]) al.toArray(); } public void close(){ if(dbh!=null) dbh.close(); if(dbw!=null) dbw.close(); if(dbr!=null) dbr.close(); }} </code></pre> <p><strong>SmsBR.java</strong></p> <pre><code>public class SmsBR extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); if (bundle != null) { Object[] pdus = (Object[])bundle.get("pdus"); final SmsMessage[] messages = new SmsMessage[pdus.length]; for (int i = 0; i &lt; pdus.length; i++) { messages[i] = SmsMessage.createFromPdu((byte[])pdus[i]); } if (messages.length &gt; 0) { System.out.println("I received an sms from: "+messages[0].getOriginatingAddress()); DBManager dbm = new DBManager(context); dbm.insertSMS(messages[0]); dbm.close(); }}}} </code></pre> <p>But I get this error:</p> <pre><code>close() was never explicitly called on database '/data/data/it.giox.sms/databases/my_db' android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here at android.database.sqlite.SQLiteDatabase.&lt;init&gt;(SQLiteDatabase.java:1847) at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820) at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:854) at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:847) at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:549) at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203) at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118) at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187) at it.giox.sms.DBManager.&lt;init&gt;(DBManager.java:24) at it.giox.sms.DroidClient.&lt;init&gt;(DroidClient.java:29) at it.giox.sms.DroidWebServer.getClient(DroidWebServer.java:25) at it.giox.sms.WebServer.startServer(WebServer.java:101) at it.giox.sms.WebServer.run(WebServer.java:60) at java.lang.Thread.run(Thread.java:1019) </code></pre> <p>What can I change?</p> <p><strong>[EDIT]</strong> I've done this correction, but the error remains...</p> <pre><code>public Sms[] getAllSms(){ String[] columns = { "mittente","destinatario","testo","dataora" }; ArrayList&lt;Sms&gt; al=new ArrayList&lt;Sms&gt;(); Cursor c = null; try{ c=dbr.query("sms", columns, null, null, null, null, "_id ASC"); if(c.moveToFirst()) do{ al.add(new Sms(c.getString(0),c.getString(1),c.getString(2),c.getString(3))); }while(c.moveToNext());} finally{ c.close(); close(); } return (Sms[]) al.toArray(); } </code></pre> <p><strong>[EDIT 2]</strong></p> <p>The problem is that in <code>DBManager</code> constructor I create a <code>new SQLiteDatabase</code> and then I should <code>close()</code> it. If I put <code>close()</code> in the constructor I've no that error, but the system tell me that the database is closed. I solved the problem creating a new instance of <code>SQLiteDatabase</code> every time I need it, and finally closing it. It works, but I think there are better solutions!</p> <pre><code>public Sms[] getAllSms(){ SQLiteDatabase dbw; ... try{ dbw=dbh.getWritableDatabase(); ... } finally {dbw.close();}} </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload