0

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

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

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

这是我的代码(如果可以的话,我觉得我的代码与我通常在互联网上阅读的包含大量捕获/尝试/异常/各种类等的代码相比非常轻巧,所以也许它只是严格要求的代码,没有额外的但它适用于我的测试版):

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/我的 ResultListViewActivity,调用该方法的人,通过 getExtra 从另一个活动获取此方法的输入,并在列表视图中显示结果。

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 图片,仅在我第一次运行我的应用程序时(例如在卸载它之后)。
在此处输入图像描述

4

1 回答 1

0

看到您的数据库助手类,我认为您正在尝试从资产文件夹中复制数据库。

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

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

于 2013-03-13T04:33:19.200 回答