2

Я провел много тестов на эмуляторе Android, работающем в версии 4.4. На моем приложении я создаю базу данных SQLite с одной таблицы с помощью SQLiteOpenHelper:SQLiteOpenHelper: метод onCreate() не вызван на физическое устройство

package com.findwords.modeles; 

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

import com.findwords.MainActivity; 
import com.findwords.controleurs.MenuController; 

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

/** 
* Created by louk on 02/01/14. 
*/ 
public class DictionaryDbHelper extends SQLiteOpenHelper{ 

    // declare constants fields 
    private static final String DB_PATH = "/data/data/com.findwords/databases/"; 
    private static final String DB_NAME = "dictionary_db"; 
    private static final int DB_VERSION = 1; 

    // declared constant SQL Expression 
    private static final String DB_CREATE = 
      "CREATE TABLE dictionary (" + 
        "_id integer PRIMARY KEY AUTOINCREMENT, " + 
        "word text NOT NULL, " + 
        "definition text NOT NULL, " + 
        "length integer NOT NULL " + 
        ");"; 

    private static final String DB_DESTROY = 
      "DROP TABLE IF EXISTS dictionnary"; 

    /* 
    * constructor 
    */ 
    public DictionaryDbHelper(Context context) { 
     super(context, DB_NAME, null, DB_VERSION); 
    } 

    /** 
    * Creates a empty database on the system and rewrites it with your own database. 
    * */ 
    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) { 

       throw new Error("Error copying database"); 

      } 
     } 

    } 
    /** 
    * Check if the database already exist to avoid re-copying the file each time you open the application. 
    * @return true if it exists, false if it doesn't 
    */ 
    private boolean checkDataBase(){ 

     SQLiteDatabase checkDB = null; 

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

    /** 
    * Copies your database from your local assets-folder to the just created empty database in the 
    * system folder, from where it can be accessed and handled. 
    * This is done by transfering bytestream. 
    * */ 
    private void copyDataBase() throws IOException{ 

     //Open your local db as the input stream 
     InputStream myInput = MenuController.getInstance().getMainActivity().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(); 

    } 

    /* 
    * (non-Javadoc) 
    * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase) 
    */ 
    @Override 
    public void onCreate(SQLiteDatabase db) { 
     db.execSQL(DB_CREATE); 

     try { 
      createDataBase(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    /* 
    * (non-Javadoc) 
    * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int) 
    */ 
    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     db.execSQL(DB_DESTROY); 
     onCreate(db); 
    } 
} 

Кроме того, я написал переходник с открытым способом:

/* 
* open database connection 
*/ 
public DictionaryDbAdapter open() throws SQLException { 
    mDbHelper = new DictionaryDbHelper(mContext); 
    mDb = mDbHelper.getWritableDatabase(); 
    return this; 
} 

Это хорошо работает на эмуляторе так в OnCreate () метод класса SQLiteOpenHelper вызывается и создает базу данных, но не вызывается на моем телефоне (Google Nexus 5).

Мой телефон не подключен, поэтому я не могу получить доступ к папке /data/data/com.myapp/databases.

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

Заранее благодарим всех, кто мог мне помочь.

+3

удалите приложение и установите его снова, он будет называться –

ответ

5

Позвольте мне попытаться объяснить вам некоторые вещи.

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

1) База данных. Это может быть, например, в случае программы начальной настройки. В этом случае само приложение должно создать базу данных и все таблицы в ней. И, кроме того, он уже работает с недавно созданной базой данных.

2) База данных существует, но ее версия устарела. Возможно, это обновление. Например, новой версии программы нужны дополнительные поля в старых таблицах или новых таблицах. В этом случае приложение должно обновлять существующие таблицы и при необходимости создавать новые.

3) База данных и ее фактическая версия. В этом случае приложение успешно подключается к базе данных и работает.

Как вы знаете, фраза «приложение должна» означать фразу «разработчик должен», то есть это наша задача. Чтобы справиться с описанными выше ситуациями, нам нужно создать класс, который наследует SQLiteOpenHelper. Назовите его DBHelper. Этот класс предоставит нам методы для создания или обновления базы данных в случае их отсутствия или устаревания.

onCreate - это метод, который будет вызываться, если база данных, к которой мы хотим подключиться - не существует (это ваш случай)

+0

Благодарим за объяснение. Я думал, что приложение было удалено перед запуском приложения на Android-студии, но это не так. Я только что удалил приложение на телефоне, и он правильно создал базу данных при следующем запуске. – Chewbye

5

Метод onCreate вызывается только в первый раз - когда база данных фактически создана. Поэтому, если вы удалите свое приложение и затем его снова установите - он будет вызван, но если вы установите поверх существующей копии onCreate, не будет вызываться (поскольку БД уже существует)

1

Как сказал @Asahi, база данных только создается, только если вы переустановите приложение. Но так как вы сказали, что Мой телефон не внедрен, поэтому я не могу получить доступ к папке /data/data/com.myapp/databases, я хочу указать, что вы можете подключить свой мобильный телефон к компьютеру, установите правильный USB-драйверы и используйте DDMS, чтобы просмотреть файловую структуру вашего мобильного телефона.Там вы можете увидеть базу данных вашего приложения вместе с Shared Preferences и другими файлами.

PS: - Чтобы увидеть все папки реального устройства на DDMS вам нужно доступ к корневой. Если ваше устройство не внедрено и вы не хотите его root, тогда вы можете установить устройство на эмулятор, который показывает все папки в DDMS.

+0

Спасибо за ваш ответ, но я до сих пор не могу получить доступ к папке с данными из ddms. Когда я нажимаю «данные», он ничего не делает в ddms. И используя adb У меня есть ошибка при доступе к этой папке: opendir failed, Permission denied – Chewbye

+1

@Chewbye Я забыл упомянуть, что для этого требуется ** root access **. –

+1

Я нашел решение, используя эту команду в adb: run-as com.yourapp – Chewbye

Смежные вопросы