我在使用数据库时尝试了几个代码。我正在尝试使用我复制到assets文件夹的现有数据库。我希望我的弹出窗口显示SQL查询的结果。我试过的代码是
package com.example.singlepop;
import java.io.IOException;
import java.util.Calendar;
import android.os.Bundle;
import android.app.Activity;
import android.database.Cursor;
import android.database.SQLException;
import android.view.Menu;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
public class Single extends Activity {
PopupWindow popUp;
LinearLayout layout;
TextView tv;
LayoutParams params;
LinearLayout mainLayout;
Button but;
boolean click = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DataBaseHelper myDbHelper = new DataBaseHelper(this);
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
myDbHelper.openDataBase();
}catch(SQLException sqle){
throw sqle;
}
popUp = new PopupWindow(this);
layout = new LinearLayout(this);
mainLayout = new LinearLayout(this);
final Calendar cld = Calendar.getInstance();
int time = cld.get(Calendar.HOUR_OF_DAY);
if(time==20)
{
tv = new TextView(this);
but = new Button(this);
but.setText("Click me for pop up");
but.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (click) {
popUp.showAtLocation(layout, Gravity.BOTTOM, 10, 10);
popUp.update(50, 50, 300, 80);
click = false;
} else {
popUp.dismiss();
click = true;
}
}
});
params = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
layout.setOrientation(LinearLayout.VERTICAL);
//tv.setText("Time is 8 pm");
// display the outcome of the query
tv.setText(myDbHelper.thought());
layout.addView(tv, params);
popUp.setContentView(layout);
// popUp.showAtLocation(layout, Gravity.BOTTOM, 10, 10);
mainLayout.addView(but, params);
setContentView(mainLayout);
}
else
{
tv.setText("NO TIME");
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.single, menu);
return true;
}
}
这段代码让我成功弹出。我有一个数据库“MyDatabase”创建n复制到资产文件夹。我的DataBaseHelper类是
package com.example.singlepop;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
public class DataBaseHelper extends SQLiteOpenHelper {
private static final int _id = 1;
//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/com.example.singlepop/databases/";
private static String DB_NAME = "MyDatabase";
private SQLiteDatabase myDataBase;
private final Context myContext;
private static String DB_TABLE = "Totlist";
private static final String tot = null;
String des=tot;
/**
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
*/
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exist
}else{
//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 exist 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){
//database does't exist yet.
}
if(checkDB != null){
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 your local db 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 db 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{
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// This function should return the outcome of the query but below code is wrong
public String thought()
{
String quer="Hello";
String sql = "SELECT * FROM option WHERE id = 1";
Cursor check = myDataBase.rawQuery(sql, null);
quer=String.valueOf(check);
return quer;
}
}
rawQuery
返回Cursor
类型,我无法使用setText显示该类型。我应该怎么做,以便我可以在弹出窗口中显示b的查询结果。
当我运行这个时,我在logcat
中遇到了很多错误。它可能是连接问题。
08-28 20:00:57.396: E/Trace(841): error opening trace file: No such file or directory (2)
08-28 20:00:59.003: E/SQLiteLog(841): (14) cannot open file at line 30176 of [00bb9c9ce4]
08-28 20:00:59.023: E/SQLiteLog(841): (14) os_unix.c:30176: (2) open(/data/data/com.example.singlepop/databases/MyDatabase) -
08-28 20:00:59.173: E/SQLiteDatabase(841): Failed to open database '/data/data/com.example.singlepop/databases/MyDatabase'.
08-28 20:00:59.173: E/SQLiteDatabase(841): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
仍有很多错误
答案 0 :(得分:1)
通过发送一些简单的SQL(如
)来测试数据库连接很容易 select 1;
这应该返回1而不是其他任何东西,并且当没有与数据库的连接时肯定会失败。此类查询不承担创建或访问任何表的权限,不会修改任何内容并独立于实际数据库内容工作。
答案 1 :(得分:0)
您收到的错误消息表明数据库文件/data/data/com.example.singlepop/databases/MyDatabase
不存在。你能检查一下吗?
此外,一旦此方法有效,Cursor
代表您从查询中获得的所有结果。可以返回多条记录。首先将光标定位到要读取的行,然后您可以访问各个列。例如(省略所有错误处理并假设您的表有一个名为col1
的列):
check.moveToFirst();
String col1 = check.getString(check.getColumnIndex("col1"));
答案 2 :(得分:0)
我不确定我理解你的问题,但是这里是你如何设置和读取数据库:
public class SQLTest extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "TestDatabase.db";
private static final int DATABASE_VERSION = 1;
private Context context;
public static final String TABLENAME = "mytable";
public static final String COL_ID = "_id";
public static final String COL_NAME = "name";
public SQLSimple(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
String STATEMENT_CREATE = "create table if not exists '"+TABLENAME+"' ("
+COL_ID+" integer primary key autoincrement, "
+COL_NAME+" text not null, "
db.execSQL(STATEMENT_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String STATEMENT_DROP = "drop table if exists '"+TABLENAME+"';";
db.execSQL(STATEMENT_DROP);
onCreate(db);
}
public String readName(int id) {
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = null;
try {
//Return these two columns only. Here, we only have two of course, but in a bigger table this is good for performance.
String[] projection = new String[]{COL_ID, COL_NAME};
//The where part of the query that defines what we are looking for
String selection = COL_ID + " = ?";
//The data that will replace the ? in the query before. Doing it this way is to prevent injection and escaping errors
String selectionArgs[] = new String[]{id+""};
cursor = db.query(TABLENAME, projection, selection, selectionArgs, null, null, null);
String name = null;
if(cursor.moveToFirst()) {
String name = cursor.getString(cursor.getColumnIndex(COL_NAME));
}
return name;
} finally {
//Close the database before returning item, even in the case of an exception
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
if (db.isOpen()) {
db.close();
}
}
}
我希望这能回答你的问题。如果没有,请询问。
答案 3 :(得分:0)
您的数据库文件位于assets文件夹中。您正在调用createDataBase()
,首先使用checkDataBase()
检查是否存在数据库。然后您调用copyDataBase()
;
因此,当您尝试在/data/data/com.example.singlepop/databases/MyDatabase
打开数据库时。
在checkDataBase()
中,您得到该异常,因为数据库仍在/ assets文件夹中,直到您调用copyDatabase()
即。
error opening trace file: No such file or directory
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
在尝试打开数据库之前,您必须先将数据库复制到适当的位置。
我建议您使用CommonsWare自己推荐的SQLiteAssetHelper。