Search code examples
javaandroidxmlsqlitecursor

App Crashes When Using Cursor To Read Data From SQLITE Database - Android


I'm trying to display data from a database into a ListView using SimpleCursorProvider, but when i run my app in crashes instantly. After hours of editing i found that the problem is from the cursor in the getAllData() method. Even though, i couldn't fix the code!!

So can you look at my code and tell me what's wrong with it. Is it possible that the problem is that the database is empty, or is it the way I'm populating the ListView.

Here's My Code:

package com.xtreem.gpstracker;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class GPSDatabase {
    private DbHelper dbHelper;
    private static final String TAG = "GPSDatabase";
    public final static String DBNAME="gpstracker.db";
    public final static int DBVERSION=1;
    private SQLiteDatabase db;
    public static final String TABLE_NAME="location";
    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_DATE = "date";
    public static final String COLUMN_TIME = "time";
    public static final String COLUMN_LAT = "latitude";
    public static final String COLUMN_LON = "longitude";
    public static final String COLUMN_ALT = "altitude";
    public static final String COLUMN_SPEED = "speed";
    public static final String COLUMN_DIR = "direction";
    public static final String COLUMN_ACC = "accuracy";
    public static final String[] ALL_COLUMNS = new String[]{COLUMN_ID,COLUMN_DATE,COLUMN_TIME,COLUMN_LAT,COLUMN_LON,COLUMN_ALT,COLUMN_SPEED,COLUMN_DIR,COLUMN_ACC};
    public final static String CREATERDB="create table "
              + TABLE_NAME + "(" + COLUMN_ID
              + " integer primary key autoincrement, "
              + COLUMN_DATE + " text not null, " 
              + COLUMN_TIME + " text not null, "
              + COLUMN_LAT + " text not null, "
              + COLUMN_LON + " text not null, "
              + COLUMN_ALT + " text not null, "
              + COLUMN_SPEED + " text not null, "
              + COLUMN_DIR + " text not null, "
              + COLUMN_ACC + " text not null);";
    private final Context context;

    //const
    public GPSDatabase(Context ctx){
        this.context = ctx;
        dbHelper=new DbHelper(context);
    }   

    public long insertRows(String column2, String column3, String column4, String column5, String column6, String column7, String column8, String column9){
        ContentValues value=new ContentValues();
        value.put(COLUMN_DATE, column2);
        value.put(COLUMN_TIME, column3);
        value.put(COLUMN_LAT, column4);
        value.put(COLUMN_LON, column5);
        value.put(COLUMN_ALT, column6);
        value.put(COLUMN_SPEED, column7);
        value.put(COLUMN_DIR, column8);
        value.put(COLUMN_ACC, column9);
        return db.insert(TABLE_NAME,null,value);
    }
    public Cursor getAllRows(){
        Cursor c =db.query(TABLE_NAME,ALL_COLUMNS, null,null, null, null, null); /*COLUMN_ID+" DESC"*/
        if (c != null) {
            c.moveToFirst();
        }
        return c;
    }
    public GPSDatabase open() {
        db = dbHelper.getWritableDatabase();
        return this;
    }
    public void close(){
        dbHelper.close();
        //return true;
    }





    public static class DbHelper extends SQLiteOpenHelper{
        public DbHelper(Context context){
            super(context, DBNAME, null, DBVERSION);
        }
        @Override
        public void onCreate(SQLiteDatabase _db) {
            // TODO Auto-generated method stub
            _db.execSQL(CREATERDB);
        }
        @Override
        public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {
            // TODO Auto-generated method stub

            Log.w(TAG, "Upgrading application's database from version " + oldVersion
                    + " to " + newVersion + ", which will destroy all old data!");

            // Destroy old database:
            _db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);

            // Recreate new database:
            onCreate(_db);
        }
    }
}

MainActivity

package com.xtreem.gpstracker;


import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;

public class MainActivity extends Activity {

    GPSDatabase myDb;

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

        startService(new Intent(getBaseContext(), gpsLogger.class));
        openDB();
        populateListViewFromDB();

    }



    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.start_menu_option: 
            startService(new Intent(getBaseContext(), gpsLogger.class));
            return true;
        case R.id.stop_menu_option:
            stopService(new Intent(getBaseContext(), gpsLogger.class));
            return true;
        case R.id.quit_menu_option:
            Toast.makeText(this, "quit", Toast.LENGTH_SHORT).show();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private void openDB() {
        myDb = new GPSDatabase(this);
        myDb.open();
    }
    private void closeDB() {
        myDb.close();
    }

    protected void onDestroy() {
        super.onDestroy();  
        closeDB();
    }

    private void populateListViewFromDB() {
        GPSDatabase DB = new GPSDatabase(this); 
        Cursor cursor = DB.getAllRows();

        startManagingCursor(cursor);

        String[] fromFieldNames = new String[]
                {GPSDatabase.COLUMN_LAT}; //I'm using only one column for tesing
        int[] toViewIDs = new int[]
                {R.id.latTextView};

        SimpleCursorAdapter myCursorAdapter = new SimpleCursorAdapter(
                this,                       
                R.layout.item_layout,       
                cursor,                     
                fromFieldNames,             
                toViewIDs                   
                );


        ListView myList = (ListView) findViewById(R.id.list);
        myList.setAdapter(myCursorAdapter);
    }

}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" >

    </ListView>

</RelativeLayout>

item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<TextView
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_toRightOf="@+id/latTextView"
    android:text=", "
    android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
    android:id="@+id/longTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_toRightOf="@+id/textView2"
    android:text="Large Text"
    android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
    android:id="@+id/textView5"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/latTextView"
    android:layout_toRightOf="@+id/dateTextView"
    android:text=", "
    android:textColor="#878787" />

<TextView
    android:id="@+id/timeTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBaseline="@+id/textView5"
    android:layout_alignBottom="@+id/textView5"
    android:layout_toRightOf="@+id/textView5"
    android:text="Medium Text"
    android:textColor="#878787" />

<TextView
    android:id="@+id/latTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="16dp"
    android:text="Large Text"
    android:textAppearance="?android:attr/textAppearanceLarge" />

<TextView
    android:id="@+id/dateTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBaseline="@+id/textView5"
    android:layout_alignBottom="@+id/textView5"
    android:layout_alignLeft="@+id/textView"
    android:text="Medium Text"
    android:textColor="#878787" />

</RelativeLayout>

LogCat

12-01 00:03:19.824: E/AndroidRuntime(830): FATAL EXCEPTION: main
12-01 00:03:19.824: E/AndroidRuntime(830): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xtreem.gpstracker/com.xtreem.gpstracker.MainActivity}: java.lang.NullPointerException
12-01 00:03:19.824: E/AndroidRuntime(830):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1955)
12-01 00:03:19.824: E/AndroidRuntime(830):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
12-01 00:03:19.824: E/AndroidRuntime(830):  at android.app.ActivityThread.access$600(ActivityThread.java:122)
12-01 00:03:19.824: E/AndroidRuntime(830):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146)
12-01 00:03:19.824: E/AndroidRuntime(830):  at android.os.Handler.dispatchMessage(Handler.java:99)
12-01 00:03:19.824: E/AndroidRuntime(830):  at android.os.Looper.loop(Looper.java:137)
12-01 00:03:19.824: E/AndroidRuntime(830):  at android.app.ActivityThread.main(ActivityThread.java:4340)
12-01 00:03:19.824: E/AndroidRuntime(830):  at java.lang.reflect.Method.invokeNative(Native Method)
12-01 00:03:19.824: E/AndroidRuntime(830):  at java.lang.reflect.Method.invoke(Method.java:511)
12-01 00:03:19.824: E/AndroidRuntime(830):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
12-01 00:03:19.824: E/AndroidRuntime(830):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
12-01 00:03:19.824: E/AndroidRuntime(830):  at dalvik.system.NativeStart.main(Native Method)
12-01 00:03:19.824: E/AndroidRuntime(830): Caused by: java.lang.NullPointerException
12-01 00:03:19.824: E/AndroidRuntime(830):  at com.xtreem.gpstracker.GPSDatabase.getAllRows(GPSDatabase.java:59)
12-01 00:03:19.824: E/AndroidRuntime(830):  at com.xtreem.gpstracker.MainActivity.populateListViewFromDB(MainActivity.java:118)
12-01 00:03:19.824: E/AndroidRuntime(830):  at com.xtreem.gpstracker.MainActivity.onCreate(MainActivity.java:34)
12-01 00:03:19.824: E/AndroidRuntime(830):  at android.app.Activity.performCreate(Activity.java:4465)
12-01 00:03:19.824: E/AndroidRuntime(830):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
12-01 00:03:19.824: E/AndroidRuntime(830):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1919)
12-01 00:03:19.824: E/AndroidRuntime(830):  ... 11 more

Thank You


Solution

  • Try change populateListViewFromDB() to this:

    private void populateListViewFromDB() {
    
        Cursor cursor = myDb.getAllRows();
    
        startManagingCursor(cursor);
    
        String[] fromFieldNames = new String[]
                {GPSDatabase.COLUMN_LAT}; //I'm using only one column for tesing
        int[] toViewIDs = new int[]
                {R.id.latTextView};
    
        SimpleCursorAdapter myCursorAdapter = new SimpleCursorAdapter(
                this,                       
                R.layout.item_layout,       
                cursor,                     
                fromFieldNames,             
                toViewIDs                   
                );
    
    
        ListView myList = (ListView) findViewById(R.id.list);
        myList.setAdapter(myCursorAdapter);
    }