0

all day long I've been searching the root cause of the following error. I there anyone who can help me with this issue?

Using: Android Studio 4.1.1 / Java

My goal: I have a sqlite database created with DB Browser (recipe.db3) in my assets folder: Assets > recipe.db3. This database shall be copied to app database folder in the SplashActivity.java if the database does not exist yet (basically once in app lifetime). Once created, I want to access this database and show its content (only title) in the RecycleViewer in RecipesFragment.java.

My issue: I receive a NullPointerException when I try to show my RecyclerView - basically when I run this.getReadableDatabase() in my DataBaseHelper.java. It seems like I cannot even access my database. Even if I do not copy my baking.db3 file to /data/data/com.android.baking/databases/ but create the database programmatically I receive the same error.

Does anyone have a clue where the error lies?

Thanks! Kornelius

Logcat output

I/database: TABLE_RECIPES created
    TABLE_US created
...............
D/EGL_emulation: eglMakeCurrent: 0xb31050c0: ver 2 0 (tinfo 0xb3103660)
I/art: Do partial code cache collection, code=55KB, data=59KB
    After code cache collection, code=54KB, data=58KB
    Increasing code cache capacity to 256KB
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.android.baking, PID: 9878
    androidx.fragment.app.Fragment$InstantiationException: Unable to instantiate fragment com.android.baking.ui.recipes.RecipesFragment: calling Fragment constructor caused an exception
        at androidx.fragment.app.Fragment.instantiate(Fragment.java:566)
        at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
        at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
        at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
        at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
        at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
        at androidx.navigation.NavController.navigate(NavController.java:1059)
        at androidx.navigation.NavController.navigate(NavController.java:944)
        at androidx.navigation.NavController.navigate(NavController.java:877)
        at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97)
        at androidx.navigation.ui.NavigationUI$5.onNavigationItemSelected(NavigationUI.java:531)
        at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243)
        at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
        at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
        at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
        at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:127)
        at android.view.View.performClick(View.java:5610)
        at android.view.View$PerformClick.run(View.java:22265)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
        at androidx.fragment.app.Fragment.instantiate(Fragment.java:548)
        at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57) 
        at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390) 
        at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132) 
        at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162) 
        at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58) 
        at androidx.navigation.NavController.navigate(NavController.java:1059) 
        at androidx.navigation.NavController.navigate(NavController.java:944) 
        at androidx.navigation.NavController.navigate(NavController.java:877) 
        at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97) 
        at androidx.navigation.ui.NavigationUI$5.onNavigationItemSelected(NavigationUI.java:531) 
        at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243) 
        at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834) 
        at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158) 
        at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985) 
        at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:127) 
        at android.view.View.performClick(View.java:5610) 
        at android.view.View$PerformClick.run(View.java:22265) 
        at android.os.Handler.handleCallback(Handler.java:751) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6077) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase android.content.Context.openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase$CursorFactory, android.database.DatabaseErrorHandler)' on a null object reference
        at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223)
        at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
        at com.android.baking.DataBaseHelper.<init>(DataBaseHelper.java:64)
        at com.android.baking.ui.recipes.RecipesFragment.<init>(RecipesFragment.java:37)
        at java.lang.reflect.Constructor.newInstance0(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:430) 
        at androidx.fragment.app.Fragment.instantiate(Fragment.java:548) 
        at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57) 
        at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390) 
        at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132) 
        at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162) 
        at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58) 
        at androidx.navigation.NavController.navigate(NavController.java:1059) 
        at androidx.navigation.NavController.navigate(NavController.java:944) 
        at androidx.navigation.NavController.navigate(NavController.java:877) 
        at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97) 
        at androidx.navigation.ui.NavigationUI$5.onNavigationItemSelected(NavigationUI.java:531) 
        at com.google.android.material.bottomnavigation.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:243) 
        at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834) 
        at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158) 
        at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985) 
        at com.google.android.material.bottomnavigation.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:127) 
        at android.view.View.performClick(View.java:5610) 
        at android.view.View$PerformClick.run(View.java:22265) 
        at android.os.Handler.handleCallback(Handler.java:751) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6077) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 

DataBaseHelper.java:

package com.android.baking;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.ContactsContract;
import android.util.Log;

import com.android.baking.ui.adapter.RecipeAdapter;
import com.android.baking.ui.models.RecipeModel;
import com.android.baking.ui.models.UserSpecificModel;

import java.util.ArrayList;

import androidx.annotation.Nullable;


public class DataBaseHelper extends SQLiteOpenHelper {

    private static final int DB_VERSION = 1;
    public static String DB_NAME = "recipe.db3";

    //ITEMS IN TABLE: RECIPES
    public static final String TABLE_RECIPES = "RECIPES";
    public static final String RECIPE_RECIPE = "RECIPE";
    public static final String RECIPE_ID = "ID";
    public static final String RECIPE_SOURCE = "SOURCE";
    public static final String RECIPE_TITLE = "TITLE";
    ...............
    public static final String RECIPE_ZERO_DOUGH = "ZERO_DOUGH";
    public static final String RECIPE_IMAGE_1 = "IMAGE_1";
    public static final String RECIPE_IMAGE_2 = "IMAGE_2";

    //ITEMS IN TABLE: USER_SPECIFIC
    public static final String TABLE_USER_SPECIFIC = "USER_SPECIFIC";
    public static final String US_ID = "ID";
    public static final String US_URL = "URL";
    public static final String US_NOTES = "NOTES";
    public static final String US_IS_FAVORITE = "IS_FAVORITE";

    public Context context;

    public DataBaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        this.context = context;
        this.getReadableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        //CREATE RECIPES TABLE
        String createTableStatement = "CREATE TABLE " + TABLE_RECIPES + " (" + RECIPE_ID + " INTEGER PRIMARY KEY " +
                "AUTOINCREMENT, " + RECIPE_SOURCE + " TEXT, " + RECIPE_TITLE + " TEXT, " + RECIPE_URL + " TEXT, " + RECIPE_DATE + " TEXT, " + RECIPE_IMGLINKS + " TEXT, " + RECIPE_DESCRIPTION + " TEXT, " + RECIPE_INGREDIENTS + " TEXT, " + RECIPE_RECIPE + " TEXT, " + RECIPE_PREPTIME_TOTAL + " TEXT, " + RECIPE_PREPTIME_BAKETIME + " TEXT, " + RECIPE_MATCOST + " TEXT, " + RECIPE_OVERNIGHT + " INTEGER, " + RECIPE_FULL_GRAIN + " INTEGER, " + RECIPE_NO_KNEAD + " INTEGER, " + RECIPE_PASTRY_TYPE + " TEXT, " + RECIPE_DOUGHS + " TEXT, " + RECIPE_TASTE + " TEXT, " + RECIPE_PORES + " TEXT, " + RECIPE_FORM + " TEXT, " + RECIPE_ZERO_DOUGH + " TEXT, " + RECIPE_IMAGE_1 + " BLOB, " + RECIPE_IMAGE_2 + " BLOB)";
        db.execSQL(createTableStatement);
        Log.i("database", "TABLE_RECIPES created");

        //CREATE USER_SPECIFIC TABLE
        createTableStatement =
                "CREATE TABLE " + TABLE_USER_SPECIFIC + " (" + US_ID + " INTEGER PRIMARY KEY, " + US_URL + " TEXT, " +
                          US_NOTES + " TEXT, " + US_IS_FAVORITE + " INTEGER)";
        db.execSQL(createTableStatement);
        Log.i("database", "TABLE_US created");


    }

    public boolean addOneUS(UserSpecificModel userSpecificModel){
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();

        cv.put(US_URL, userSpecificModel.getUrl());
        cv.put(US_NOTES, userSpecificModel.getNote());
        cv.put(US_IS_FAVORITE, userSpecificModel.getIs_favorite());

        long insert = db.insert(TABLE_USER_SPECIFIC,null, cv);
        if (insert == -1) {
            return false;
        } else {
            return true;
        }
    }


    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
        /*SQLiteDatabase db = this.getWritableDatabase();
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_RECIPES);
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_USER_SPECIFIC);
        onCreate(db);*/
    }


    public ArrayList<RecipeModel> getAllRecipes() {
        ArrayList<RecipeModel> results = new ArrayList<>();
        SQLiteDatabase db = this.getReadableDatabase();

        //String where = " where " + ContentDBManager.KEY_id + " = ? ";
        Cursor cursor =
                db.rawQuery("SELECT * FROM " + TABLE_RECIPES + " ORDER BY " + RECIPE_TITLE + " DESC", null);


        if (cursor != null && cursor.getCount() > 0) {
            try {
                if (cursor.moveToFirst()) {
                    do {
                        RecipeModel recipeModel = new RecipeModel();
                        recipeModel.setId(cursor.getInt(0));
                        recipeModel.setSource(cursor.getString(1));
                        recipeModel.setUrl(cursor.getString(2));
                        recipeModel.setDate(cursor.getString(3));
                        recipeModel.setImglinks(cursor.getString(4));
                        recipeModel.setDescription(cursor.getString(5));
                        recipeModel.setIngredients(cursor.getString(6));
                        recipeModel.setRecipe(cursor.getString(7));
                        recipeModel.setPreptime_total(cursor.getString(8));
                        recipeModel.setPreptime_baketime(cursor.getString(9));
                        recipeModel.setMatcost(cursor.getString(10));
                        recipeModel.setOvernight(cursor.getInt(11));
                        recipeModel.setFull_grain(cursor.getInt(12));
                        recipeModel.setNo_knead(cursor.getInt(13));
                        recipeModel.setPastry_type(cursor.getString(14));
                        recipeModel.setDoughs(cursor.getString(15));
                        recipeModel.setTaste(cursor.getString(16));
                        recipeModel.setPores(cursor.getString(17));
                        recipeModel.setForm(cursor.getString(18));
                        recipeModel.setZero_dough(cursor.getString(19));

                        results.add(recipeModel);
                    } while (cursor.moveToNext());
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                if (!cursor.isClosed()){
                    cursor.close();
                }
            }
        } else {
            if (cursor != null) {
                Log.i("Database",
                        "Cursor is Null!");
                cursor.close();
            }
        }       // to free up memory of cursor
        return results;
    }

}

SplashActivity.java:

package com.android.baking.ui;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.SQLException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.Menu;

import com.android.baking.DataBaseHelper;
import com.android.baking.MainActivity;
import com.android.baking.R;

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

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class SplashActivity extends MainActivity {
    private static boolean splashLoaded = false;
    private static String DB_PATH;
    private static String DB_NAME;
    private static final int SPLASH_TIME = 1000;

    public final int WRITE_PERMISSION_REQUEST_CODE = 1110;
    private final String[] NEEDED_PERMISSIONS = new String[]{
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
    };


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!checkPermissions(NEEDED_PERMISSIONS)){
            ActivityCompat.requestPermissions(SplashActivity.this, NEEDED_PERMISSIONS, WRITE_PERMISSION_REQUEST_CODE);
        }else {
            BackgroundTask backgroundTask = new BackgroundTask();
            backgroundTask.execute();
        }




        if (!splashLoaded) {
            setContentView(R.layout.splash_screen);

            int secondsDelayed = 3;
            new Handler().postDelayed(new Runnable() {
                public void run() {
                    startActivity(new Intent(SplashActivity.this, MainActivity.class));
                    finish();
                }
            }, secondsDelayed * SPLASH_TIME);
            splashLoaded = true;

        } else {
            Intent goToMainActivity = new Intent(SplashActivity.this, MainActivity.class);
            goToMainActivity.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
            startActivity(goToMainActivity);
            finish();
        }



        //copy database from assets to database folder if it does not exist
        //see also: https://stackoverflow.com/questions/18805874/copy-database-from-assets-to-databases-folder/18806587

        if (!doesDatabaseExist(this, DataBaseHelper.DB_NAME)){

        DB_PATH = getApplicationInfo().dataDir + "/databases/";
        DB_NAME = DataBaseHelper.DB_NAME;
        copyDataBase(DB_NAME, DB_PATH);
    }
 

    }

    private static boolean doesDatabaseExist(Context context, String dbName) {
        File dbFile = context.getDatabasePath(dbName);
        return dbFile.exists();
    }


    private void copyDataBase(String dbName, String dbPath)
    {
        Log.i("Database",
                "New database is being copied to device!");
        byte[] buffer = new byte[1024];
        OutputStream myOutput = null;
        int length;
        // Open your local db as the input stream
        InputStream myInput = null;

        try
        {
            myInput = getApplicationContext().getAssets().open(dbName);
            // transfer bytes from the inputfile to the
            // outputfile
            myOutput = new FileOutputStream(dbPath + dbName);
            while((length = myInput.read(buffer)) > 0)
            {
                myOutput.write(buffer, 0, length);
            }
            myOutput.close();
            myOutput.flush();
            myInput.close();
            Log.i("Database",
                    "New database has been copied to device!");

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


    }


    // to get FaceFeature and FaceIdFeature.
    private boolean checkPermissions(String[] neededPermissions) {
        if (neededPermissions == null || neededPermissions.length == 0) {
            return true;
        }
        boolean allGranted = true;
        for (String neededPermission : neededPermissions) {
            allGranted &= ContextCompat.checkSelfPermission(getApplicationContext(), neededPermission) == PackageManager.PERMISSION_GRANTED;
        }
        return allGranted;
    }


    private class BackgroundTask extends AsyncTask {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected Object doInBackground(Object[] objects) {
            try {
                Thread.sleep(SPLASH_TIME);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Object[] values) {
            super.onProgressUpdate(values);
        }

        @Override
        protected void onPostExecute(Object o) {
            super.onPostExecute(o);
            Intent intent = new Intent(SplashActivity.this, MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
            finish();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case WRITE_PERMISSION_REQUEST_CODE:
                if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    BackgroundTask backgroundTask = new BackgroundTask();
                    backgroundTask.execute();
                }
                break;
            default:
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == WRITE_PERMISSION_REQUEST_CODE && resultCode == RESULT_OK) {
            BackgroundTask backgroundTask = new BackgroundTask();
            backgroundTask.execute();
        }
    }

}

RecipeAdapter.java:

package com.android.baking.ui.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import com.android.baking.R;
import com.android.baking.ui.listeners.RecipeItemClickListener;
import com.android.baking.ui.models.RecipeModel;

import java.util.ArrayList;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

// Create the basic adapter extending from RecyclerView.Adapter
// Note that we specify the custom ViewHolder which gives us access to our views
// see: https://stackoverflow.com/questions/40584424/simple-android-recyclerview-example
public class RecipeAdapter extends
        RecyclerView.Adapter<RecipeAdapter.ViewHolder> {

    private Context recipeContext;
    private ArrayList<RecipeModel> recipeList = new ArrayList<>();
    private ArrayList<RecipeModel> recipeSearchList = new ArrayList<>();
    private RecipeItemClickListener recipeListener;

    public RecipeAdapter(Context context, ArrayList<RecipeModel> recipeContentList, RecipeItemClickListener listener) {
        this.recipeContext = context;
        this.recipeListener = listener;
        this.recipeList.addAll(recipeContentList);
        recipeSearchList.addAll(recipeList);
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(recipeContext).inflate(R.layout.item_recycler_view_recipes, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        final RecipeModel recipeModel = recipeList.get(position);
        holder.tv_title.setText(recipeModel.getTitle());
    }

    @Override
    public int getItemCount() {
        return recipeList.size();
    }

    // stores and recycles views as they are scrolled off screen
    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView tv_title;

        public ViewHolder(View itemView) {
            //ToDo: hier weitermachen
            super(itemView);
            tv_title = itemView.findViewById(R.id.item_title);
        }
    }

}

RecipeFragment.java:

package com.android.baking.ui.recipes;

import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.android.baking.DataBaseHelper;
import com.android.baking.MainActivity;
import com.android.baking.R;
import com.android.baking.ui.adapter.RecipeAdapter;
import com.android.baking.ui.listeners.RecipeItemClickListener;
import com.android.baking.ui.models.RecipeModel;

import java.util.ArrayList;

public class RecipesFragment extends Fragment {

    private RecipesViewModel recipesViewModel;
    private ArrayList<RecipeModel> recipeList = new ArrayList<>();
    private static RecipesFragment mInstance;
    DataBaseHelper dataBaseHelper = new DataBaseHelper(getContext());

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        recipesViewModel = new ViewModelProvider(this).get(RecipesViewModel.class);
        View root = inflater.inflate(R.layout.fragment_recipes, container, false);

        RecyclerView rec_recipes = root.findViewById(R.id.recipes_recycler_view);
        rec_recipes.setLayoutManager(new LinearLayoutManager(getContext()));
        recipeList = dataBaseHelper.getAllRecipes();
        RecipeAdapter recipeAdapter = new RecipeAdapter(getContext(), recipeList, new RecipeItemClickListener() {
            @Override
            public void OnItemClicked(RecipeModel recipeModel) {
                Toast.makeText(getContext(), "You clicked " + recipeModel.getTitle(), Toast.LENGTH_SHORT).show();
            }
        });

        rec_recipes.setAdapter(recipeAdapter);

        return root;
    }
}
Ko Wi
  • 13
  • 3

1 Answers1

0

In RecipieFragment.DataBaseHelper, calling getContext() here it may be returning you a null, hence the NPE. Try creating the DataBaseHelper in onCreateView() instead.

user3170251
  • 310
  • 1
  • 13
  • Thanks a lot! That actually worked to get rid of the error. But now, I still receive an empty cursor if I access the database. I printed the database path (db.getPath()) in logcat and it seems the app refers to a database located in /data/user/0/com.android.baking/databases/recipes.db3 and not in /data/data/com.android.baking/databases/recipes.db3. Why doesn't it use my coped database at all? In Device File Explorer I cannot even navigate to /data/user/ directory. – Ko Wi Feb 24 '21 at 05:53
  • to clarify, `doesDatabaseExist()` correctly returns false but the database file is being created elsewhere? – user3170251 Feb 24 '21 at 15:25