android - データベースでclose()が明示的に呼び出されたことはありません

android sqlite broadcastreceiver

SMSを受け取ったら、SQLiteデータベースにSMSを保存する必要があります。
私はこれらのクラスを使用しています:

DBHelper.java

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);
    }


DBManager.java

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()>0 && sms.getReceiver().length()>0 && 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<Sms> al=new ArrayList<Sms>();
        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();
    }}


SmsBR.java

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 < pdus.length; i++) {
                            messages[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
                        }
                        if (messages.length > 0) {
                            System.out.println("I received an sms from: "+messages[0].getOriginatingAddress());
                            DBManager dbm = new DBManager(context);
                            dbm.insertSMS(messages[0]);
                            dbm.close();
                        }}}}


しかし、私はこのエラーを受け取ります:

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.<init>(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.<init>(DBManager.java:24)
     at it.giox.sms.DroidClient.<init>(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)


何を変更できますか?

[編集]
私はこの修正を行いましたが、エラーは残っています...

public Sms[] getAllSms(){
        String[] columns = { "mittente","destinatario","testo","dataora" };
        ArrayList<Sms> al=new ArrayList<Sms>(); 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();
        }


[編集2]

問題は、DBManagerコンストラクターでnew SQLiteDatabaseを作成し、次にclose()を作成する必要があることです。 close()をコンストラクターに入れてもエラーは発生しませんが、データベースが閉じていることがシステムから通知されます。
SQLiteDatabaseの新しいインスタンスが必要になるたびに作成し、最後にそれを閉じる問題を解決しました。うまくいきましたが、もっと良い解決策があると思います!

public Sms[] getAllSms(){
        SQLiteDatabase dbw;
                ...
                try{
                dbw=dbh.getWritableDatabase();
                ...
                } finally {dbw.close();}}
答え
カーソルを使い終わったら、カーソルを閉じる必要があります。 try/finallyおよびgetAllSms()getSmsById()を使用して、データを読み取った後にカーソルを閉じます。
関連記事

android - AndroidのドライバーからHCIデバイスのリストを取得する際の問題

android - 正方形のテクスチャとしてテキストを描画しても何も表示されません

android - Android:クリックでアプリ全体の言語を翻訳する[終了]

android - Androidでのアクティビティ開始の問題

android - Androidでzxing not found例外

android - Android:Location.getAltitude()以外に高度を取得する方法はありますか? (センサーの使用を聞いたことがあります)

android-3.0-honeycomb - タブレット用とスマートフォン用のアプリを別々に作成する必要がありますか?

android - Androidメディアプレーヤーが、スペースまたは特殊文字を含むURLからオーディオファイルを再生しない

android - Google+アプリやGoogle DocアプリのようなViewPagerインジケーター

android - Androidプログラミングで2つのビューをマージする