问题描述
我在我的Android应用程序的一个大问题。我制定了第一次与SQLite数据库的Android应用程序,但我有我并不能解决问题。
我有名字saldb.sqlite对Eclipse项目的资产文件夹我的SQLite数据库
我有以下类来管理与Singletone模式数据库:
包sal.app.logic; 进口java.io.FileOutputStream中;
进口java.io.IOException异常;
进口的java.io.InputStream;
进口java.io.OutputStream中; 进口android.content.Context;
进口android.database.Cursor;
进口android.database.SQLException;
进口android.database.sqlite.SQLiteDatabase;
进口android.database.sqlite.SQLiteException;
进口android.database.sqlite.SQLiteOpenHelper; 公共类的DatabaseManager扩展SQLiteOpenHelper { 私有静态的DatabaseManager dbManagerInstance = NULL;
私人语境salContext;
私人SQLiteDatabase salDatabase;
私人静态字符串DB_PATH =/data/data/sal.app/databases/;
私人静态字符串DB_NAME =saldb.sqlite;
私人的DatabaseManager(上下文C)
{
超(C,DB_NAME,空,1);
//this.salContext = C;
} 公共静态的DatabaseManager getSalDatabase(上下文C)
{
如果(dbManagerInstance == NULL)
{
dbManagerInstance =新的DatabaseManager(C);
} 返回dbManagerInstance;
} 公共无效的CreateDatabase()抛出IOException 布尔dbExist = checkDataBase(); 如果(dbExist){
//什么也不做 - 已存在于数据库
}其他{ //通过调用此方法与空的数据库将被创建到默认的系统路径
//你的应用程序,所以我们要能够覆盖该数据库与我们的数据库。
this.getReadableDatabase(); 尝试{ copyDataBase(); }赶上(IOException异常五){ 抛出新的错误(错误复制数据库); }
} } 私人布尔checkDataBase()
{ SQLiteDatabase CHECKDB = NULL; 尝试{
字符串mypath中= DB_PATH + DB_NAME;
CHECKDB = SQLiteDatabase.openDatabase(mypath中,空,SQLiteDatabase.OPEN_READONLY); }赶上(SQLiteException E){ //数据库开不存在。 } 如果(CHECKDB!= NULL){ checkDB.close(); } 返回CHECKDB!= NULL?真假;
} 私人无效copyDataBase()抛出IOException //打开本地数据库的输入流
InputStream的myInput = salContext.getAssets()开(DB_NAME)。 //路径刚刚创建的空分贝
//字符串outFileName = DB_PATH + DB_NAME; 字符串outFileName =/data/data/sal.app/databases/saldb.sqlite;
//打开空分贝的输出流
的OutputStream myOutput =新的FileOutputStream(outFileName); //传递从inputfile中字节到OUTPUTFILE
字节[]缓冲区=新的字节[1024];
INT长;
而((长度= myInput.read(缓冲液))大于0){
myOutput.write(缓冲液,0,长度);
} //关闭流
myOutput.flush();
myOutput.close();
myInput.close(); } 公共无效的openDatabase()抛出的SQLException { //打开数据库
字符串mypath中= DB_PATH + DB_NAME;
salDatabase = SQLiteDatabase.openDatabase(mypath中,空,SQLiteDatabase.OPEN_READWRITE); } @覆盖
公共同步无效的close(){ 如果(salDatabase!= NULL)
salDatabase.close(); super.close(); } @覆盖
公共无效的onCreate(SQLiteDatabase DB){ //db.execSQL(\"Insert质疑(_id,水平,文本,idTopic)值(1,1,'ASA',0));
} @覆盖
公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){ } //添加您的公开辅助方法访问并从数据库中获取的内容。
//你可以做返回游标返回myDataBase.query(....),因此这将会是很容易
//你创建你的意见适配器。 公众质疑getOneQuestion()
{
// Versioni的列表,查询文本搜索结果 问寻求=新问题(); 尝试
{
//打开数据库查询
的openDatabase(); //salDatabase.execSQL(\"Insert质疑(_id,水平,文本,idTopic)值(1,1,'ASA',0)); //光标指针= salDatabase.rawQuery(选择文本,idTopic,从问题level其中level = 2,NULL); 光标光标= salDatabase.rawQuery(选择的问题*,NULL);
/ *光标光标= salDatabase.query(问题 新的String [] {文本,idTopic,级别},
电平= 2,
空值 ,
空值,
空值,
RANDOM()LIMIT 1); * / //光标C = db.rawQuery(选择,NULL); * / //映射的所有行数据对象
如果(cursor.moveToFirst())
{
的System.out.println(cursor.getString(2));
做
{
光标光标2 = salDatabase.rawQuery(SELECT * FROM WHERE主题_id = 0,NULL);
cursor2.moveToFirst();
主题T =新主题(cursor2.getString(1));
追求=新课题(cursor.getString(2),T(INT)cursor.getShort(1)); 打破;
}而(cursor.moveToNext()); }
//关闭游标
cursor.close();
}
赶上(异常前)
{
的System.out.println(DatabaseHelper.search() - :前+ ex.getClass()+,+ ex.getMessage());
}
//
返回任务; } / *公众的ArrayList<应答和GT; getAnswersOfQuestion(Questin Q)
{ } * /}
但是,在我第一次运行我的应用程序都已经释放了以下误差修改:
23 05-29:55:45.684:D / DDM堆(221):GOT功能列表请求
05-29 23:55:46.295:D / dalvikvm(221):GC释放519对象/在109ms 45792字节
05-29 23:55:46.544:E /数据库(221):sqlite3_open_v2(/数据/数据/ sal.app /数据库/ saldb.sqlite,&安培;手柄,1,NULL)失败。
23 05-29:55:46.594:D / AndroidRuntime(221):关闭VM
05-29 23:55:46.604:W / dalvikvm(221):主题ID = 3:螺纹未捕获的异常(组= 0x4001b188)
23 05-29:55:46.604:E / AndroidRuntime(221):未捕获的处理程序:螺纹主力退出,由于未捕获的异常
在我的主要活动即时通讯做这样的:
公共类SALActivity延伸活动{ 按钮后退;
按钮choiceA;
静态INT选择= 0;
的DatabaseManager分贝;
//按钮choiceB;
//按钮choiceC;
//按钮choiceD;
/ **当第一次创建活动调用。 * /
@覆盖
公共无效的onCreate(捆绑savedInstanceState){ super.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState); 的setContentView(R.layout.gamemenu);
// DB =新的DatabaseManager(本);
DB = DataBaseManager.getSalDatabase(本);
尝试{
db.createDataBase();
}赶上(IOException异常五){
// TODO自动生成catch块
e.printStackTrace();
}
//db=DataBaseManager.getSalDatabase(this); 问题Q = db.getOneQuestion(); //回来=(按钮)findViewById(R.id.gaveup_button);
choiceA =(按钮)findViewById(R.id.choice_a_button);
choiceA.setTextColor(为0xffffffff);
//choiceA.setText(\"A:Académica);
choiceA.setText(q.getQuestionText()); choiceA.setOnClickListener(新View.OnClickListener(){
公共无效的onClick(视图v){
}
}); //choiceA.setText(10);
// choiceB =(按钮)findViewById(R.id.choice_b_button);
// choiceC =(按钮)findViewById(R.id.choice_c_button);
// choiceD =(按钮)findViewById(R.id.choice_d_button); //意向V =新意图(这一点,SALActivity.class); //this.startActivity(v);
}
}
在我运行应用程序中的第二次,不要出现错误,数据库是在正确的路径,但只有表android_metadata P>
我也可以说,如果我把正确的数据库上/data/data/sal.app/databases/整个程序只是工作...
该错误是在copyDatabase。
这是我的工作code复制数据库。
私有静态字符串DB_PATH =/data/data/com.demo.databaseDemo/databases/;
私人静态字符串DB_NAME =myDatabase.db;
私人无效copyDataBase()抛出IOException //打开本地数据库的输入流
InputStream的myInput = _myContext.getAssets()开(DB_NAME)。 //路径刚刚创建的空分贝
字符串outFileName = DB_PATH + DB_NAME; //打开空分贝的输出流
的OutputStream myOutput =新的FileOutputStream(outFileName); //传递从inputfile中字节到OUTPUTFILE
字节[]缓冲区=新的字节[1024];
INT长;
而((长度= myInput.read(缓冲液))大于0){
myOutput.write(缓冲液,0,长度);
} //关闭流
myOutput.flush();
myOutput.close();
myInput.close(); } // copyDataBase的end()方法
I have a big problem in my android application. I'm develop for the first time an android application with a sqlite database but i have problems that i cant solve.
I have my sqlite database on assets folder of eclipse project with name saldb.sqlite
I have the following class to manage Database with Singletone pattern:
package sal.app.logic;
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 DataBaseManager extends SQLiteOpenHelper{
private static DataBaseManager dbManagerInstance = null;
private Context salContext;
private SQLiteDatabase salDatabase;
private static String DB_PATH = "/data/data/sal.app/databases/";
private static String DB_NAME = "saldb.sqlite";
private DataBaseManager(Context c)
{
super(c, DB_NAME, null, 1);
//this.salContext = c;
}
public static DataBaseManager getSalDatabase(Context c)
{
if (dbManagerInstance == null)
{
dbManagerInstance = new DataBaseManager(c);
}
return dbManagerInstance;
}
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");
}
}
}
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;
}
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = salContext.getAssets().open(DB_NAME);
// Path to the just created empty db
//String outFileName = DB_PATH + DB_NAME;
String outFileName = "/data/data/sal.app/databases/saldb.sqlite";
//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;
salDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
@Override
public synchronized void close() {
if(salDatabase != null)
salDatabase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
//db.execSQL("Insert Into Question(_id,level,text,idTopic) Values (1,1,'asa',0)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
// Add your public helper methods to access and get content from the database.
// You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
// to you to create adapters for your views.
public Question getOneQuestion()
{
//list of Versioni, search result with query text
Question quest = new Question();
try
{
//open database to query
openDataBase();
//salDatabase.execSQL("Insert Into Question(_id,level,text,idTopic) Values (1,1,'asa',0)");
//Cursor cursor = salDatabase.rawQuery("SELECT text, idTopic, level from Question WHERE level=2", null);
Cursor cursor = salDatabase.rawQuery("SELECT * from Question", null);
/*Cursor cursor = salDatabase.query("Question",
new String[] { "text","idTopic","level"},
"level=2",
null ,
null,
null,
"RANDOM() LIMIT 1");*/
//Cursor c = db.rawQuery(select, null); */
//mapped all rows to data object
if (cursor.moveToFirst())
{
System.out.println(cursor.getString(2));
do
{
Cursor cursor2 = salDatabase.rawQuery("SELECT * from Topic WHERE _id=0", null);
cursor2.moveToFirst();
Topic t = new Topic(cursor2.getString(1));
quest = new Question(cursor.getString(2),t,(int)cursor.getShort(1));
break;
} while (cursor.moveToNext());
}
//close cursor
cursor.close();
}
catch(Exception ex)
{
System.out.println("DatabaseHelper.search()- : ex " + ex.getClass() +", "+ ex.getMessage());
}
//
return quest;
}
/*public ArrayList<Answer> getAnswersOfQuestion(Questin q)
{
}*/
}
But in first time that i run my application i have de following erros:
05-29 23:55:45.684: D/ddm-heap(221): Got feature list request05-29 23:55:46.295: D/dalvikvm(221): GC freed 519 objects / 45792 bytes in 109ms05-29 23:55:46.544: E/Database(221): sqlite3_open_v2("/data/data/sal.app/databases/saldb.sqlite", &handle, 1, NULL) failed
05-29 23:55:46.594: D/AndroidRuntime(221): Shutting down VM05-29 23:55:46.604: W/dalvikvm(221): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
05-29 23:55:46.604: E/AndroidRuntime(221): Uncaught handler: thread main exiting due to uncaught exception
in my main Activity im doing this:
public class SALActivity extends Activity {
Button back;
Button choiceA;
static int choice = 0;
DataBaseManager db;
//Button choiceB;
//Button choiceC;
//Button choiceD;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.gamemenu);
//db= new DataBaseManager(this);
db=DataBaseManager.getSalDatabase(this);
try {
db.createDataBase();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//db=DataBaseManager.getSalDatabase(this);
Question q = db.getOneQuestion();
//back = (Button) findViewById(R.id.gaveup_button);
choiceA = (Button) findViewById(R.id.choice_a_button);
choiceA.setTextColor(0xffffffff);
//choiceA.setText("A: Académica");
choiceA.setText(q.getQuestionText());
choiceA.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
}
});
//choiceA.setText(10);
//choiceB = (Button) findViewById(R.id.choice_b_button);
//choiceC = (Button) findViewById(R.id.choice_c_button);
//choiceD = (Button) findViewById(R.id.choice_d_button);
//Intent v = new Intent(this, SALActivity.class);
//this.startActivity(v);
}
}
In the second time that i run app, error dont occur, database are in the correct path but only have the table android_metadata
I also could say that if i put the correct dataBase on /data/data/sal.app/databases/ the entire program just works...The error is in the copyDatabase.
This is my working code to copy database.
private static String DB_PATH = "/data/data/com.demo.databaseDemo/databases/";
private static String DB_NAME = "myDatabase.db";
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();
}//end of copyDataBase() method
这篇关于在资产文件夹自己的数据库在Android的Eclipse项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!