2012-03-28 12 views
15

Ho un database SQLite che desidero interrogare. Voglio scegliere come target Android 2.2 tramite ICS. Ho trovato l'articolo this su come eseguire questa operazione, ma utilizza codice deprecato (non esegue una query in modo asincrono, ma sul thread dell'interfaccia utente). Da allora ho letto che posso usare CursorLoader insieme a LoaderManager per fare questa attività il modo migliore, preferibile (per non impantanare il thread dell'interfaccia utente).Utilizzo di CursorLoader per eseguire query su DB SQLite e compilare AutoCompleteTextView

Il problema è trovare un esempio conciso per spiegarmi come eseguire questa operazione. 1) Carica il database, 2) interrogalo, 3) usa il risultato per compilare una vista elenco di AutoCompletetextBox.

Esiste un simile esempio?

+0

Cercando anche di trovare un esempio come questo. Quelli che trovo sembrano non avere un cursore. – kpierce8

+0

Sto facendo qualcosa di simile QUI !! http://stackoverflow.com/questions/12854336/autocompletetextview-backed-by-cursorloader – toobsco42

risposta

1

So che questa è una vecchia questione, ma per le persone che visitano questa pagina:

SimpleCursorAdapter ha un nuovo costruttore:

SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) 

questo cunstructor non usa il thread dell'interfaccia utente. Puoi usarlo sicuro.

0

Ho creato una classe SQLiteHelper. Im il mio caso, ho un database SQLite che copio dalla cartella beni per la/directory/dati dati se non c'è:

private DatabaseHelper(Context context, String name, CursorFactory factory, 
     int version) { 
    super(context, DB_NAME, null, 1); 
    this.mContext = context; 
} 

// getInstance() singleton 
public static synchronized DatabaseHelper getInstance(Context context) { 
    if (_instance == null) { 
     _instance = new DatabaseHelper(context,null,null,1); 
    } 
    return _instance; 
} 

@Override 
public void onCreate(SQLiteDatabase db) { 
    // Leave it blank, we don't want to create. 

} 

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
    // Leave it blank, we don't want to upgrade 

} 

public void createDataBase() throws IOException{ 

    boolean dbExist = checkDataBase(); 

    if(dbExist){ 
     openDataBase(); 
     // check the version number; 
     SQLiteCursor cursor = runQuery("select versionNumber from version where VersionType = \"CURRENT\""); 
     if (cursor!=null){ 
      cursor.moveToFirst(); 
      int version = cursor.getInt(cursor.getColumnIndex("versionNumber")); 
      if (version!=SQL_VERSION){ 
       //TODO - grab the favorites and ingredients first. 
       ArrayList<String> favorites = getFavorites(); 
       // I think I need to close the db before erasing it, then open new one. 
       close(); 
       mContext.deleteDatabase(DB_NAME); 
       this.getReadableDatabase(); 
       copyDataBase(); 
       openDataBase(); 
       for (int i = 0; i<favorites.size();i++){ 
        insert(Constants.TABLE_FAVORITES,Constants.FAVORITE,favorites.get(i)); 
       } 
       close(); 
      } 
     } 
    }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(); 

     copyDataBase(); 
    } 
} 

private void copyDataBase(){ 

    //Open your local db as the input stream 
    InputStream myInput; 
    try { 
     myInput = mContext.getAssets().open(DB_NAME); 
     // Path to the just created empty db 
     String outFileName = LOCATION + 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(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

} 

public void openDataBase() throws SQLException{ 
    //Open the database 
    String myPath = LOCATION + DB_NAME; 
    mDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); 

} 

@Override 
public synchronized void close() { 
    if(mDatabase != null) 
     mDatabase.close(); 
    super.close(); 
} 

public SQLiteCursor runQuery(String query){ 
    return (SQLiteCursor) mDatabase.rawQuery(query,null); 
} 

private boolean checkDataBase(){ 

    SQLiteDatabase checkDB = null; 

    try{ 
     String myPath = LOCATION + 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; 
} 

// all insert does is insert to favorites and into your bar. 
public void insert(String table, String column, String value) { 
    ContentValues values = new ContentValues(); 
    values.put(column, value); 
    mDatabase.insert(table, null, values); 

} 

public void delete(String table, String column, String value){ 
    mDatabase.delete(table,column+" = \""+value+"\"",null); 
} 

Per riempire l'auto completamento automatico TextView sulla mia attività:

startManagingCursor(mCursor); 
    // get instance of database helper class 
    mDatabaseHelper = DatabaseHelper.getInstance(this); 
    // create database for first time 
    try { 
     mDatabaseHelper.createDataBase(); 
    } catch (IOException e) { 
     //Log.i(TAG,"Could not create the database"); 
     e.printStackTrace(); 
    } 
    // open the database 
    mDatabaseHelper.openDataBase(); 
      mDrinks = this.populate(); 

metodo popolare:

//populates by drinks 
private ArrayList<String> populate() { 
    ArrayList<String> items = new ArrayList<String>(); 
    mCursor = mDatabaseHelper.runQuery(
      "select "+ Constants.TITLE +" from " 
      +Constants.TABLE_DRINK+" order by " 
      +Constants.TITLE); 
    if (mCursor != null){ 
     mCursor.moveToFirst(); 
     while (!mCursor.isAfterLast()){ 
      items.add(mCursor.getString(mCursor.getColumnIndex(Constants.TITLE))); 
      mCursor.moveToNext(); 
     } 
    } 
    return items; 
} 

Poi ho impostato:

// when text changes, autocomplete happens 
    mSearchTextView = (AutoCompleteTextView) findViewById(R.id.search_drink); 
    mSearchTextView.setAdapter(
      new ArrayAdapter<String>(
        this, R.layout.list_item, mDrinks)); 
    mSearchTextView.setClickable(true); 
    // clear the text when the searchTextView is clicked. Necessary for 
    // clearing after pressing enter in an invalid drink. 
    mSearchTextView.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      mSearchTextView.setText(""); 

     } 
    }); 
    mSearchTextView.setOnItemClickListener(new OnItemClickListener(){ 

     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, 
       long arg3) { 
      // TODO - here we need to get the name, then search for ingredients and show everything in 
      // an alert dialog. Here is main logic. 
      buildDialog(parent.getItemAtPosition(position).toString()); 
     } 

    }); 
    mSearchTextView.setOnEditorActionListener(new OnEditorActionListener() { 

     @Override 
     public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 
      if (event != null&& (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) { 
       InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
       in.hideSoftInputFromWindow(mSearchTextView 
         .getApplicationWindowToken(), 
         InputMethodManager.HIDE_NOT_ALWAYS); 
       Toast.makeText(v.getContext(), "Please Select a Drink from the Auto Complete or the List Shown", Toast.LENGTH_LONG).show(); 
      } 

      return false; 
     } 
    }); 

Spero che tu capisca. Non posso darti la mia piena fonte perché è in un'app di mercato che ho sviluppato. È possibile controllarlo fuori prima di tentare di fare tutto il lavoro: https://play.google.com/store/apps/details?id=com.life.plus.studios.bartender.drink.recipes.light

+0

Grazie. Dovrò controllare la tua implementazione. Come la tua app! – mraviator

+0

Np. Se hai ulteriori domande fammi sapere poiché non ho messo la fonte completa alcune cose potrebbero essere confuse. –

+6

Avrei un downnvote, ma non ho abbastanza reputazione, perché la risposta non implementa CursorLoader, che è la migliore pratica e ciò che è stato chiesto. – CraPo

Problemi correlati