2015-09-21 8 views
22

Sto creando un'applicazione Android e sto utilizzando database sqlite al suo interno. per questo ho inserito un file sqlite nella cartella delle risorse del progetto e sto copiando questo file sul telefono mentre eseguivo la prima esecuzione dell'applicazione utilizzando il codice seguente.Il database non viene copiato correttamente in OnePlus Two

private void copyDataBase() throws IOException { 
    new File(DB_PATH).mkdirs(); 
    InputStream myInput = appContext.getAssets().open(DB_NAME); 
    String outFileName = DB_PATH + DB_NAME; 
    OutputStream myOutput = new FileOutputStream(outFileName); 
    byte[] buffer = new byte[1024]; 
    int length; 

    while ((length = myInput.read(buffer)) > 0) { 
     myOutput.write(buffer, 0, length); 
    } 

    myOutput.flush(); 
    myOutput.close(); 
    myInput.close(); 
} 

ma sto ricevendo questi errori.

09-21 18:03:56.841: E/SQLiteLog(7850): (1) no such table: tbl_player 

ma questa tabella esiste nel file di risorse. così ho recuperato il file di database dal telefono usando questo metodo.

public static void exportDB(String databaseName, Context context) { 
    try { 
     File sd = Environment.getExternalStorageDirectory(); 
     File data = Environment.getDataDirectory(); 

     if (sd.canWrite()) { 
      String currentDBPath = "//data//" + context.getPackageName() 
        + "//databases//" + databaseName + ""; 
      String backupDBPath = "sensor_game.db"; 
      File currentDB = new File(data, currentDBPath); 
      File backupDB = new File(sd, backupDBPath); 

      if (currentDB.exists()) { 
       FileChannel src = new FileInputStream(currentDB) 
         .getChannel(); 
       FileChannel dst = new FileOutputStream(backupDB) 
         .getChannel(); 
       dst.transferFrom(src, 0, src.size()); 
       src.close(); 
       dst.close(); 
      } 
     } 

    } catch (Exception e) { 

    } 
} 

e ho trovato che non esiste alcuna tabella nel file di database recuperato.

Nota: Questo problema si verifica solo è in OnePlus Two e lavorare bene in Nexus 4, Htc 820, Moto E, Galxy S3 e Galaxy Quottro

+0

'void exportDB'. Crea quel valore booleano e aggiungi il codice nel caso in cui currentB non esista. Quel codice non può/può funzionare. – greenapps

+0

Alcune volte ho trovato lo stesso problema. –

+0

Sto sperimentando problemi e app che sto sviluppando nel mio OP2 e mi sta facendo impazzire – Frildoren

risposta

3

Dopo lunghe prove e ricerche che costretti ad assumere che ci dovrebbe essere un problema nella produzione OP2 come funziona bene in tutti gli altri dispositivi.

e ho modificato il mio approccio per creare database utilizzando la query anziché copiare il file di database dalle risorse. come il codice qui sotto

import java.io.File; 
import android.content.ContentValues; 
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 android.util.Log; 

public class MySQLiteHelper extends SQLiteOpenHelper implements DBConstants { 

private static MySQLiteHelper mInstance = null; 
private SQLiteDatabase myDataBase; 
private static String DB_PATH = ""; 

public MySQLiteHelper(Context context) { 
    super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    try { 
     if (checkDataBase()) 
      openDataBase(); 
     else 
      myDataBase = this.getReadableDatabase(); 
    } catch (Exception e) { 
    } 
} 

public static MySQLiteHelper instance(Context context) { 

    File outFile = context.getDatabasePath(DATABASE_NAME); 
    DB_PATH = outFile.getPath(); 

    if (mInstance == null) { 
     mInstance = new MySQLiteHelper(context); 
    } 

    return mInstance; 
} 

private void openDataBase() throws Exception { 
    try { 
     myDataBase = SQLiteDatabase.openDatabase(DB_PATH, null, 
       SQLiteDatabase.OPEN_READWRITE); 
    } catch (SQLException e) { 
     // TODO: handle exception 
    } 
} 

private boolean checkDataBase() { 
    SQLiteDatabase checkDB = null; 
    try { 
     checkDB = SQLiteDatabase.openDatabase(DB_PATH, null, 
       SQLiteDatabase.OPEN_READONLY); 

    } catch (SQLiteException e) { 
     /** database does't exist yet. */ 
    } catch (Exception e) { 
    } 
    if (checkDB != null) { 
     checkDB.close(); 
    } 
    return checkDB != null ? true : false; 
} 

@Override 
public void onCreate(SQLiteDatabase db) { 

    Log.v("log_tag", "onCreate"); 
    myDataBase = db; 

    // creating a sample table 
    String CREATE_DEVICE_TABLE = "CREATE TABLE " + DEVICE + " (" 
      + KEY_DEVICEID + " TEXT, " + KEY_OPERATOR + " TEXT, " 
      + KEY_DEVICENAME + " TEXT, " + KEY_DEVICETOTALMEMORY 
      + " INTEGER, " + KEY_SCREENWIDTH + " INTEGER, " 
      + KEY_SCREENHEIGHT + " INTEGER, " + KEY_OPERATINGSYSTEM 
      + " TEXT)"; 

    db.execSQL(CREATE_DEVICE_TABLE); 

    // other tables also can be created from here. 
} 

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
    db.execSQL("DROP TABLE IF EXISTS " + DEVICE); 

    // Create tables again (as per requirement) 
    this.onCreate(db); 
} 

public Cursor rawQuery(String qry) { 
    return myDataBase.rawQuery(qry, null); 
} 

public long insert(String tableName, ContentValues cv) { 
    return myDataBase.insert(tableName, null, cv); 
} 

public void insertWithOnConflict(String tableName, ContentValues cv, 
     int flag) { 
    myDataBase.insertWithOnConflict(tableName, null, cv, flag); 

} 

public long update(String tableName, ContentValues cv, String whereClose) { 
    return myDataBase.update(tableName, cv, whereClose, null); 

} 

public int deleteData(String table_name, String whereClause) { 
    return (int) myDataBase.delete(table_name, whereClause, null); 
} 

} 

e ha funzionato per me

Grazie!

5

Percorso database possono essere diverse a seconda dei dispositivi. Per ottenere il percorso del database è necessario utilizzare Context.getDatabasePath(String).

ad es.

File backupDB = context.getDatabasePath(backupDBPath); 
+1

Immagino se questo è corretto di questa riga in '' 'sqlite-asset-helper''' è sbagliato pure: https://github.com/ jgilfelt/android-sqlite-asset-helper/blob/master/library/src/main/java/com/readystatesoftware/sqliteasset/SQLiteAssetHelper.java # L109 - giusto? – swalkner

+0

IMO è ancora meglio della versione completamente codificata. Almeno si comporterà correttamente quando l'app viene spostata su sdcard. Ad ogni modo, penso che non sia necessario cercare di assumere un percorso, mentre il sistema lo sta già fornendo. –

+0

Non ho ricevuto il tuo commento, mi dispiace; Voglio dire: se hai ragione che '' 'deve essere usato getDatabasePath()' '', che dovrebbe essere il predefinito in '' 'sqlite-asset-helper''', giusto? – swalkner

2

Ho trovato soluzione per questo, ho usato qui di seguito la funzione:

public void createDb() { 
     boolean dbExist = checkDataBase(); 

     if (dbExist) { 
      // do nothing - database already exist 
     } else { 
      // call close() for properly copy database file 
      this.getReadableDatabase().close(); 
      try { 
       copyDataBase(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       throw new Error("Error copying database"); 
      } 
     } 
    } 

Come per this post abbiamo bisogno di chiamare close() e si può spingere database per OnePlus due dispositivi anche.

+0

Grazie amico, mi hai salvato la giornata! –

Problemi correlati