应用程序应从数据库加载内容但不加载

时间:2013-03-12 10:05:41

标签: android database assets

我有一个非常恼人的问题,我似乎无法找到解决问题的方法。我制作了第一个应用程序(测试我的方法的beta版本),我在其中定义了所有内容,因此我的应用程序可以与数据库通信。它工作得很好。

我在同一个模型上启动了我的新应用程序,保留了相同的类和所有内容,但它不再起作用了。例如,我应该打开一个listview,它必须显示来自数据库的一些内容:我可以打开listview(当我这样做时我的应用程序没有崩溃),但它只是空的。

与我的beta应用程序的不同之处在于数据库的大小:它现在是4个月而不是几个ko。我已经阅读了一些关于存储在资产文件中的数据库大小的内容,但是之前的一个版本我可以使我的应用程序使用相同的数据库。
此外,我的logcat没有告诉我任何事情:我只是让我的应用程序工作正常,但没有显示它应该的任何东西。

这是我的代码(如果可以的话,我觉得我的代码与我通常在互联网上阅读的内容非常相似,包含了大量的catch / try / exception /各种类等等,所以也许它突然出现了严格要求的代码没有额外但是它适用于我的测试版):

A / DatabaseAdapter (我的方法是从数据库中获取数据,最后定义为findPoiInTable):

public class DatabaseAdapter {

public static final String DATABASE_TABLE = "tblpoisurvey";

public static final String KEY_ROWID = "_id";
public static final String COL_NAME = "name";
public static final String COL_CAT1 = "cat1";
public static final String COL_CAT2 = "cat2";
public static final String COL_CAT3 = "cat3";
public static final String COL_SUBCAT = "subcat";
public static final String COL_STREET = "street";

private Context myContext;
private SQLiteDatabase myDatabase;
private DatabaseHelper dbHelper;
private Cursor c;

// Constructor
public DatabaseAdapter(Context context) {
    this.myContext = context;
}

public DatabaseAdapter open() throws SQLException {
    dbHelper = new DatabaseHelper(myContext);
    try {
        dbHelper.createDatabase();
    } catch (IOException e) {
        e.printStackTrace();
    }
    myDatabase = dbHelper.getReadableDatabase();
    return this;
}


public void close() {
    if (c != null) {
        c.close();
    }
    try {
        dbHelper.close();
        myDatabase.close();
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}


public Cursor findPoiInTable(String inInterval) {
    String where = COL_CAT1 + " IN " + inInterval + " OR " + COL_CAT2
            + " IN " + inInterval + " OR " + COL_CAT3 + " IN " + inInterval;

    Cursor c = myDatabase.query(DATABASE_TABLE, new String[] { KEY_ROWID,
            COL_NAME, COL_STREET }, where, null, null, null, null);
    return c;
} }

B / My ResultListViewActivity ,调用方法的人,通过getExtra从另一个活动获取此方法的输入,并在listview中显示结果。

public class ResultListViewActivity extends Base_Activity {

private SimpleCursorAdapter cursorAdapter;
private DatabaseAdapter dbHelper;
ListView listView;
TextView poititle; 
private static String TAG = ResultListViewActivity.class.getSimpleName();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_result_list_view);

    poititle = (TextView) findViewById(R.id.poititle);
    dbHelper = new DatabaseAdapter(this);
    dbHelper.open();

    displayListView();
}

private void displayListView() {

    Bundle bundle = getIntent().getExtras();
    String title = bundle.getString("title", "Choose here :");  
    String inInterval = bundle.getString("inInterval");

    poititle.setText(title); // FYI: the title is displayed properly so the problem is not from the putExtra / getExtra

    Cursor c = dbHelper.findPoiInTable(inInterval);
    String[] columns = new String[] {DatabaseAdapter.COL_NAME,
            DatabaseAdapter.COL_STREET };

    int[] to = new int[] {R.id.name, R.id.street};

    cursorAdapter = new SimpleCursorAdapter(this, R.layout.poi_info, c, columns, to, 0);
    ListView listView = (ListView) findViewById(R.id.poilistview);
    listView.setAdapter(cursorAdapter);         
    }


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getSupportMenuInflater().inflate(R.menu.main, menu);
    return true;
}  } 

C / 我认为这不会有用,但如果是,我的 DatabaseHelper类

public class DatabaseHelper extends SQLiteOpenHelper {

private static String DB_NAME = "POIfinal";
private static int DB_VERSION = 1;
private static String DB_PATH = "/data/data/com.example.asiatypeapplicationbeta/databases/";
private static String TAG = DatabaseHelper.class.getSimpleName();

private SQLiteDatabase myDatabase;
private Context myContext;

public DatabaseHelper(Context context){
    super(context, DB_NAME, null, DB_VERSION);
    this.myContext = context ;
}

public void createDatabase() throws IOException {
    boolean dbExist = checkDatabase();
    if (!dbExist) {

        // By calling this method and empty database will be created into
        // the default system path
        // of your application so we are gonna be able to overwrite that
        // database with our database.
        this.getReadableDatabase();
        try {
            copyDatabase();
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }
}

/**
 * Check if the database already exists to avoid re-copying the file each
 * time you open the application.
 * 
 * @return true if it exists, false if it doesn't
 */
private boolean checkDatabase() {
    SQLiteDatabase checkDB = null;
    try {
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READONLY);
    } catch (SQLiteException e) {
        final String message = e.getMessage();
        return false;
    }
    checkDB.close();
    return checkDB != null ? true : false;
}

/**
 * Copies your database from your local assets-folder to the just created
 * empty database in the system folder, from where it can be accessed and
 * handled. This is done by transfering bytestream.
 * */

private void copyDatabase() throws IOException {
    // open the LOCAL DATABASE as the INPUT stream
    InputStream myInput = myContext.getAssets().open(DB_NAME);
    // path to the just created empty db
    String outfilename = DB_PATH + DB_NAME;
    // open the EMPTY DATABASE as the OUTPUT stream
    OutputStream myOutput = new FileOutputStream(outfilename);

    // transfer bytes from the INPUTfile to the OUTPUTfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }

    // close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();
}

public void openDatabase() throws SQLException {
    String myPath = DB_PATH + DB_NAME;
    try {
        myDatabase = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READONLY);
    } catch (SQLiteException e) {
        final String message = e.getMessage();
        if (message == null) {
            throw e;
        }
        if (!message.contains("attempt to write a readonly database")) {
            throw e;
        }
    }
}

@Override
public synchronized void close() throws SQLException {

    if (myDatabase != null)
        try {
            myDatabase.close();
            super.close();
        } catch (SQLException e) {

        }

}
@Override
public void onCreate(SQLiteDatabase arg0) {
    // TODO Auto-generated method stub

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
       Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
               + newVersion + ", which will destroy all old data");
       db.execSQL("DROP TABLE IF EXISTS notes");
       onCreate(db);
}  }

编辑:我的logcat图片,显示错误消息,仅在我第一次运行我的应用程序时(例如卸载后)。
enter image description here

1 个答案:

答案 0 :(得分:0)

查看您的Database Helper类我认为您正在尝试从资源文件夹中复制数据库。

所以在通过dbHelper.open()打开数据库之前;首先尝试将其复制到内部路径。 Databasehelper类中创建的方法数据库会将其复制到内部位置...然后尝试打开它。现在可能发生的事情是你的open()方法无法在给定的路径上找到数据库。

如果有的话,也尝试传递数据库名称及其扩展名“somedatabase.sqlite”。