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
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);
}