2013-08-28 124 views
0

我已經嘗試了使用數據庫的幾個代碼。我想使用現有的數據庫,我複製到資產文件夾。我希望我的彈出窗口顯示sql查詢的結果。我試過的代碼是如何在android中檢查數據庫連接是否成功?

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」,並將其複製到assets文件夾中。我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 

仍然有很多錯誤

回答

0

你得到的錯誤消息表明,一個數據庫文件/data/data/com.example.singlepop/databases/MyDatabase不存在。你可以檢查嗎?

此外,一旦這項工作,Cursor代表您從查詢中獲得的所有結果。可以返回多個記錄。您首先將光標定位到您想要閱讀的行,然後您可以訪問各個列。例如(離開了所有的錯誤處理,並假設你的表中有一個名爲col1列):

check.moveToFirst(); 
String col1 = check.getString(check.getColumnIndex("col1")); 
+0

我走進了工作區並沿着路徑走。我只找到2個.java文件,但沒有找到MyDatabase。這是否意味着連接不成立? – user2648852

+0

如果我有超過1列回來,我應該使用什麼? – user2648852

+0

重複其他列的最後一行。 – Henry

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(); 
     } 
    } 
} 

我希望這會回答你的問題。如果沒有,請詢​​問。

+0

我有一個數據庫有2個字段,ID和說明。我已經使用sqlite瀏覽器創建了這個數據庫。我的應用程序應該在我的數據庫的「描述」字段中顯示內容。我已經指定了它應該在我的代碼中顯示的位置 – user2648852

+0

我的應用必須在早上每天顯示一個彈出窗口。彈出窗口應該是我數據庫描述字段中的內容。這就是我需要的 – user2648852

+0

哦,好的。那麼,首先您需要知道該應用程序預計數據庫位於/ data/data/ /database/YourDatabase.db中。你必須嘗試,如果它從另一個文件夾工作,我不確定。所以讓我們假設你已經把它放在正確的地方,然後採取我的代碼,但保持onCreate和onUpgrade爲空,更改數據庫和表名稱,相應地修改列名稱,然後可以使用readName(id)來獲取你的描述(當然你也應該重命名該方法)。希望有所幫助! – metter

1

這是很容易通過發送一些瑣碎的SQL像

select 1; 

這應該只返回1,並沒有別的測試數據庫連接,當有到數據庫的連接必定會失敗。此類查詢不承擔創建或訪問任何表的權利,不會修改任何內容並獨立於實際數據庫內容工作。

0

您的數據庫文件位於資產文件夾中。並且您打電話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

相關問題