SQLite вставка возврат -1.после удаления папки, содержащей базу данных - PullRequest
0 голосов
/ 23 февраля 2019

После программного удаления папки, содержащей базу данных, когда в следующий раз вызывается запрос вставки, он возвращает -1. Я думаю, что решение снова создает базу данных, вызывая конструктор базы данных. Но я не знаю, как это сделать внутри фрагмента.

Базовый класс данных:

public class SQliteHelperClass  extends SQLiteOpenHelper {
    public static final String Dabase_name= "UserRecord.db";
    public static final String Table_name= "RTable";
    public static final String col_0= "Id";
    public static final String col_1= "KM";
    public static final String col_2= "MDATE";
    public static final String col_3= "MTIME";
    public static final String col_4= "MDIFFER";


    public SQliteHelperClass(Context context) {
        super(context, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                + File.separator+"MyCarData"
                + File.separator +  Dabase_name, null, 1);

    }

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE "+ Table_name +"(Id INTEGER PRIMARY KEY AUTOINCREMENT, KM INTEGER, MDATE TEXT, MTIME TEXT , MDIFFER INTEGER) ");

}

public boolean insertData(KmDataModel kmDataModel) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put(col_0,kmDataModel.getId());
    contentValues.put(col_1,kmDataModel.getKm());
    contentValues.put(col_2,kmDataModel.getDate());
    contentValues.put(col_3,kmDataModel.getTime());
    contentValues.put(col_4,kmDataModel.getDffKm());
    long result =db.insert(Table_name,null,contentValues);
    if(result == -1){
        return false;
    }else{
        return true;
    }
}

}

Метод удаления, который вызывает удаление Содержит определенную папку:

public void DeleteDataFolder(){
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
        + File.separator+"MyCarData"
        + File.separator);
if (dir.isDirectory())
{
    String[] children = dir.list();
    for (int i = 0; i < children.length; i++)
    {

        Log.e("File_List",children[i]);
        new File(dir, children[i]).delete();
    }
}
}

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

1 Ответ

0 голосов
/ 23 февраля 2019

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

Поэтому обновите существующий экземпляр, например, myInstanceOfDBHelper = new SQliteHelperClass(context)

  • , где контекстдолжен быть действительным контекстом

Если вы этого не сделаете, вы получите что-то вроде следующего в журнале: -

2019-02-23 16:15:32.049 31038-31038/abc.so54838140sqlitealtfilelocation D/DBINSERT: Attempt # 1 at inserting into DB
2019-02-23 16:15:32.070 31038-31038/abc.so54838140sqlitealtfilelocation E/File_List: UserRecord.db
2019-02-23 16:15:32.070 31038-31038/abc.so54838140sqlitealtfilelocation E/File_List: UserRecord.db-wal
2019-02-23 16:15:32.071 31038-31038/abc.so54838140sqlitealtfilelocation E/File_List: UserRecord.db-shm
2019-02-23 16:15:32.071 31038-31038/abc.so54838140sqlitealtfilelocation D/DBINSERT: Attempt # 2 at inserting into DB
2019-02-23 16:15:32.074 31038-31038/abc.so54838140sqlitealtfilelocation E/SQLiteDatabase: Error inserting MDIFFER=30 KM=100 Id=1 MTIME=10:30 MDATE=2019-01-01
    android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: RTable.Id (code 1555 SQLITE_CONSTRAINT_PRIMARYKEY)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:796)
        at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
        at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
        at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1564)
        at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1433)
        at abc.so54838140sqlitealtfilelocation.SQliteHelperClass.insertData(SQliteHelperClass.java:48)
        at abc.so54838140sqlitealtfilelocation.MainActivity.onCreate(MainActivity.java:30)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Вам может быть интересно, как вы получаете дубликат после удаления, возможно, старое соединение разрешает доступ к кэшированным данным

Следующий код был использован для вышеупомянутого: -

  • ваш SQliteHelperClass (слегка изменен для вывода попытки вставки #)
  • приблизительное значение вашего KmDataModel класса и
  • вызывающее действие (легче кодировать)

Код действия: -

public class MainActivity extends AppCompatActivity {

    SQliteHelperClass mDBHlpr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(Build.VERSION.SDK_INT >= 23) {
            ExternalStoragePermissions.verifyStoragePermissions(this);
        }

        mDBHlpr = new SQliteHelperClass(this); //<<<<<<<<<< original instantiation
        KmDataModel k = new KmDataModel();
        k.setId(1);
        k.setKm(100);
        k.setDate("2019-01-01");
        k.setTime("10:30");
        k.setDffKm(30);
        mDBHlpr.insertData(k,1);
        mDBHlpr.DeleteDataFolder();
        // If not commeneted out line below will re-instantiate the DB helper
        //mDBHlpr = new SQliteHelperClass(this); //<<<<<<<<<< COMMENTED OUT TO FAIL
        mDBHlpr.insertData(k,2);
    }
}
  • с закомментированной строкой, а не закомментированной вышеупомянутой работой.= так что все, что вам нужно сделать, это применить вышеупомянутое в вашем фрагменте, что потребует получения подходящего контекста.Если у вас возникли трудности с получением контекста, тогда может помочь Использование контекста во фрагменте .

При повторном создании журнала после запуска: -

2019-02-23 16:19:39.179 31176-31176/abc.so54838140sqlitealtfilelocation D/DBINSERT: Attempt # 1 at inserting into DB
2019-02-23 16:19:39.200 31176-31176/abc.so54838140sqlitealtfilelocation E/File_List: UserRecord.db
2019-02-23 16:19:39.200 31176-31176/abc.so54838140sqlitealtfilelocation E/File_List: UserRecord.db-wal
2019-02-23 16:19:39.200 31176-31176/abc.so54838140sqlitealtfilelocation E/File_List: UserRecord.db-shm
2019-02-23 16:19:39.202 31176-31176/abc.so54838140sqlitealtfilelocation D/DBINSERT: Attempt # 2 at inserting into DB
2019-02-23 16:19:39.239 31176-31176/abc.so54838140sqlitealtfilelocation D/OpenGLRenderer: Skia GL Pipeline
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...