Java 如何在我的Android应用程序中启动emulator时填充SQLite数据库。

Java 如何在我的Android应用程序中启动emulator时填充SQLite数据库。,java,android,sqlite,Java,Android,Sqlite,我有一个包含4个字段的excel文件,我想在首次使用emulator时使用该文件填充数据库。以前,我习惯于将数据库文件直接存储在手机上,但如果在创建时填充这些项目会更容易。当emulator启动时,如何读取excel文件或文本文件并填充数据库?假设电子表格如下:- 已使用文件资源管理器将其作为名为Book1.CSV的CSV文件保存到应用程序的资产文件夹中(如果需要,创建名为资产的文件夹),例如 i、 e.D:\Android\u Applications\LoadDataFromExcel\

我有一个包含4个字段的excel文件,我想在首次使用emulator时使用该文件填充数据库。以前,我习惯于将数据库文件直接存储在手机上,但如果在创建时填充这些项目会更容易。当emulator启动时,如何读取excel文件或文本文件并填充数据库?

假设电子表格如下:-

已使用文件资源管理器将其作为名为Book1.CSV的CSV文件保存到应用程序的资产文件夹中(如果需要,创建名为资产的文件夹),例如

i、 e.
D:\Android\u Applications\LoadDataFromExcel\app\src\main\assets

以及一个DatabaseHelper(即SQLiteOpenHelper的子类),如下所示:-

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;
    public static final String MYDATA_TBL = "mydata";
    public static final String MYDATA_ID_COL = "_id";
    public static final String MYDATA_NAME_COL = "_name";
    public static final String MYDATA_AMOUNT_COL = "_amount";
    public static final String MYDATA_DATE_COL = "_date";
    public static final String MYDATA_DESCRIPTION_COL = "_description";

    private static final String TBLCREATESQL =
            "CREATE TABLE " + MYDATA_TBL +
                    "(" +
                    MYDATA_ID_COL + " INTEGER PRIMARY KEY," +
                    MYDATA_NAME_COL + " TEXT," +
                    MYDATA_AMOUNT_COL + " INTEGER," +
                    MYDATA_DATE_COL + " TEXT, " +
                    MYDATA_DESCRIPTION_COL + " TEXT" +
                    ")";

    private SQLiteDatabase mDB;


    public DatabaseHelper(Context ccontext) {
        super(ccontext, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

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

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

    }

    public long insertRow(String name, int amount, String date, String description) {
        ContentValues cv = new ContentValues();
        cv.put(MYDATA_NAME_COL,name);
        cv.put(MYDATA_AMOUNT_COL,amount);
        cv.put(MYDATA_DATE_COL,date);
        cv.put(MYDATA_DESCRIPTION_COL,description);
        return mDB.insert(MYDATA_TBL,null,cv);
    }
}
然后你就可以得到一些基于:-

public class MainActivity extends AppCompatActivity {

    DatabaseHelper dbh;

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

        dbh = new DatabaseHelper(this);
        loadExternalData();
    }


    private void loadExternalData() {

        InputStream importdata;
        BufferedReader br;
        String line;
        String[] splitdata;
        int linecount = 0;

        final String tag = "loadExternalData";
        try {
            importdata = this.getAssets().open("Book1.csv");
        } catch (IOException e) {
            Log.d(tag,"Error opening asset file");
            return;
        }
        br = new BufferedReader(new InputStreamReader(importdata));
        try {
            while ( (line = br.readLine()) != null) {
                // Skip column headings
                if (linecount++ > 0) {
                     splitdata = line.split(",");
                     dbh.insertRow(
                             splitdata[0],
                             new Integer(splitdata[1]),
                             splitdata[2],
                             splitdata[3]
                     );
                }
            }
        } catch (IOException e) {
            Log.d(tag,"IO Error reading data at line " + (linecount + 1));
            e.printStackTrace();
        }
    }
}
注意!这是一个非常基本的、原则上的演示,例如,它不能处理数据中的逗号,每次运行它时都会创建一组新的行

结果数据库:-

编辑-更改为仅添加一次行(但允许添加新数据) 1) 将新方法添加到DatabaseHelper类:-

public boolean ifRowExists(String name, int amount, String date, String description) {
    Cursor csr = mDB.query(MYDATA_TBL,null,
            MYDATA_NAME_COL + "=? AND " +
                    MYDATA_AMOUNT_COL + "=? AND " + 
                    MYDATA_DATE_COL + "=? AND " + 
                    MYDATA_DESCRIPTION_COL + "=?",
            new String[]{name,Integer.toString(amount), date, description},
            null,null,null
    );
    boolean rv = csr.getCount() > 0;
    csr.close();
    return rv;
}
2) 修改调用类中的
loadExternalData
方法,以检查插入的行是否存在:-

private void loadExternalData() {

    InputStream importdata;
    BufferedReader br;
    String line;
    String[] splitdata;
    int linecount = 0;

    final String tag = "loadExternalData";
    try {
        importdata = this.getAssets().open("Book1.csv");
    } catch (IOException e) {
        Log.d(tag,"Error opening asset file");
        return;
    }
    br = new BufferedReader(new InputStreamReader(importdata));
    try {
        while ( (line = br.readLine()) != null) {
            // Skip column headings
            if (linecount++ > 0) {
                splitdata = line.split(",");
                if (!dbh.ifRowExists(splitdata[0], new Integer(splitdata[1]), splitdata[2], splitdata[3])) {
                    dbh.insertRow(
                            splitdata[0],
                            new Integer(splitdata[1]),
                            splitdata[2],
                            splitdata[3]
                    );
                }
            }
        }
    } catch (IOException e) {
        Log.d(tag,"IO Error reading data at line " + (linecount + 1));
        e.printStackTrace();
    }
}

我建议您在开发机器上使用数据创建一个SQLite数据库,然后使用
sqliteAssetThelper
将该数据库与应用程序打包:我能够正确存储数据,但它会像您所说的那样添加一组新的行。关于如何只调用该方法一次有什么建议吗?@RichardAguilar我已经用一个解决方案编辑了答案,该解决方案检查数据是否已经存在。但是,这将在每次运行应用程序时读取数据。它的优点是可以引入新数据,但缺点是它会频繁地读取数据并不必要地检查行的存在。就个人而言,我会考虑一个替代方案,比如用一行表来表示数据已经被读取。