0

I want to ask about my SQLite database on Android Studio. I have a database and stored in this path: /data/data/com.example.ilhamakbar.yukmasakbygd/databases/.

When I opened it from Nox App Player, the database works and shows any tables and all data that I already inserted. However, when I build my APK and run it from my phone (Android 6.0.1 Marshmallow), it says that there were no data in my database.

For example when I clicked button View on TabActivityAdministrator.java, the database will be shown in Nox App player, but won't be shown in my mobile phone.

I already follow some instrunctions from these links below, but it seems doesn't work.

  1. Simple export and import of a SQLite database on Android
  2. Import and Use External Database in Android
  3. Reading sqlite file from asset folder
  4. Not empty LiteSQL DB at start
  5. Updating prepopulated database in Android
  6. Using your own SQLite database in Android applications

This is my DatabaseHelper.java

public class DatabaseHelper extends SQLiteOpenHelper {
    // DATABASE NAME
    public static String DATABASE_PATH = "/data/data/com.example.ilhamakbar.yukmasakbygd/databases/";
    public static final String DATABASE_NAME = "yukmasak.db";
    private final Context myContext;
    private SQLiteOpenHelper openHelper;
    private SQLiteDatabase myDatabase;

    int id = 0;
    Random random = new Random();

    //TABLE NAMES
    public static final String EXPERT_TABLE = "expertTable";
    public static final String INGREDIENTS_TABLE = "ingredientsTable";
    public static final String MENU_TABLE = "menuTable";

    // FOUR LINES BELOW ARE CODES FOR EXPERT TABLE'S COLUMNS NAME. SO PLEASE DON'T MESS IT UP
    public static final String COL_EXPERT_CODE = "expertCode";
    public static final String COL_EXPERT_NAME = "expertName";
    public static final String COL_EXPERT_WEIGHTING = "expertWeighting";

    // FOUR LINES BELOW ARE CODES FOR INGREDIENTS TABLE'S COLUMNS NAME. SO PLEASE DON'T MESS IT UP
    public static final String COL_INGREDIENTS_CODE = "ingredientsCode";
    public static final String COL_INGREDIENTS_CODEFK = "ingredientsCodeFK";
    public static final String COL_INGREDIENTS_NAME = "ingredientsName";
    public static final String COL_INGREDIENTS_QTY = "ingredientsQty";

    // FOUR LINES BELOW ARE CODES FOR MENU TABLE'S COLUMNS NAME. SO PLEASE DON'T MESS IT UP
    public static final String COL_MENU_CODE = "menuCode";
    public static final String COL_MENU_NAME = "menuName";
    public static final String COL_MENU_PICTURE = "menuPictures";

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, 1);
        this.myContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + EXPERT_TABLE + "(expertCode STRING PRIMARY KEY, expertName TEXT, expertWeighting FLOAT)");
        db.execSQL("CREATE TABLE " + INGREDIENTS_TABLE + "(ingridientsCode STRING PRIMARY KEY, ingridientsCodeFK STRING, ingredientsName TEXT, ingredientsQty FLOAT, FOREIGN KEY (ingridientsCodeFK) REFERENCES EXPERT_TABLE(expertCode))");
        db.execSQL("CREATE TABLE " + MENU_TABLE + "(menuCode STRING PRIMARY KEY, menuName TEXT, menuPictures BLOB)");
        createDB();
    }

    private void createDB(){
        boolean dbExist = dbExists();
        if(!dbExist){
            copyDatabase();
        }
        else if(dbExist){
            copyDatabase();
        }
    }

    private boolean dbExists(){
        SQLiteDatabase db = null;
        try{
            String dbPath = DATABASE_PATH + DATABASE_NAME;
            db = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
            db.setLocale(Locale.getDefault());
            db.setLockingEnabled(true);
            db.setVersion(1);
        }
        catch(SQLiteException e){
            Log.e("SQL Helper", "database not found");
        }
        if(db != null){
            db.close();
        }
        return db != null ? true : false;
    }

    // Additional codes and will be deleted if not working
    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");
            }
        }

        createDB();
    }

    private boolean checkDatabase(){
        SQLiteDatabase checkDB = null;

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

    public void openDB(){
        this.myDatabase = openHelper.getWritableDatabase();
    }

    public void closeDB(){
        if(myDatabase != null){
            this.myDatabase.close();
        }
    }

    private void copyDatabase(){
        InputStream iStream = null;
        OutputStream oStream = null;

        // Path to the just created empty db
        String outFileName = DATABASE_PATH + DATABASE_NAME;

        try{
            iStream = myContext.getAssets().open(DATABASE_NAME);        // Open your local db as the input stream
            oStream = new FileOutputStream(outFileName);                // Open the empty db as the output stream
            byte[] buffer = new byte[1024];                             // Transfer bytes from the inputfile to the outputfile
            int length;
            while ((length = iStream.read(buffer))>0){
                oStream.write(buffer, 0, length);
            }

            //Close the streams
            oStream.flush();
            oStream.close();
            iStream.close();
        }
        catch(IOException ioe){
            throw new Error("Problem copying database from resource file.");
        }
    }

    public void openDatabase() throws SQLException {
        //Open the database
        String myPath = DATABASE_PATH + DATABASE_NAME;
        myDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

    }

    @Override
    public synchronized void close() {
        if(myDatabase != null)
            myDatabase.close();

        super.close();

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // DROP OLDER TABLES IF EXISTED
        db.execSQL("DROP TABLE IF EXISTS " + EXPERT_TABLE);
        db.execSQL("DROP TABLE IF EXISTS " + INGREDIENTS_TABLE);
        db.execSQL("DROP TABLE IF EXISTS " + MENU_TABLE);

        onCreate(db);
    }

    public boolean insertExpertTable(String code, String name, String weighting){
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues contentValues = new ContentValues();
        contentValues.put(COL_EXPERT_CODE, code);
        contentValues.put(COL_EXPERT_NAME, name);
        contentValues.put(COL_EXPERT_WEIGHTING, weighting);

        long result = db.insert(EXPERT_TABLE, null, contentValues);
        if(result == -1)
            return false;
        else
            return true;
    }

    public boolean insertIngredientsTable(String code, String codefk, String name, String qty){
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues contentValues = new ContentValues();
        contentValues.put(COL_INGREDIENTS_CODE, code);
        contentValues.put(COL_INGREDIENTS_CODEFK, codefk);
        contentValues.put(COL_INGREDIENTS_NAME, name);
        contentValues.put(COL_INGREDIENTS_QTY, qty);

        long result = db.insert(INGREDIENTS_TABLE, null, contentValues);
        if(result == -1)
            return false;
        else
            return true;
    }

    public boolean insertMenuTable(String code, String name, byte[] picture){
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues contentValues = new ContentValues();
        contentValues.put(COL_MENU_CODE, code);
        contentValues.put(COL_MENU_NAME, name);
        contentValues.put("menuPictures", picture);

        long result = db.insert(MENU_TABLE, null, contentValues);
        if(result == -1) {
            return false;
        }
        else {
            return true;
        }
    }

    public Cursor getAllExpertData(){
        SQLiteDatabase db = this.getWritableDatabase();

        Cursor res = db.rawQuery("SELECT * FROM " + EXPERT_TABLE, null);
        return res;
    }

    public Cursor getAllIngredientsData(){
        SQLiteDatabase db = this.getWritableDatabase();

        Cursor res = db.rawQuery("SELECT * FROM " + INGREDIENTS_TABLE, null);
        return res;
    }

    public Cursor getAllMenuData(){
        SQLiteDatabase db = this.getWritableDatabase();

        Cursor res = db.rawQuery("SELECT * FROM " + MENU_TABLE, null);
        return res;
    }

    public List<String> getExpertTableData(){
        SQLiteDatabase db = this.getWritableDatabase();

        List<String> list = new ArrayList<>();
        Cursor cursor = db.rawQuery("SELECT * FROM " + EXPERT_TABLE, null);

        while (cursor.moveToNext()) {
            // WHICH COLUMN I WANT TO EXPORT
            list.add(cursor.getString(0)+" | " + cursor.getString(1)+" | " + cursor.getString(2)+"\n" );
        }

        cursor.close();
        return list;
    }

    public List<String> getIngridientsTableData(){
        SQLiteDatabase db = this.getWritableDatabase();

        List<String> list = new ArrayList<>();
        Cursor cursor = db.rawQuery("SELECT * FROM " + INGREDIENTS_TABLE, null);

        while (cursor.moveToNext()) {
            // WHICH COLUMN I WANT TO EXPORT
            list.add(cursor.getString(0)+" | " + cursor.getString(1)+" | " + cursor.getString(2)+"\n" );
        }

        cursor.close();
        return list;
    }

    public List<Object> getMenuTableData(){
        SQLiteDatabase db = this.getWritableDatabase();

        List<Object> list = new ArrayList<>();
        Cursor cursor = db.rawQuery("SELECT * FROM " + MENU_TABLE, null);

        while (cursor.moveToNext()) {
            // WHICH COLUMN I WANT TO EXPORT
            list.add(cursor.getString(0)+" | " + cursor.getString(1)+" | " + cursor.getBlob(2)+"\n" );
        }

        cursor.close();
        return list;
    }

    public boolean updateExpertData(String code, String name, String weighting, String change_code){
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues contentValues = new ContentValues();
        contentValues.put(COL_EXPERT_CODE, code);
        contentValues.put(COL_EXPERT_NAME, name);
        contentValues.put(COL_EXPERT_WEIGHTING, weighting);
        contentValues.put(COL_EXPERT_CODE, change_code);
        db.update(EXPERT_TABLE, contentValues, "expertCode=?",new String[] {change_code});
        return true;
    }

    public boolean updateIngredientsData(String code, String codefk, String name, String qty, String change_code){
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues contentValues = new ContentValues();
        contentValues.put(COL_INGREDIENTS_CODE, code);
        contentValues.put(COL_INGREDIENTS_CODEFK, codefk);
        contentValues.put(COL_INGREDIENTS_NAME, name);
        contentValues.put(COL_INGREDIENTS_QTY, qty);
        contentValues.put(COL_INGREDIENTS_CODE, change_code);
        db.update(INGREDIENTS_TABLE, contentValues, "ingridientsCode=?",new String[] {change_code});
        return true;
    }

//    public boolean updateMenuData(String code, String name, String picture, String change_code){
//        SQLiteDatabase db = this.getWritableDatabase();
//
//        ContentValues contentValues = new ContentValues();
//        contentValues.put(COL_MENU_CODE, code);
//        contentValues.put(COL_MENU_NAME, name);
//        contentValues.put(COL_MENU_PICTURE, picture);
//        contentValues.put(COL_MENU_CODE, change_code);
//        db.update(MENU_TABLE, contentValues, "menuCode=?",new String[] {change_code});
//        return true;
//    }

    public Integer deleteExpertData(String change_code){
        SQLiteDatabase db = this.getWritableDatabase();

        return db.delete(EXPERT_TABLE, "expertCode=?", new String[] {change_code});
    }

    public Integer deleteIngredientsData(String change_code){
        SQLiteDatabase db = this.getWritableDatabase();

        return db.delete(INGREDIENTS_TABLE, "ingridientsCode=?", new String[] {change_code});
    }

    public Integer deleteMenuData(String change_code){
        SQLiteDatabase db = this.getWritableDatabase();

        return db.delete(MENU_TABLE, "menuCode=?", new String[] {change_code});
    }
}

This is my TabActivityAdministrator.java

public class TabActivityAdministrator01 extends android.support.v4.app.Fragment {
    // THESE CODES BELOW UNTIL THE NEXT @OVERRIDE IS USED TO CALL THE DATABASEHELPER.JAVA
    DatabaseHelper myDb;
    private EditText editExpertWeightingCode,
                     editExpertWeightingName,
                     editExpertWeightingValue,
                     editExpertWeightingChangedCode;
    private Button buttonExpertAddData,
                   buttonExpertViewData,
                   buttonExpertUpdateData,
                   buttonExpertDeleteData;
    private ListView listViewExpertData;

    // TODO: Rename and change types and number of parameters
    public static TabActivityAdministrator01 newInstance(String param1, String param2) {
        TabActivityAdministrator01 fragment = new TabActivityAdministrator01();
        Bundle args = new Bundle();
        //args.putString(ARG_PARAM1, param1);
        //args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        myDb = new DatabaseHelper(getContext());
        View view = inflater.inflate(R.layout.fragment_tab_activity_administrator01,container,false);

        editExpertWeightingCode = (EditText)view.findViewById(R.id.edtWeightingCode_TabActivityAdministrator01);
        editExpertWeightingName = (EditText)view.findViewById(R.id.edtWeightingName_TabActivityAdministrator01);
        editExpertWeightingValue = (EditText)view.findViewById(R.id.edtWeightingValue_TabActivityAdministrator01);
        editExpertWeightingChangedCode = (EditText)view.findViewById(R.id.edtWeightingChangedCode_TabActivityAdministrator01);
        buttonExpertAddData = (Button)view.findViewById(R.id.btnExpertAddData_TabActivityAdministrator01);
        buttonExpertViewData = (Button)view.findViewById(R.id.btnExpertViewData_TabActivityAdministrator01);
        buttonExpertUpdateData = (Button)view.findViewById(R.id.btnExpertUpdateData_TabActivityAdministrator01);
        buttonExpertDeleteData = (Button)view.findViewById(R.id.btnExpertDeleteData_TabActivityAdministrator01);
        listViewExpertData = (ListView)view.findViewById(R.id.lvExpertViewData_TabActivityAdministrator01);

        AddExpertData();
        ViewExpertData();
        UpdateExpertData();
        DeleteExpertData();

        return view;
    }

    // THESE CODES BELOW FOR ADDING EXPERT DATAS TO MY DATABASE
    public void AddExpertData(){
        buttonExpertAddData.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        boolean isInserted = myDb.insertExpertTable(editExpertWeightingCode.getText().toString(),
                                                                    editExpertWeightingName.getText().toString(),
                                                                    editExpertWeightingValue.getText().toString() );

                        if(isInserted = true)
                            Toast.makeText(TabActivityAdministrator01.this.getActivity(), "Data Berhasil Dimasukkan", Toast.LENGTH_LONG).show();
                        else
                            Toast.makeText(TabActivityAdministrator01.this.getActivity(), "Data Gagal Dimasukkan", Toast.LENGTH_LONG).show();

                        editExpertWeightingCode.getText().clear();      // clear edit text for expertWeightingCode
                        editExpertWeightingName.getText().clear();      // clear edit text for expertWeightingName
                        editExpertWeightingValue.getText().clear();     // clear edit text for expertWeightingValue
                    }
                }
        );
    }

    /*
    // THESE CODES BELOW FOR VIEWING DATAS ON MY DATABASE WITH POP UP DATAS
    public void ViewExpertData(){
        buttonExpertViewData.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Cursor res = myDb.getAllExpertData();
                        if(res.getCount() == 0){
                            // IF NO DATA WAS FOUND, THIS MESSAGE BELOW WILL APPEAR
                            ShowMessage("Error", "Data Tidak Ditemukan");
                            return;
                        }

                        StringBuffer buffer = new StringBuffer();
                        while(res.moveToNext()){
                            buffer.append("CODE: " +res.getString(0)+"\n");
                            buffer.append("NAMA: " +res.getString(1)+"\n");
                            buffer.append("BOBOT: " +res.getString(2)+"\n\n");
                        }

                        // IF THE DATA WAS FOUND, THIS MESSAGE BELOW WILL APPEAR
                        ShowMessage("Data", buffer.toString());
                    }
                }
        );
    }
    */

    // THESE CODES BELOW FOR VIEWING DATAS ON MY DATABASE WITH POP UP DATAS     // will be deleted if unused
    public void ViewExpertData(){
        buttonExpertViewData.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Cursor res = myDb.getAllExpertData();
                        if(res.getCount() == 0){
                            // IF NO DATA WAS FOUND, THIS MESSAGE BELOW WILL APPEAR
                            ShowMessage("Error", "Data Tidak Ditemukan");
                            return;
                        }
                        while(res.moveToNext()){
                            myDb = new DatabaseHelper(getActivity());
                            List<String> yukmasak = myDb.getExpertTableData();
                            myDb.closeDB();
                            ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, yukmasak);
                            listViewExpertData.setAdapter(adapter);
                        }
                    }
                }
        );
    }

    public void ShowMessage(String title, String message){
        AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity());
        builder.setCancelable(true);
        builder.setTitle(title);
        builder.setMessage(message);
        builder.show();
    }

    // THESE CODES BELOW FOR UPDATING DATAS ON MY DATABASE
    public void UpdateExpertData(){
        buttonExpertUpdateData.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        boolean isUpdated = myDb.updateExpertData(editExpertWeightingCode.getText().toString(),
                                                                  editExpertWeightingName.getText().toString(),
                                                                  editExpertWeightingValue.getText().toString(),
                                                                  editExpertWeightingChangedCode.getText().toString());

                        if(isUpdated=true)
                            Toast.makeText(TabActivityAdministrator01.this.getActivity(), "Data Berhasil Diperbaharui", Toast.LENGTH_LONG).show();
                        else
                            Toast.makeText(TabActivityAdministrator01.this.getActivity(), "Data Gagal Diperbaharui", Toast.LENGTH_LONG).show();

                        editExpertWeightingCode.getText().clear();               // clear edit text for expertWeightingCode
                        editExpertWeightingName.getText().clear();               // clear edit text for expertWeightingName
                        editExpertWeightingValue.getText().clear();              // clear edit text for expertWeightingValue
                        editExpertWeightingChangedCode.getText().clear();        // clear edit text for expertWeightinChangedgCode
                    }
                }
        );
    }

    // THESE CODES BELOW FOR DELETING DATAS ON MY DATABASE
    public void DeleteExpertData(){
        buttonExpertDeleteData.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        Integer deletedRows = myDb.deleteExpertData(editExpertWeightingChangedCode.getText().toString());
                        if(deletedRows > 0)
                            Toast.makeText(TabActivityAdministrator01.this.getActivity(), "Data Berhasil Dihapus", Toast.LENGTH_LONG).show();
                        else
                            Toast.makeText(TabActivityAdministrator01.this.getActivity(), "Data Gagal Dihapus", Toast.LENGTH_LONG).show();

                        editExpertWeightingChangedCode.getText().clear();        // clear edit text for expertWeightinChangedgCode
                    }
                }
        );
    }
}
  • Are you getting any exception? Also don't use hardcoded paths like this "/data/data/com.example.ilhamakbar.yukmasakbygd/databases/". There is no guarantee that this folder will be available. Instead use `context.getDataDir()` or `context.getDatabathPath()` – Henry Nov 15 '17 at 09:23
  • There's no any exception shown – Ilham Akbar Nov 15 '17 at 09:27
  • Do you want to create an empty database, or ship an existing database with your app? Because this code tries to do both. – CL. Nov 15 '17 at 09:27
  • @CL: I want to ship an existing database with my app when i build an apk – Ilham Akbar Nov 15 '17 at 09:51
  • Then just use [SQLiteAssetHelper](http://jgilfelt.github.io/android-sqlite-asset-helper/). – CL. Nov 15 '17 at 09:54
  • I had a similar problem before in one of my apps. Did you try moving the `copyDatabase` method to somewhere like the `Application` class? I remember there was a file lock on the db file when `onCreate` was called. – Naveen Dissanayake Nov 15 '17 at 09:57
  • @CL: I will try first. Thank you for your help – Ilham Akbar Nov 15 '17 at 10:06
  • @Naveen Dissanayake: What do you mean by file lock? Actually when I build an APK and run it on my phone, the databases is not exist. But when I run it on a emulator like Nox App, the database is exist. – Ilham Akbar Nov 15 '17 at 10:08
  • I mean you cannot access the file when `onCreate` is called. I can't be sure why it would work on the emulator though. – Naveen Dissanayake Nov 15 '17 at 10:57
  • @CL: Why you marked my question as duplicated? I already stated that I followed the instruection from the link above and it doesn't work. You told me to open Ship an application with a database link? Do you open my link number 6? I already wrote it. – Ilham Akbar Nov 15 '17 at 17:09
  • Your code does not do the same thing as in that link. Neither does it use SQLiteAssetHelper. – CL. Nov 15 '17 at 17:48

0 Answers0