从SQLite数据库Android获取数据

时间:2013-04-22 09:18:52

标签: android arraylist android-sqlite

我正在尝试从我的资源文件夹中访问SQLite数据库中的数据。数据库的名称是“fruits.sql”。

第一:

public class ArticlesTable {        
    public String TABLE_NAME="fruit";
    public String ORANGE="orange";
}

然后我的模态

public class Article {
    public String orange;
}

最后我的DBHelper类是

public class DBHelper {

    private final String DATABASE_PATH = "/data/data/mon.immeuble/databases/";
    private final String DATABASE_NAME = "frui.sqlite";
    private final static int DATABASE_VERSION = 1;

    private Context context;
    private SQLiteDatabase database = null;
    OpenHelper openHelper=null;
    StringBuilder query =null;
    Cursor cursor=null;

    ArticlesTable articlesTable=new ArticlesTable();

    public static DBHelper dbHelper = null;

    private DBHelper(Context context) {

    this.context = context;
    openHelper = new OpenHelper(this.context);
    this.database = openHelper.getWritableDatabase();

    try {

        createDataBase();
        openDataBase();

    } catch (IOException e) {

        e.printStackTrace();
    }

    }
    public static DBHelper getInstance(Context context)
    {
    if(dbHelper == null)
        dbHelper = new DBHelper(context);
    return dbHelper;
    }

   public void openDataBase() throws SQLException{

    //Open the database
    String myPath = DATABASE_PATH + DATABASE_NAME;
    database = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
    }

    /**
     * Creates a empty database on the system and rewrites it with your own database.
     * */
    public void createDataBase() throws IOException
    {
    openHelper.getReadableDatabase();
    if(getDBAlreadyCopiedToDeviceOnceFlag(context) == false){
        try {
        copyDataBase();
        setDBAlreadyCopiedToDeviceOnceFlag(context);
        } catch (IOException e) {
        e.printStackTrace();
        throw new Error("Error copying database");
        }
    }
    }

    /**
     * Check if the database already exist to avoid re-copying the file each time you open the application.
     * @return true if it exists, false if it doesn't
     */
    @SuppressWarnings("unused")
    private boolean checkDataBase(){

    SQLiteDatabase checkDB = null;

    try{
        String myPath = DATABASE_PATH + DATABASE_NAME;
        checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);

    }catch(SQLiteException e){

        //database does't exist yet.

    }

    if(checkDB != null){

        checkDB.close();

    }

    return checkDB != null ? true : false;
    }

    /**
     * Copies your database from your local assets-folder to the just created empty database in the
     * system folder, from where it can be accessed and handled.
     * This is done by transfering bytestream.
     * */
    private void copyDataBase() throws IOException{

    //Open your local db as the input stream
    InputStream myInput = context.getAssets().open(DATABASE_NAME);

    // Path to the just created empty db
    String outFileName = DATABASE_PATH + DATABASE_NAME;

    //Open the empty db as the output stream
    OutputStream myOutput = new FileOutputStream(outFileName);

    //transfer bytes from the inputfile to the outputfile
    byte[] buffer = new byte[1024];
    int length;
    while ((length = myInput.read(buffer))>0){
        myOutput.write(buffer, 0, length);
    }

    //Close the streams
    myOutput.flush();
    myOutput.close();
    myInput.close();

    }

    private class OpenHelper extends SQLiteOpenHelper
    {

        @SuppressWarnings("unused")
        SQLiteStatement insertStmt;

        public OpenHelper(Context context)
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db)
        {
            // TODO Auto-generated method stub
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
        {
            // TODO Auto-generated method stub
        }
    }


    public void setDBAlreadyCopiedToDeviceOnceFlag(Context ctx)
    {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putBoolean("isDBAlreadyCopiedToDeviceOnce", true);
        editor.commit();
    }

    public boolean getDBAlreadyCopiedToDeviceOnceFlag(Context ctx)
    {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
        boolean isDBAlreadyCopiedToDeviceOnce = prefs.getBoolean("isDBAlreadyCopiedToDeviceOnce", false);
        return isDBAlreadyCopiedToDeviceOnce; 
    }


    public ArrayList<Article> getArticlesList()
    {
        ArrayList<Article> items=new ArrayList<Article>();

        try
        {
            query = new StringBuilder();
            query.append("select * from "+articlesTable.TABLE_NAME+" ORDER BY nom DESC");

            cursor=this.database.rawQuery(query.toString(),null);
            if (cursor.moveToFirst())
            {
                do
                {
                    Article a=new Article();

                    a.orange=cursor.getString(cursor.getColumnIndex(articlesTable.FRUIT));


                    items.add(a);

                    System.out.println("added_items:"+items);
                }
                while (cursor.moveToNext());
            }
            if (cursor != null && !cursor.isClosed())
            {
            cursor.close();

            }
        }
        catch(SQLiteException e){

            e.printStackTrace();
            return null;
        }

        return items;
    }
    //--here
    public boolean addArticle(Article a){
        this.database.beginTransaction();

        try{

            ContentValues contentValues=new ContentValues();

            contentValues.put(articlesTable.FRUIT, a.fruit);


            this.database.insert(articlesTable.TABLE_NAME,null,contentValues);
        this.database.setTransactionSuccessful();
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }finally{
            this.database.endTransaction();
        }
        return true;
    }

和我访问数据的全局类

public class Globals {
    public static DBHelper dbHelper;

    public static ArrayList<Article> articles;

    public static void copyArticles(ArrayList<Article> articlesList) {
        if(articlesList!=null){

            if(articles==null)

                articles=new ArrayList<Article>();
            else
                articles.clear();

            for(Article a: articlesList)
                articles.add(a);
        }
    }

但是,当我使用

在我的创建活动中调用一个字段时
 public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fruit);
System.out.println(Globals.articles.get(0).adresse1);
    }

我得到一个空指针异常。

更新

Alex G.解决了这个问题,现在我在日志中收到此错误

04-22 13:43:52.375: E/AndroidRuntime(5015): FATAL EXCEPTION: main
04-22 13:43:52.375: E/AndroidRuntime(5015): java.lang.Error: Error copying database
04-22 13:43:52.375: E/AndroidRuntime(5015):     at .db.DBHelper.createDataBase(DBHelper.java:82)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at .db.DBHelper.<init>(DBHelper.java:47)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at .db.DBHelper.getInstance(DBHelper.java:59)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at .utils.Globals.init(Globals.java:17)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at .utils.map.Map.onCreate(Map.java:71)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.app.ActivityThread.startActivityNow(ActivityThread.java:1491)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:127)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.widget.TabHost$IntentContentStrategy.getContentView(TabHost.java:657)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.widget.TabHost.setCurrentTab(TabHost.java:329)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at .TabSample.setProximite(TabSample.java:567)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at .TabSample.onCreate(TabSample.java:81)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.os.Looper.loop(Looper.java:130)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at android.app.ActivityThread.main(ActivityThread.java:3687)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at java.lang.reflect.Method.invokeNative(Native Method)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at java.lang.reflect.Method.invoke(Method.java:507)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
04-22 13:43:52.375: E/AndroidRuntime(5015):     at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:2)

您正在尝试从ArrayList articles获取一个项目,但您没有在任何地方初始化它。如果没有评论你的类结构,你至少需要初始化你的dbhelper和你的arraylist:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fruit);

    Globals.init(this);

    System.out.println(Globals.articles.get(0).adresse1);
}

请注意添加对init的调用。然后:

public class Globals {
    public static DBHelper dbHelper;

    public static ArrayList<Article> articles;

    public static void init(Context ctx) {
        DBHelper helper = DBHelper.getInstance(ctx);
        copyArticles(helper.getArticlesList());
    }

    public static void copyArticles(ArrayList<Article> articlesList) {
        if(articlesList!=null){

            if(articles==null)

                articles=new ArrayList<Article>();
            else
                articles.clear();

            for(Article a: articlesList)
                articles.add(a);
        }
    }
}

同样,我没有对您的代码的结构方式做出任何评论,只是简单地指出了您收到错误的原因。