База данных не копируется должным образом в OnePlus Two

Я создаю приложение для Android и использую в нем базу данных sqlite. для этого я поместил файл sqlite в папку ресурсов проекта, и я копирую этот файл на телефон во время моего первого запуска приложения, используя приведенный ниже код.

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

но я получаю эти ошибки.

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

но эта таблица существует в файле активов. поэтому я получил файл базы данных с телефона, используя этот метод.

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) {

    }
}

и я обнаружил, что в извлеченном файле базы данных нет таблицы.

Примечание. Эта проблема возникает только в OnePlus Two и нормально работает в Nexus 4, Htc 820, Moto E, Galxy S3 и Galaxy Quottro.


person Jignesh Ansodariya    schedule 21.09.2015    source источник
comment
void exportDB. Сделайте это логическим и добавьте код, если currentDB не существует. Этот код будет/не может работать.   -  person greenapps    schedule 21.09.2015
comment
Несколько раз я находил ту же проблему.   -  person M D    schedule 21.09.2015
comment
Я экспериментирую с проблемами и приложением, которое я разрабатываю в своем OP2, и это сводит меня с ума.   -  person Frildoren    schedule 07.10.2015
comment
вы нашли какое-то решение этой проблемы?   -  person varun bhardwaj    schedule 08.10.2015
comment
Нет :/ все еще пытаюсь понять, что не так   -  person Frildoren    schedule 08.10.2015
comment
Столкнулся с пользователем моего приложения с похожей проблемой. statement aborts at 15: [SELECT locale FROM android_metadata UNION SELECT NULL ORDER BY locale DESC LIMIT 1] 10-13 14:20:35.633 E/SQLiteDatabase(15040): Failed to open database '/data/data/myapp/databases/app.db'. 10-13 14:20:35.633 E/SQLiteDatabase(15040): android.database.sqlite.SQLiteException: Failed to change locale for db '/data/data/myapp/databases/app.db' to 'de_DE'.   -  person David    schedule 13.10.2015
comment
я тоже до сих пор мучаюсь с этой проблемой   -  person Jignesh Ansodariya    schedule 14.10.2015
comment
теперь у меня всего 4 пользователя, у которых не удается изменить локаль в sqlite. Все пользователи используют oneplustwo. На всех остальных 99,9% устройств работает. Последнее обновление Oxygen ничего не изменило.   -  person David    schedule 18.10.2015
comment
Я также сталкиваюсь с той же проблемой с OxygenOS на устройствах OnePlus 2. Вы нашли какое-нибудь решение для этого?   -  person Mitesh Sharma    schedule 24.10.2015
comment
Я создал ветку oneplus, пожалуйста, прокомментируйте здесь: forums.oneplus.net/threads/   -  person Calvin    schedule 26.10.2015
comment
У вас есть определенные таблицы Android, такие как sqlite_sequence и android_metadata? Я столкнулся с аналогичной проблемой stackoverflow.com/questions/9322899/, и ошибка исчезла, когда я заново создал базу данных со всеми специальными таблицами.   -  person forcelain    schedule 26.10.2015
comment
какие-либо обновления по этому поводу? Я также сталкиваюсь с проблемами sqlite с sqlite-asset-helper на устройствах oneplus...   -  person swalkner    schedule 01.12.2015
comment
@JigneshAnsodariya: оба метода copyDataBase и exportDB выполняются правильно без каких-либо исключений?   -  person ρяσѕρєя K    schedule 07.12.2015
comment
@swalkner, пожалуйста, посмотри мой ответ на это   -  person Jignesh Ansodariya    schedule 14.12.2015
comment
@ρяσѕρєя K да, все правильно   -  person Jignesh Ansodariya    schedule 14.12.2015


Ответы (3)


Путь к базе данных может быть разным на разных устройствах. Вам нужно использовать Context.getDatabasePath(String), чтобы получить путь к базе данных.

e.g.

File backupDB = context.getDatabasePath(backupDBPath);
person Ugur Ozmen    schedule 11.12.2015
comment
Я предполагаю, что если это правильно, то эта строка в sqlite-asset-helper также неверна: github.com/jgilfelt/android-sqlite-asset-helper/blob/master/ — правильно? - person swalkner; 11.12.2015
comment
ИМО, это все же лучше, чем полностью жестко закодированная версия. По крайней мере, он будет вести себя правильно, когда приложение будет перемещено на SD-карту. В любом случае, я думаю, что нет необходимости пытаться принять путь, пока система уже предоставляет его. - person Ugur Ozmen; 11.12.2015
comment
Я не понимаю вашего комментария, извините; Я имею в виду: если вы правы в том, что нужно использовать getDatabasePath(), то это должно быть по умолчанию и в sqlite-asset-helper, верно? - person swalkner; 11.12.2015
comment
ИМО, было бы лучше использовать Context.getDatabasePath(). Но это не значит, что context.getApplicationInfo().dataDir + "/databases" неправильно. - person Ugur Ozmen; 11.12.2015
comment
IMO, Android должен решить, где размещать базы данных, а не устройство, если только поставщики не изменят коды Android и не создадут свой собственный. - person frogatto; 13.12.2015

После долгих проб и поисков я вынужден был предположить, что должна быть ошибка в производстве OP2, так как на всех других устройствах он работает нормально.

и я изменил свой подход к созданию базы данных с помощью запроса, а не копирования файла базы данных из активов. как код ниже

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

}

и это сработало для меня

Спасибо!

person Jignesh Ansodariya    schedule 14.12.2015

Я нашел решение для этого, я использовал функцию ниже:

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

Согласно этому сообщению нам нужно вызвать close(), и вы также можете отправить базу данных на два устройства Oneplus.

person Jaiprakash Soni    schedule 10.02.2016
comment
Спасибо, чувак, ты спас мой день! - person Loïc; 23.03.2016