2013-07-03 2 views
3

Итак, я создал базу данных для использования в своем приложении для Android. То, что я пытаюсь сделать, это просто, просто читать из моей базы данных и отображать данные в TextView, вот DataBaseHelper классAndroid: Чтение из базы данных SQLite во время выполнения

package com.tix.activity; 

import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 

import android.content.Context; 
import android.database.Cursor; 
import android.database.SQLException; 
import android.database.sqlite.SQLiteDatabase; 
import android.database.sqlite.SQLiteException; 
import android.database.sqlite.SQLiteOpenHelper; 

public class DatabaseHelper extends SQLiteOpenHelper{ 
    private static String DB_PATH = "/data/data/com.tix.activity/databases/"; 
    private static String DB_NAME = "tix"; 
    private SQLiteDatabase myDatabase; 
    private final Context myContext; 

    public DatabaseHelper (Context context) { 
     super(context, DB_NAME, null, 1); 
     this.myContext = context; 
    } 

public void createDataBase() throws IOException{ 
    boolean dbExist = checkDataBase(); 

    if(dbExist){ 
    }else{ 
     this.getReadableDatabase(); 
     try{ 
      copyDataBase(); 
     }catch (IOException e) { 
      throw new Error("Error copying Database"); 
     } 
    } 
} 

private boolean checkDataBase() { 
    // TODO Auto-generated method stub 
    SQLiteDatabase checkDB = null; 
    try { 
     String myPath = DB_PATH + DB_NAME; 
     checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 
    }catch(SQLiteException e){ 

    } 
    if(checkDB != null){ 
     checkDB.close(); 
    } 

    return checkDB != null ? true : false; 
} 

private void copyDataBase() throws IOException{ 
    InputStream myInput = myContext.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; 
    myDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

} 

@Override 
public synchronized void close(){ 
    if(myDatabase != null) 
     myDatabase.close(); 
    super.close(); 

} 
@Override 
public void onCreate(SQLiteDatabase db){ 

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

} 

public Cursor data(){ 
    Cursor c; 
    c = myDatabase.query(DB_NAME,null,null,null,null,null,null); 
    return c; 
} 
} 

И это мой MainActivity класс

package com.tix.activity; 

import java.io.IOException; 

import android.os.Bundle; 
import android.app.Activity; 
import android.database.Cursor; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.TextView; 

public class MainActivity extends Activity { 
Cursor cur; 
TextView tv; 
Button next, prev; 
DatabaseHelper dbh; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     tv = (TextView)findViewById(R.id.tv); 
     next = (Button)findViewById(R.id.nbtn); 
     prev = (Button)findViewById(R.id.pbtn); 

     dbh = new DatabaseHelper(this); 

     try { 
      dbh.createDataBase(); 
     } catch (IOException e2) { 
      e2.printStackTrace(); 
     } 

     dbh.openDataBase(); 
     cur = dbh.data(); 
     cur.moveToFirst(); 
     tv.setText(cur.getString(1)); 

     next.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // TODO Auto-generated method stub 
       if(cur.isLast()) 
       { 
        cur.moveToFirst(); 
        tv.setText(""+cur.getString(1)); 
       } 
       else 
       { 
        cur.moveToNext(); 
        tv.setText(""+cur.getString(1)); 

       } 
      } 
     }); 
     prev.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // TODO Auto-generated method stub 
      if(cur.isFirst()){ 
       cur.moveToLast(); 
       tv.setText(""+cur.getString(1)); 
      } 
      else 
      { 
       cur.moveToPrevious(); 
       tv.setText(""+cur.getString(1)); 
      } 
      } 
     }); 

    } 
} 

Но, каждый раз Я запускаю приложение в эмуляторе, он просто падает. Но если я поставлю tv.setText (cur.getString (0)); вместо tv.setText (cur.getString (1));

затем я получаю textview для отображения 'en_US' (который я действительно не хочу отображать, возможно, его из локали) и при нажатии любой из кнопок приложение сбой.

Вот ошибка, я получаю на LogCat,

07-03 16:37:45.120: E/CursorWindow(1912): Failed to read row 0, column 1 from a CursorWindow which has 1 rows, 1 columns. 
07-03 16:37:45.160: D/AndroidRuntime(1912): Shutting down VM 
07-03 16:37:45.160: W/dalvikvm(1912): threadid=1: thread exiting with uncaught exception (group=0x40a70930) 
07-03 16:37:45.180: E/AndroidRuntime(1912): FATAL EXCEPTION: main 
07-03 16:37:45.180: E/AndroidRuntime(1912): java.lang.IllegalStateException: Couldn't read row 0, col 1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at android.database.CursorWindow.nativeGetString(Native Method) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at android.database.CursorWindow.getString(CursorWindow.java:434) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at com.tix.activity.MainActivity$2.onClick(MainActivity.java:65) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at android.view.View.performClick(View.java:4202) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at android.view.View$PerformClick.run(View.java:17340) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at android.os.Handler.handleCallback(Handler.java:725) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at android.os.Handler.dispatchMessage(Handler.java:92) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at android.os.Looper.loop(Looper.java:137) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at android.app.ActivityThread.main(ActivityThread.java:5039) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at java.lang.reflect.Method.invokeNative(Native Method) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at java.lang.reflect.Method.invoke(Method.java:511) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
07-03 16:37:45.180: E/AndroidRuntime(1912):  at dalvik.system.NativeStart.main(Native Method) 
07-03 16:39:01.480: I/Process(1912): Sending signal. PID: 1912 SIG: 9 
07-03 16:39:30.201: W/Trace(1966): Unexpected value from nativeGetEnabledTags: 0 
07-03 16:39:30.201: W/Trace(1966): Unexpected value from nativeGetEnabledTags: 0 
07-03 16:39:30.631: W/Trace(1966): Unexpected value from nativeGetEnabledTags: 0 
07-03 16:39:30.631: W/Trace(1966): Unexpected value from nativeGetEnabledTags: 0 
07-03 16:39:31.522: E/CursorWindow(1966): Failed to read row 0, column 1 from a CursorWindow which has 1 rows, 1 columns. 
07-03 16:39:31.531: D/AndroidRuntime(1966): Shutting down VM 
07-03 16:39:31.531: W/dalvikvm(1966): threadid=1: thread exiting with uncaught exception (group=0x40a70930) 
07-03 16:39:31.582: E/AndroidRuntime(1966): FATAL EXCEPTION: main 
07-03 16:39:31.582: E/AndroidRuntime(1966): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tix.activity/com.tix.activity.MainActivity}: java.lang.IllegalStateException: Couldn't read row 0, col 1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.app.ActivityThread.access$600(ActivityThread.java:141) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.os.Handler.dispatchMessage(Handler.java:99) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.os.Looper.loop(Looper.java:137) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.app.ActivityThread.main(ActivityThread.java:5039) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at java.lang.reflect.Method.invokeNative(Native Method) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at java.lang.reflect.Method.invoke(Method.java:511) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at dalvik.system.NativeStart.main(Native Method) 
07-03 16:39:31.582: E/AndroidRuntime(1966): Caused by: java.lang.IllegalStateException: Couldn't read row 0, col 1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it. 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.database.CursorWindow.nativeGetString(Native Method) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.database.CursorWindow.getString(CursorWindow.java:434) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at com.tix.activity.MainActivity.onCreate(MainActivity.java:38) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.app.Activity.performCreate(Activity.java:5104) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144) 
07-03 16:39:31.582: E/AndroidRuntime(1966):  ... 11 more 

Мой 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" 
    tools:context=".MainActivity" > 

    <Button 
     android:id="@+id/pbtn" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:layout_marginLeft="33dp" 
     android:layout_marginTop="48dp" 
     android:text="Back" /> 

    <Button 
     android:id="@+id/nbtn" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignBaseline="@+id/pbtn" 
     android:layout_alignBottom="@+id/pbtn" 
     android:layout_alignParentRight="true" 
     android:layout_marginRight="25dp" 
     android:text="Next" /> 

    <TextView 
     android:id="@+id/tv" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/pbtn" 
     android:layout_centerHorizontal="true" 
     android:layout_marginTop="141dp" 
     android:text="Large Text" 
     android:textAppearance="?android:attr/textAppearanceLarge" /> 

</RelativeLayout> 

Я сделал базу данных с помощью SQLite Database Browser , но он содержит таблицу под названием android_metadata с полем локали (текста) со значением как «en_US», а другая таблица «tix» с первичным полем как «_id», а другое поле - «шутки». Вот и все.

Может ли кто-нибудь указать, что не так? И как это исправить? Мне определенно нужна помощь в этом, потому что это мой первый снимок в базе данных:/

+0

Пожалуйста, используйте 'SQLiteAssetHelper' для обработки настроенной базы данных: https://github.com/jgilfelt/android-sqlite-asset-helper – CommonsWare

+0

Я мало знаю, но из того, что я читал, он в значительной степени делает то же самое. И что касается попытки, я просто сделал это сейчас, не помог, получить то же самое сообщение об ошибке. Спасибо хоть. – iMan

+0

Пожалуйста, помогите с этим http://stackoverflow.com/questions/20728808/android-reading-stored-sqlite-database – gandharv09

ответ

3

Просто поместить курсор в TextView не получится. Сначала нужно получить контент.

вы coukd попробовать, как это в вашем классе DB:

public String data(){ 
    Cursor c; 
    String result; 


    c = myDatabase.query(DB_NAME,null,null,null,null,null,null); 

     try { 
       if (c.moveToFirst()) { 
        result = cursor.getString(0); 
       } 
       result = c.getString(0); 
      } finally { 
       c.close(); 
      } 

    return result; 
} 

и в вашем TextView:

tv.setText(dbh.data()); 

Или что-то подобное

не лучший способ, но должен работать

+0

Спасибо, но, к сожалению, он не работает. Я полагаю, что это может быть связано с индексом столбца или строки? У меня есть две таблицы в моей базе данных, android_metadata и tix, как мне выбрать таблицу tix из базы данных? Я много гугл, не нашел объяснений, чтобы помочь мне в этом. У меня явно нет никакой идеи. – iMan

+0

Вы выбираете базу данных в запросе. DB_NAME - ваша таблица. –

+0

Спасибо, теперь я могу частично получить доступ к моему db.Скажем, мой db: '| -------------------------- |' '| _id | шутки | | -------------------------- | | 1 | jokeA | | 2 | jokeB | | -------------------------- | ' теперь я получаю, вывод как« 1 », когда' getString (0) ' и jokeA, если 'getString (1)', как мне получить jokeB? Любое другое целочисленное значение вызывает сбой приложения! – iMan