1

I have an app where I navigated with buttons and activites. Now I have rewritten it using a sliding menu and fragments.

Everything works so far but my class for displaying the database entries gives me a d`oh.

I can´t seem to find the error. Maybe someone else does :-)

Activity Code:

import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class anzeigen extends AppCompatActivity {

    private static final String TAG = anlegen.class.getSimpleName();
    private static final String FILENAME = TAG + ".kdf";
    private List valueList = new ArrayList<String>();
    final VorgangDataSource dataSource = new VorgangDataSource(this);


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

        Log.d(TAG,"Die Datenquelle wird geöffnet!");
        dataSource.open();

        final List<vorgangsdaten> vorgangsdatenList = dataSource.getAllVorgangsDaten();

        final ArrayAdapter<vorgangsdaten> VorgangArrayAdapter = new ArrayAdapter<>(
                this,
                R.layout.mylistlayout,
                vorgangsdatenList
        );


        final ListView lv = (ListView)findViewById(R.id.listView);
        lv.setAdapter(VorgangArrayAdapter);
        lv.setItemsCanFocus(false);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, final int position, final long id) {
                String s_id = String.valueOf(id);
                Log.d(s_id,"id_in_onitem");

                String p_id = String.valueOf(position);
                Log.d(p_id,"position_on_item");

                final AlertDialog delete = new AlertDialog.Builder(anzeigen.this).create();
                delete.setTitle(getResources().getString(R.string.advice));
                delete.setMessage(getResources().getString(R.string.delete2dialog));
                delete.setIcon(R.drawable.warning);
                delete.setButton(DialogInterface.BUTTON_POSITIVE, getResources().getString(R.string.ok), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        vorgangsdatenList.remove(position);
                        dataSource.deleteRow(id);
                        VorgangArrayAdapter.notifyDataSetChanged();
                        Toast.makeText(anzeigen.this,getResources().getString(R.string.eventdeleted),Toast.LENGTH_SHORT).show();
                    }
                });
                delete.setButton(DialogInterface.BUTTON_NEGATIVE, getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        delete.closeOptionsMenu();
                    }
                });

                delete.show();

                /*vorgangsdatenList.remove(position);
                dataSource.deleteRow(id);
                VorgangArrayAdapter.notifyDataSetChanged();
                Toast.makeText(anzeigen.this,getResources().getString(R.string.eventdeleted),Toast.LENGTH_SHORT).show(); */
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        dataSource.close();
    }
}

Fragment Code:

import android.content.Context;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;


public class frag_anzeigen extends Fragment {

    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;


    private static final String TAG = frag_anlegen.class.getSimpleName();
    private static final String FILENAME = TAG + ".kdf";
    private List valueList = new ArrayList <String>();
    final VorgangDataSource dataSource = new VorgangDataSource(getActivity());


    public frag_anzeigen() {
        // Required empty public constructor
    }

    public static frag_anzeigen newInstance(String param1, String param2) {
        frag_anzeigen fragment = new frag_anzeigen();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        final View anzeigen = inflater.inflate(R.layout.frag_anzeigen,container,false);

        Log.d(TAG,"Die Datenquelle wird geöffnet!");
        dataSource.open();

        final List<vorgangsdaten> vorgangsdatenList = dataSource.getAllVorgangsDaten();

        final ArrayAdapter<vorgangsdaten> VorgangArrayAdapter = new ArrayAdapter< >(getActivity(),R.layout.mylistlayout,vorgangsdatenList);


        final ListView lv = (ListView)anzeigen.findViewById(R.id.listView);
        lv.setAdapter(VorgangArrayAdapter);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, final int position, final long id) {
                String s_id = String.valueOf(id);
                Log.d(s_id,"id_in_onitem");

                String p_id = String.valueOf(position);
                Log.d(p_id,"position_on_item");

                final AlertDialog delete = new AlertDialog.Builder(getActivity()).create();
                delete.setTitle(getResources().getString(R.string.advice));
                delete.setMessage(getResources().getString(R.string.delete2dialog));
                delete.setIcon(R.drawable.warning);
                delete.setButton(DialogInterface.BUTTON_POSITIVE, getResources().getString(R.string.ok), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        vorgangsdatenList.remove(position);
                        dataSource.deleteRow(id);
                        VorgangArrayAdapter.notifyDataSetChanged();
                        Toast.makeText(getActivity(), getResources().getString(R.string.eventdeleted), Toast.LENGTH_SHORT).show();
                    }
                });
                delete.setButton(DialogInterface.BUTTON_NEGATIVE, getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        delete.closeOptionsMenu();
                    }
                });

                delete.show();
            }
        });
        return anzeigen;
    }

    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;

    }


    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        dataSource.close();
    }
}

ERROR-Message

E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                Process: com.example..., PID: 14818
                                                                                java.lang.NullPointerException
                                                                                    at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
                                                                                    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
                                                                                    at com.example...VorgangDataSource.open(VorgangDataSource.java:146)
                                                                                    at com.example...frag_anzeigen.onCreateView(frag_anzeigen.java:86)
                                                                                    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
                                                                                    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
                                                                                    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
                                                                                    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
                                                                                    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
                                                                                    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
                                                                                    at android.os.Handler.handleCallback(Handler.java:733)
                                                                                    at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                    at android.os.Looper.loop(Looper.java:146)
                                                                                    at android.app.ActivityThread.main(ActivityThread.java:5679)
                                                                                    at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                    at java.lang.reflect.Method.invoke(Method.java:515)
                                                                                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
                                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
                                                                                    at dalvik.system.NativeStart.main(Native Method)
Patrick260284
  • 89
  • 1
  • 11

1 Answers1

1

First of all, this question has been answered before (Android Database Locked), but anyways ...

In the Activity, you have

Log.d(TAG,"Die Datenquelle wird geöffnet!");
dataSource.open();

and you don't close it until onDestroy is called. Then, in the Fragment, you are trying to open the database again. There are 2 solutions to this:

  1. Use the Singleton pattern and check if it is already open before trying to open it. Using Singleton design pattern for SQLiteDatabase

OR

  1. Close the dataSource as soon as you don't need it anymore.

I will give you a quick guide on how to use the singleton pattern for your project.

In your class that extends SQLiteOpenHelper, do the following:

public class ClassName extends SQLiteOpenHelper {
    private static ClassName sInstance;

    public static synchronized ClassName getInstance() {
        if (sInstance == null) {
            sInstance = new DBOpenHelper(MyApplication.getAppContext());
        }
        return sInstance;
    }
}

And in the VorgangDataSource class:

private SQLiteDatabase database;
private ClassName dbHelper;

public VorgangDataSource open(boolean readOnly) throws SQLException {
    dbHelper = ClassName.getInstance(); //Class name of the above class
    if (readOnly)
        database = dbHelper.getReadableDatabase();
    else
        database = dbHelper.getWritableDatabase();
    return this;
}

This is the code for MyApplication.java:

public class MyApplication extends Application {
    private static MyApplication INSTANCE;

    @Override
    public void onCreate() {
        super.onCreate();
        INSTANCE = this;
    }

    public static MyApplication getINSTANCE(){
        return INSTANCE;
    }

    public static Context getAppContext() {
        return INSTANCE.getApplicationContext();
    }
}

Don't forget to add the android:name=".MyApplication" attribute to your <application> in AndroidManifest.xml. For example:

<application
        android:name=".MyApplication"
        ...>
        <activity ...

Now, it should be much easier for you to manage the database. Use the isOpen() method to see if it is already open. Hope this helps.

Community
  • 1
  • 1
Aftab Safdar
  • 653
  • 5
  • 19
  • I added what you suggested and additionally changed the following in my vorgangDataSource: `dbHelper = new VorgangDbHelper(context);` ----> `dbHelper = VorgangDbHelper.getInstance();` now it works. Thx a lot :-) – Patrick260284 Jun 07 '16 at 14:57