0

我已经尝试了几个使用数据库的代码。我正在尝试使用我复制到资产文件夹的现有数据库。我希望我的弹出窗口显示 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”并将其复制到资产文件夹中。我的 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 显示的类型。我应该怎么做才能使查询结果显示在弹出窗口中。当我运行这个时,我得到了很多错误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

仍然有很多错误

4

4 回答 4

2

通过发送一些简单的 SQL 来测试数据库连接很容易,例如

 select 1;

这应该准确地返回 1 而没有其他任何东西,并且当没有与数据库的连接时它肯定会失败。此类查询不承担创建或访问任何表的权限,不修改任何内容并且独立于实际数据库内容工作。

于 2013-08-29T19:31:00.100 回答
0

您收到的错误消息表明数据库文件/data/data/com.example.singlepop/databases/MyDatabase不存在。你能检查一下吗?

此外,一旦这有效,Cursor代表您从查询中获得的所有结果。可以返回多条记录。您首先将光标定位到要阅读的行,然后您可以访问各个列。例如(省略所有错误处理并假设您的表有一个名为 的列col1):

check.moveToFirst();
String col1 = check.getString(check.getColumnIndex("col1"));
于 2013-08-28T15:10:24.240 回答
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();
        }
    }
}

我希望这能回答你的问题。如果没有,请询​​问。

于 2013-08-28T15:17:22.690 回答
0

您的数据库文件位于 assets 文件夹中。并且您正在调用createDataBase(),您首先使用 . 检查数据库是否存在checkDataBase()。然后您正在调用copyDataBase();

因此,当您尝试在/data/data/com.example.singlepop/databases/MyDatabase. 在checkDataBase()你得到那个例外,因为数据库仍然在 /assets 文件夹中,直到你调用 copyDatabase()

IE。

  1. error opening trace file: No such file or directory
  2. android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database

您必须先将数据库复制到适当的位置,然后再尝试打开它。

我建议你使用CommonsWare 自己推荐的SQLiteAssetHelper 。

于 2013-08-29T19:55:57.353 回答