1

我想顯示數據從我的數據庫在ListView小部件。使用SearchView小部件查詢數據庫。從外部SQlite數據庫查詢與SearchView小部件填充ListView - Android

這裏是我的SQlite的開放輔助類代碼:

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; 


import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

public class DataBaseHelper extends SQLiteOpenHelper { 

//The Android's default system path of your application database. 

private static String DB_NAME = "DB.sqlite"; 

private SQLiteDatabase myDB; 

private final Context myContext; 


/** 
* Constructor 
* Takes and keeps a reference of the passed context in order to access to the application assets and resources. 
* @param context 
*/ 
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 = myContext.getDatabasePath(DB_NAME).getPath(); 
     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 = myContext.getDatabasePath(DB_NAME).getPath(); 

    //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 = myContext.getDatabasePath(DB_NAME).getPath(); 
    myDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

} 

@Override 
public synchronized void close() { 

    if(myDB != null) 
     myDB.close(); 

    super.close(); 

} 

@Override 
public void onCreate(SQLiteDatabase myDataBase) { 

} 


@Override 
public void onUpgrade(SQLiteDatabase myDataBase, int oldVersion, int newVersion) { 

} 



public Cursor getC(String animal) { 
    Cursor c; 
    c=myDB.rawQuery("SELECT * FROM Table where animal MATCH ?", new String [] {animal}); 
    c.moveToFirst(); 

    return c; 
} 




} 


// 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. 

這裏是我的光標適配器類代碼:

import android.content.Context; 
import android.database.Cursor; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.CursorAdapter; 
import android.widget.TextView; 


public class TodoCursorAdapter extends CursorAdapter { 

private LayoutInflater mInflater; 

public TodoCursorAdapter(Context context, Cursor c, int flags) { 
    super(context, c, flags); 
    mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

/* ... */ 

@Override 
public View newView(Context context, Cursor cursor, ViewGroup parent) { 
    return mInflater.inflate(R.layout.search_item, parent, false); 
} 



// The bindView method is used to bind all data to a given view 
// such as setting the text on a TextView. 

@Override 
public void bindView(View view, Context context, Cursor cursor) { 
    TextView content = (TextView) view.findViewById(R.id.résultatAnimal); 
    content.setText(cursor.getString(2)); 

    } 
} 

這裏是我的搜索活動代碼:

import android.app.ListActivity; 
import android.app.SearchManager; 
import android.content.Intent; 
import android.database.SQLException; 
import android.os.Bundle; 
import android.widget.ListView; 


import java.io.IOException; 


public class searchableActivity extends ListActivity { 



@Override 
public void onCreate(Bundle savedInstanceState) { 

    DataBaseHelper myDbHelper = new DataBaseHelper(searchableActivity.this); 

    try { 

     myDbHelper.createDataBase(); 

    } catch (IOException ioe) { 

     throw new Error("Unable to create database"); 

    } 

    try { 

     myDbHelper.openDataBase(); 

    }catch(SQLException sqle){ 

     throw sqle; 

    } 


    super.onCreate(savedInstanceState); 



    // Get the intent, verify the action and get the query 
    Intent intent = getIntent(); 
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) { 
     String query = intent.getStringExtra(SearchManager.QUERY); 
     //myDbHelper.getC(query).getString(2); 
     // Find ListView to populate 
     ListView AnimalListe = (ListView) findViewById(R.id.list); 
// Setup cursor adapter using cursor from last step 
     TodoCursorAdapter todoAdapter = new TodoCursorAdapter(this, myDbHelper.getC(query), 0); 
// Attach cursor adapter to the ListView 
     AnimalListe.setAdapter(todoAdapter); 
    } 

    myDbHelper.close(); 
} 
} 

當我在我的SearchView小部件中啓動搜索時,出現「NULL POINTER EXCEPTION」錯誤, e應用程序崩潰。爲什麼?

+0

我已經改變了 「公共類searchableActivity擴展ListActivity」 在我的搜索活動 「公共類searchableActivity擴展活動」,而現在它的工作原理! –

回答

0

請首先檢查是否在Android Monitor中創建數據庫。 我認爲你的代碼是寫的,但有一段時間寫在copydatabase中寫下面的代碼。

私人無效copyDataBase()拋出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 = myContext.getDatabasePath(DB_NAME).getPath(); 

File file=outFileName; 

if(!file.isExits) 
    file.mkdir(); 

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

}

+0

謝謝,但我認爲問題出在遊標適配器類或可搜索活動中,因爲當我試圖從我的SQlite打開幫助器類中的「getC」方法查詢數據庫時,不使用SearchView,然後顯示在TextView中的結果,它工作得很好。但我仍然沒有發現問題... –