-1

I have created an app witch uses sqlite database to display data. i can read the data and display it in two activities but i cant store or delete the data . i want to save and remove the bookmarks in another table.

i have searched a lot on internet , watched a lot of videos but nothing helps.

Here is my DatabaseHelper.

  public class DatabaseHelper extends SQLiteOpenHelper {

private  static final String DB_NAME = "mydic.db";
private static final int DB_VERSION = 1;
private String DB_PATH = null;
private  static final String TABLE_DICTIONARY = "dictionary1";
public   static final String TABLE_BOOKMARK= "bookmark";
private static final String COLUMN_ID = "id";
public static final String COL_WORD = "word";
public static final String COL_DEFINITION = "definition";
private Context mcontext;
private SQLiteDatabase mDatabase;

public DatabaseHelper( Context context) {
    super(context, DB_NAME, null, DB_VERSION);
    this.mcontext = context;
    this.DB_PATH = "/data/data/" + context.getPackageName() + "/" + "databases/";
}
public void createDataBase() throws IOException {

    boolean dbExist = checkDataBase();
    if (!dbExist) {
        this.getReadableDatabase();
        try {
            mcontext.deleteDatabase(DB_NAME);
            copyDataBase();
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }
}
public boolean checkDataBase() {
    SQLiteDatabase checkDB = null;
    try {
        String myPath = DB_PATH + DB_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    } catch (SQLiteException e) {
        e.printStackTrace();
    }
    if (checkDB != null) {
        checkDB.close();
    }
    return checkDB != null ? true : false;
}

private void copyDataBase() throws IOException {

    InputStream myInput = mcontext.getAssets().open(DB_NAME);
    String outFileName = DB_PATH + DB_NAME;
    OutputStream myOutput = new FileOutputStream(outFileName);
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer)) > 0) {
        myOutput.write(buffer, 0, length);
    }
    myOutput.flush();
    myOutput.close();
    myInput.close();
}
public void openDatabase() throws SQLException {
    String myPath = DB_PATH + DB_NAME;
    mDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}

@Override
public synchronized void close() {
    if (mDatabase != null)
        mDatabase.close();
    super.close();
}
public Cursor getListWord(String wordSearch) {

    String query = "SELECT * FROM " + TABLE_DICTIONARY + " Where word Like ? " ;
    Cursor cursor = null;
    try {
        openDatabase();
        String[] args = {"%"+wordSearch+"%"};
         cursor = mDatabase.rawQuery(query , args);
    }catch (Exception e){
        e.printStackTrace();
    }
    return cursor;
}
public boolean addBookmark(String title, String subtitle) {

    // Gets the data repository in write mode
    SQLiteDatabase db = getWritableDatabase();

    // Create a new map of values, where column names are the keys
    ContentValues values = new ContentValues();
    values.put(DatabaseHelper.COL_WORD, title);
    values.put(DatabaseHelper.COL_DEFINITION, subtitle);

    // Insert the new row, returning the primary key value of the new row
    db.insert(DatabaseHelper.TABLE_BOOKMARK, null, values);

    return true;
}
public void removeBookmark(String title, String subtitle) {
    mDatabase = this.getReadableDatabase();
    mDatabase.execSQL("delete from favourites where  word Like ? ");
    mDatabase.close();
}
public Cursor getBookmarkWord(String wordSearch) {
    String query = "SELECT * FROM favourites Where word Like ? " ;
    Cursor cursor = null;
    try {
        openDatabase();
        String[] args = {"%"+wordSearch+"%"};
        cursor = mDatabase.rawQuery(query , args);
    }catch (Exception e){
        e.printStackTrace();
    }
    return cursor;
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE favourites ( id INTEGER PRIMARY KEY AUTOINCREMENT,word,definition)" );
}

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

    if (newVersion > oldVersion) {
        try {
            copyDataBase();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

}

Here is my adapter

  word = itemView.findViewById(R.id.wordText);
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                int position = getAdapterPosition();
                cursor.moveToPosition(position);

                Intent intent = new Intent(context, DetailActivity.class);
                intent.putExtra("WORD",cursor.getString(1));
                intent.putExtra("DEFINITION",cursor.getString(2));
                context.startActivity(intent);

and here is my detail activity.

public class DetailActivity extends AppCompatActivity {

private TextToSpeech tts;
DatabaseHelper mDBHelper;
Context context;
DictionaryAdapter dictionaryAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_detail);

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

      final String word = getIntent().getStringExtra("WORD");
      final String definition = getIntent().getStringExtra("DEFINITION");


     final TextView tvWordDetail = findViewById(R.id.tvWordDetail);
    WebView wordDefinition = findViewById(R.id.tvWordDefinition);
     final ImageButton btnBookmark = findViewById(R.id.btnBookmark);
    ImageButton textToSpeech = findViewById(R.id.textToSpeech);

    Cursor bookmarkWord = mDBHelper.getBookmarkWord("");
    int isMark = bookmarkWord == null? 0 : 1;
    btnBookmark.setTag(isMark);

    int icon = bookmarkWord == null? R.drawable.ic_bookmark_border:R.drawable.ic_bookmark_fill;
    btnBookmark.setImageResource(icon);
    tvWordDetail.setText(Html.fromHtml(word));
    wordDefinition.loadDataWithBaseURL(null,definition,"text/html", "utf-8",null);


    btnBookmark.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            int i = (int) btnBookmark.getTag();
            if (i == 0) {
                btnBookmark.setBackgroundResource(R.drawable.ic_bookmark_fill);
                btnBookmark.setTag(1);
                mDBHelper.addBookmark(word,definition);
            } else if (i == 1){
                btnBookmark.setBackgroundResource(R.drawable.ic_bookmark_border);
                btnBookmark.setTag(0);
                mDBHelper.removeBookmark(word,definition);
            }
        }
    });


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();
    if (id== android.R.id.home){
        onBackPressed();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

}

Here is my log

 2019-02-19 15:08:08.727 11561-11561/com.elytelabs.testnav E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.elytelabs.testnav, PID: 11561
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.elytelabs.testnav/com.elytelabs.testnav.DetailActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor com.elytelabs.testnav.database.DatabaseHelper.getBookmarkWord(java.lang.String)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
    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)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor com.elytelabs.testnav.database.DatabaseHelper.getBookmarkWord(java.lang.String)' on a null object reference
    at com.elytelabs.testnav.DetailActivity.onCreate(DetailActivity.java:54)
    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) 
Faisal Khan
  • 353
  • 1
  • 16
  • 2
    Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Selvin Feb 19 '19 at 09:44
  • Post your Detail Activity code , null on 53rd line – hemen Feb 19 '19 at 09:50

1 Answers1

2

The likely cause is that you haven't instantiated mDBHelper, rater that you only declared it.

Typically you'd have DatabaseHelper mDBhelper;, this declares the variable.

Typically in the onCreate method of the activity you'd then have

mDBHelper = new DatabaseHelper(this); 

to instantiate (construct) mDBHelper.

So youe code in DetailActivity should be :-

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
mDBHelper = new DatabaseHelper(this); //<<<<<<<<<< ADDED THIS LINE

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
MikeT
  • 51,415
  • 16
  • 49
  • 68
  • it helped with the crash but i'm still unable to save the data , it only changes the icon color of every word – Faisal Khan Feb 19 '19 at 10:06
  • @FaisalKhan that may well be because you are trying to check if the cursor is null. It would only ever be null if you trapped an exception (which you don't want to trap). **It is NOT checking if no data has been extracted.** In such a case a valid instantiated Cursor is returned whose count is 0, which can be checked using the Cursor **getCount()** method. – MikeT Feb 19 '19 at 10:18