2013-11-30 2 views
-1

Я пытаюсь отобразить данные из базы данных в ListView с использованием SimpleCursorProvider, но когда я запускаю свое приложение в аварийных ситуациях мгновенно. После нескольких часов редактирования я обнаружил, что проблема связана с курсором в методе getAllData(). Хотя я не смог исправить код!Ошибка приложения при использовании курсора для чтения данных из базы данных SQLITE - Android

Итак, вы можете посмотреть мой код и рассказать мне, что с ним не так. Возможно ли, что проблема в том, что база данных пуста или это то, как я заполняю ListView.

Вот мой код:

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 

Спасибо

ответ

1

изменение Try populateListViewFromDB() это:

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

СПАСИБО ВАС ОЧЕНЬ, ЭТО РАБОТАЕТ СОВЕРШЕННО !!! : D –

1

У вас есть NullPointerException в getAllRows(). Скорее всего, ваш объект db имеет значение NULL.

Здесь вы создаете новый объект GPSDatabase, но не инициализируете переменную «db», которая затем используется для запроса на нее.

Вы можете проверить это, зарегистрировав состояние своих переменных или используя отладчик и вступая в метод, который дает вам ошибку. В большинстве IDE вы также можете установить точку останова на NullPointerException.

Я думаю, что insert() работает, потому что вы вызывали open() раньше.

+0

Как я могу проверить, если это нуль? и я должен добавить, что он не сбой, когда я использую метод insert. –

+0

Благодарим за редактирование, я попытаюсь использовать отладчик. Даже здесь я тоже открываю первый. –

+0

вы вызываете open() на объект myDb. но вы не используете этот. Вы создаете новый. – koljaTM

Смежные вопросы