2010-12-13 32 views
5

Tôi không hiểu tại sao tôi không thể sao chép tệp db của mình (abic_) vào thư mục ứng dụng ("/ data/data /" + context.getPackageName() + "/ cơ sở dữ liệu")Sao chép DB SQLite của riêng tôi từ thư mục Nội dung sang

Đây là lớp DataBaseHelper tôi:


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

import android.content.Context; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteException; 
import android.database.sqlite.SQLiteOpenHelper; 


public class DataBaseHelper extends SQLiteOpenHelper{ 

    //The Android's default system path of your application database. 
    private String DB_PATH; 

    private static String DB_NAME = "abic_"; 
    private static final Integer DB_VERSION = 1; 

    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, DB_VERSION); 
     this.myContext = context; 
     DB_PATH = "/data/data/" + context.getPackageName() + "/databases"; 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) {; 
    } 

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

public void apriDatabase() throws SQLException { 
    try { 
      String percorso = DB_PATH + DB_NAME; 
      mydb = SQLiteDatabase.openDatabase(percorso, null, SQLiteDatabase.OPEN_READONLY); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
} 

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) { 
        e.printStackTrace(); 
      } 
    } 
} 

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; 

    // if the path doesn't exist first, create it 
    File f = new File(outFileName); 
    if (!f.exists()){ 
      f.mkdir(); 
      f.createNewFile(); 
    } 

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

} 

private boolean checkDataBase(){ 

    SQLiteDatabase checkDB = null; 

    try{ 
      String myPath = DB_PATH + DB_NAME; 
      checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE); 

    }catch(SQLiteException e){ 

      //database does't exist yet. 

    } 

    if(checkDB != null){ 

      checkDB.close(); 

    } 

    return checkDB != null ? true : false; 
} 

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

}

Đây là listview mà sử dụng lớp này:

import android.app.ListActivity; 
import android.content.Intent; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.EditText; 
import android.widget.ListAdapter; 
import android.widget.ListView; 
import android.widget.SimpleCursorAdapter; 

public class abicabList extends ListActivity { 

     protected EditText searchText; 
     protected SQLiteDatabase mydb; 
     protected Cursor cursor; 
     protected ListAdapter adapter; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     mydb = (new DataBaseHelper(this)).getWritableDatabase(); 
     searchText = (EditText) findViewById (R.id.searchText); 
    } 

    public void search(View view) { 

    String text = searchText.getText().toString(); 
    String cap = "CAP"; 
    // || is the concatenation operation in SQLite 
     if (text.length()14) {  
cursor = mydb.rawQuery("SELECT _id, ABI, BANCA, CAB, CAP, Filiale, City FROM abicab WHERE ABI || CAB LIKE ? LIMIT 30", 
      new String[]{"%" + searchText.getText().toString().substring(6,10) + "%" + searchText.getText().toString().substring(11,15) + "%"});  
    adapter = new SimpleCursorAdapter( 
           this, 
           R.layout.abicab_list_item, 
           cursor, 
           new String[] {"BANCA", "Filiale", "City", "CAP"}, 
       new int[] {R.id.BANCA, R.id.Filiale, R.id.City ,R.id.CAP}); 
     setListAdapter(adapter); 
    } 

    }

Vì vậy, khi tôi chạy ứng dụng db được tạo ra trong thư mục nhưng nó không chứa bảng tha t là trong db tôi có trong thư mục tài sản (xem hình ảnh [1]: http://i.stack.imgur.com/AaFj8.jpg). Cảm ơn trước sự giúp đỡ của bạn.

Trả lời

3

Tôi đã giải quyết được vấn đề.

1) Tôi đã sử dụng lớp AlmanacSQLiteDatabaseAdapter.java được sử dụng trong Almanac 0.0.17 (dự án nguồn mở) mà bạn có thể tìm thấy tại đây: link. Bạn có thể phù hợp với nhu cầu của bạn (trong trường hợp của tôi tôi đã đổi tên thành DatabaseHelper);

2) Đây là lớp sử dụng Trình trợ giúp (đó là chế độ xem danh sách thực hiện chuỗi đọc thô tục trong một EditText - đó là sự sắp xếp của hướng dẫn này "coenraets.org/blog/android-samples/androidtutorial/" :

public class MiaList extends Activity { 

     protected EditText searchText; 
     protected SQLiteDatabase db; 
     protected Cursor cursor; 
     protected ListAdapter ladapter; 
     protected ListView miaList; 
     private static final String DATABASE_NAME = "miodb.jpg"; 
/* 
L'ESTENSIONE JPG (o mp3, mov) questo perchè android ha il limite di 1 mb per i file di testo 
o simili nella asset, mentre NON HA limiti per i file multimediali! Nel mio caso si tratta di 4mb 
*/ 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

//qui sotto richiamo la classe DatabaseHelper 

     DatabaseHelper dbAdapter = DatabaseHelper.getInstance(this, DATABASE_NAME); 
     /*note di Vytek*/ 
     // OK Dovrei usare aSQLiteDatabaseAdapter.getDatabase(); ma questo crea 
     // problemi nella fase di OnPause quando premo Back cosi' invece non 
     // ottengo errori 
     // e viene fatta la normale copia del DB (13/8/2010 23.18) 
     // db = aSQLiteDatabaseAdapter.getWritableDatabase(); 
     // Per ovviare a questo problema controllo se e' la prima volta che 
     // chiamo applicazione 
     if (getFirstRun()) { 
       db = dbAdapter.getDatabase(); 
       setRunned(); 
     } else { 
       db = dbAdapter.getWritableDatabase(); 
     } 

     searchText = (EditText) findViewById (R.id.searchText); 
     miaList = (ListView) findViewById (R.id.list); 
    } 


    private void setRunned() { 
       // TODO Auto-generated method stub 

     } 

     private boolean getFirstRun() { 
       // TODO Auto-generated method stub 
       return false; 
     } 

     public void search(View view) { 

     String text = searchText.getText().toString(); 
     // || è l'operatore "concatena" in SQLite 
     if (text.length()<15){ 
        cursor = db.rawQuery("SELECT *FROM miatable WHERE AAA || ' ' || BBB || ' ' || CCC LIKE ? LIMIT 30", 
          new String[]{"%" + searchText.getText().toString() + "%"}); 
           ladapter = new SimpleCursorAdapter( 
               this, 
               R.layout.mialist_list_item, 
               cursor, 
               new String[] {"_id", "AAA", "BBB", "CCC"}, 
               new int[] {R.id._id, R.id.AAA, R.id.BBB, R.id.CCC}); 
           miaList.setAdapter(ladapter); 
           //istruzione da eseguire 
       } 
     else {   
        cursor = db.rawQuery("SELECT * FROM miatable WHERE AAA || BBB LIKE ? LIMIT 30", 
          new String[]{"%" + searchText.getText().toString().substring(6,10) + "%" + searchText.getText().toString().substring(11,15) + "%"});   
           ladapter = new SimpleCursorAdapter( 
               this, 
               R.layout.mialist_list_item, 
               cursor, 
               new String[] {"_id", "AAA", "BBB", "CCC"}, 
               new int[] {R.id._id, R.id.AAA, R.id.BBB, R.id.CCC}); 
           miaList.setAdapter(ladapter); 
           //istruzione da eseguire 
        } 


     } 

} 

Tất nhiên SQLite dB "miodb.jpg" phải nằm trong thư mục tài sản của không gian làm việc của Eclipse

PS tôi đã sử dụng phần mở rộng jpg cho db + Nhà thư mục tài sản có. giới hạn 1Mb cho tiện ích mở rộng db hoặc txt hoặc xml.

2

Bạn đang sử dụng Trình mô phỏng hoặc thiết bị?

Tôi làm thủ tục tương tự nhưng tôi sao chép cơ sở dữ liệu vào thẻ SD, bởi vì trình giả lập có kích thước không gian hạn chế, kích thước cơ sở dữ liệu của bạn là bao nhiêu?


Thay thế phương thức sao chép bằng phương pháp này và cho tôi biết vì tôi không thể tìm thấy bất kỳ điều gì lạ ngoại trừ phương pháp sao chép, Chúc may mắn.

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

} 
+0

Các giả lập. Vấn đề không phải là kích thước mà là bản sao. Infact nếu bạn có một cái nhìn vào pic tôi đã liên kết Bạn sẽ xác minh những gì tôi có ý nghĩa. – Giumazzi

+0

Trình giả lập. Vấn đề không phải là kích thước mà là bản sao. Infact nếu bạn có một cái nhìn vào pic tôi đã liên kết Bạn sẽ xác minh những gì tôi có ý nghĩa. Tuy nhiên, nếu U muốn đăng bài như thế nào bạn đã giải quyết gắn mã của bạn, tôi sẽ rất hài lòng. Địa chỉ của tôi là giumazzi (at) gmail com. – Giumazzi

+0

Vui lòng xem cập nhật. –

0

Đây là mã đơn giản và thuận tiện mà tôi sử dụng:

public class DataBaseImportHelper { 
    private DataBaseImportHelper() {}; // Avoid instantiation 

/** 
* Creates a empty database on the system and rewrites it with your own database. 
*/ 
public static boolean importDataBase(Context context) { 
    InputStream myInput = null; 
    OutputStream myOutput = null; 
    try { 
     // Open local db from assets as the input stream 
     myInput = context.getAssets().open(DATABASE_NAME); 
     createEmptyDatabase(context); // See this method below 
     // Open the empty db as the output stream 
     myOutput = new FileOutputStream(getDatabaseFile(context)); 

     // 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(); 
     myInput.close(); 
     myOutput.close(); 
     return true; 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return false; 
} 

/** 
* Check if the database already exists. 
* @return true if it exists, false if it doesn't 
*/ 
public static boolean isDatabaseExists(Context context) { 
    return getDatabaseFile(context).exists(); 
} 

private static File getDatabaseFile(Context context) { 
    return context.getDatabasePath(DatabaseHelper.DATABASE_NAME); 
} 

/** 
* Create an empty database into the default application database 
* folder.So we are gonna be able to overwrite that database with our database 
*/ 
private static void createEmptyDatabase(Context context) { 
      // use anonimous helper to create empty database 
    new SQLiteOpenHelper(context, DatabaseHelper.DATABASE_NAME, null, 1) { 
        // Methods are empty. We don`t need to override them 
     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     } 

     @Override 
     public void onCreate(SQLiteDatabase db) { 
     } 
    }.getReadableDatabase().close(); 
} 

}

Và sử dụng trong mã:

if(!DataBaseImportHelper.isDatabaseExists(this)){ 
    if (!DataBaseImportHelper.importDataBase(this)){ 
      throw new IllegalStateException("Database doesn`t exist and hasn`t been copied!"); 
    } 
} 
2

trước hết là đảm bảo bạn thêm android.permission .WRITE_EXTERNAL_STORAGE cho phép tệp kê khai của bạn. Trong một ứng dụng của tôi, tôi đã sử dụng lớp dưới đây và nó hoạt động hoàn hảo. Hãy thử điều này và cho tôi biết nếu nó hoạt động.

public class ImpotDatabaseFileTask extends AsyncTask<String, Void, Boolean> { 
ProgressDialog dialog; 
private Context con; 
boolean success = false; 

public ImpotDatabaseFileTask(Context con) { 
    this.con = con; 
    dialog = new ProgressDialog(con); 
    this.dialog.setMessage("Importing database..."); 
    execute(null); 
} 

@Override 
protected Boolean doInBackground(String... params) { 
    try { 
     OutputStream myOutput; 
     File destination = new File(Environment.getDataDirectory() 
       + "//data//<package name>//databases//database_name.db"); 

     // Set the folder on the SDcard 
     File dbFile = new File(Environment.getExternalStorageDirectory(), 
       "//<custom folder>//<database_name>.db"); 
     if (dbFile.exists()) { 
      copyFile(dbFile, destination); 
      success = true; 
     } 

    } catch (FileNotFoundException e) { 
     // Toast.makeText(Settings.this, 
     // "Restore unsuccessful! File not found! Directory does not exist?", 
     // Toast.LENGTH_LONG).show(); 

     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     Toast.makeText(con, "Restore unsuccessful!", Toast.LENGTH_SHORT) 
       .show(); 

     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return null; 
} 

void copyFile(File src, File dst) throws IOException { 
    FileChannel inChannel = new FileInputStream(src).getChannel(); 
    FileChannel outChannel = new FileOutputStream(dst).getChannel(); 
    try { 
     inChannel.transferTo(0, inChannel.size(), outChannel); 
    } finally { 
     if (inChannel != null) 
      inChannel.close(); 
     if (outChannel != null) 
      outChannel.close(); 
    } 
} 

@Override 
protected void onPostExecute(Boolean result) { 
    if (this.dialog.isShowing()) { 
     this.dialog.dismiss(); 
    } 
    if (success) { 
     Toast.makeText(con, "Restore successful!", Toast.LENGTH_SHORT) 
       .show(); 
    } else { 
     Toast.makeText(con, "Restore failed", Toast.LENGTH_SHORT).show(); 
    } 
    super.onPostExecute(result); 
} 

}

Các vấn đề liên quan