首页 文章

如何在Android应用程序中使用现有数据库[重复]

提问于
浏览
298

这个问题在这里已有答案:

我已经创建了一个SQLite数据库 . 我想在我的Android项目中使用这个数据库文件 . 我想将此数据库与我的应用程序捆绑在一起 .

应用程序如何获取对此数据库的访问权并将其用作数据库,而不是创建新数据库?

5 回答

  • 11

    NOTE: 在尝试此代码之前,请在以下代码中找到以下行:

    private static String DB_NAME ="YourDbName"; // Database name
    

    这里的DB_NAME是您的数据库的名称 . 假设您在assets文件夹中有一个数据库副本,例如,如果您的数据库名称是ordersDB,那么DB_NAME的值将是ordersDB,

    private static String DB_NAME ="ordersDB";
    

    将数据库保存在 assets folder 中,然后按照以下步骤操作:

    DataHelper类:

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import android.content.Context;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.util.Log;
    
    public class DataBaseHelper extends SQLiteOpenHelper
    {
        private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window
        //destination path (location) of our database on device
        private static String DB_PATH = "";
        private static String DB_NAME ="YourDbName";// Database name
        private SQLiteDatabase mDataBase;
        private final Context mContext;
    
        public DataBaseHelper(Context context)
        {
            super(context, DB_NAME, null, 1);// 1? Its database Version
            if(android.os.Build.VERSION.SDK_INT >= 17){
               DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
            }
            else
            {
               DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
            }
            this.mContext = context;
        }
    
        public void createDataBase() throws IOException
        {
            //If the database does not exist, copy it from the assets.
    
            boolean mDataBaseExist = checkDataBase();
            if(!mDataBaseExist)
            {
                this.getReadableDatabase();
                this.close();
                try
                {
                    //Copy the database from assests
                    copyDataBase();
                    Log.e(TAG, "createDatabase database created");
                }
                catch (IOException mIOException)
                {
                    throw new Error("ErrorCopyingDataBase");
                }
            }
        }
    
        //Check that the database exists here: /data/data/your package/databases/Da Name
        private boolean checkDataBase()
        {
            File dbFile = new File(DB_PATH + DB_NAME);
            //Log.v("dbFile", dbFile + "   "+ dbFile.exists());
            return dbFile.exists();
        }
    
        //Copy the database from assets
        private void copyDataBase() throws IOException
        {
            InputStream mInput = mContext.getAssets().open(DB_NAME);
            String outFileName = DB_PATH + DB_NAME;
            OutputStream mOutput = new FileOutputStream(outFileName);
            byte[] mBuffer = new byte[1024];
            int mLength;
            while ((mLength = mInput.read(mBuffer))>0)
            {
                mOutput.write(mBuffer, 0, mLength);
            }
            mOutput.flush();
            mOutput.close();
            mInput.close();
        }
    
        //Open the database, so we can query it
        public boolean openDataBase() throws SQLException
        {
            String mPath = DB_PATH + DB_NAME;
            //Log.v("mPath", mPath);
            mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
            //mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
            return mDataBase != null;
        }
    
        @Override
        public synchronized void close()
        {
            if(mDataBase != null)
                mDataBase.close();
            super.close();
        }
    }
    

    Write a DataAdapter class like:

    import java.io.IOException;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteDatabase;
    import android.util.Log;
    
    public class TestAdapter
    {
        protected static final String TAG = "DataAdapter";
    
        private final Context mContext;
        private SQLiteDatabase mDb;
        private DataBaseHelper mDbHelper;
    
        public TestAdapter(Context context)
        {
            this.mContext = context;
            mDbHelper = new DataBaseHelper(mContext);
        }
    
        public TestAdapter createDatabase() throws SQLException
        {
            try
            {
                mDbHelper.createDataBase();
            }
            catch (IOException mIOException)
            {
                Log.e(TAG, mIOException.toString() + "  UnableToCreateDatabase");
                throw new Error("UnableToCreateDatabase");
            }
            return this;
        }
    
        public TestAdapter open() throws SQLException
        {
            try
            {
                mDbHelper.openDataBase();
                mDbHelper.close();
                mDb = mDbHelper.getReadableDatabase();
            }
            catch (SQLException mSQLException)
            {
                Log.e(TAG, "open >>"+ mSQLException.toString());
                throw mSQLException;
            }
            return this;
        }
    
        public void close()
        {
            mDbHelper.close();
        }
    
         public Cursor getTestData()
         {
             try
             {
                 String sql ="SELECT * FROM myTable";
    
                  Cursor mCur = mDb.rawQuery(sql, null);
                 if (mCur!=null)
                 {
                    mCur.moveToNext();
                 }
                 return mCur;
             }
             catch (SQLException mSQLException)
             {
                 Log.e(TAG, "getTestData >>"+ mSQLException.toString());
                 throw mSQLException;
             }
         }
    }
    

    Now you can use it like:

    TestAdapter mDbHelper = new TestAdapter(urContext);
    mDbHelper.createDatabase();
    mDbHelper.open();
    
    Cursor testdata = mDbHelper.getTestData();
    
    mDbHelper.close();
    

    EDIT: Thanks to JDx

    对于Android 4.1(果冻 beans ),改变:

    DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
    

    至:

    DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
    

    在DataHelper类中,此代码适用于JB 4.2多用户 .

  • 15

    如果您有预先构建的数据库而不是将其复制到资产文件夹中并创建一个新类 DataBaseHelper ,它实现 SQLiteOpenHelper 比使用以下代码:

    import java.io.File;
    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.SQLiteOpenHelper;
    
    public class DataBaseHelperClass extends SQLiteOpenHelper{
     //The Android's default system path of your application database.
    private static String DB_PATH = "/data/data/package_name/databases/";
    // Data Base Name.
    private static final String DATABASE_NAME = "DBName.sqlite";
    // Data Base Version.
    private static final int DATABASE_VERSION = 1;
    // Table Names of Data Base.
    static final String TABLE_Name = "tableName";
    
    public Context context;
    static SQLiteDatabase sqliteDataBase;
    
    /**
     * Constructor
     * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
     * @param context
     * Parameters of super() are    1. Context
     *                              2. Data Base Name.
     *                              3. Cursor Factory.
     *                              4. Data Base Version.
     */
    public DataBaseHelperClass(Context context) {       
        super(context, DATABASE_NAME, null ,DATABASE_VERSION);
        this.context = context;
    }
    
    /**
     * Creates a empty database on the system and rewrites it with your own database.
     * By calling this method and empty database will be created into the default system path
     * of your application so we are gonna be able to overwrite that database with our database.
     * */
    public void createDataBase() throws IOException{
        //check if the database exists
        boolean databaseExist = checkDataBase();
    
        if(databaseExist){
            // Do Nothing.
        }else{
            this.getWritableDatabase();         
            copyDataBase(); 
        }// end if else dbExist
    } // end createDataBase().
    
    /**
     * 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
     */
    public boolean checkDataBase(){
        File databaseFile = new File(DB_PATH + DATABASE_NAME);
        return databaseFile.exists();        
    }
    
    /**
     * 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 transferring byte stream.
     * */
    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 = DB_PATH + DATABASE_NAME; 
        //Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName); 
        //transfer bytes from the input file to the output file
        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(); 
    }
    
    /**
     * This method opens the data base connection.
     * First it create the path up till data base of the device.
     * Then create connection with data base.
     */
    public void openDataBase() throws SQLException{      
        //Open the database
        String myPath = DB_PATH + DATABASE_NAME;
        sqliteDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);  
    }
    
    /**
     * This Method is used to close the data base connection.
     */
    @Override
    public synchronized void close() { 
        if(sqliteDataBase != null)
            sqliteDataBase.close(); 
        super.close(); 
    }
    
    /**
    * Apply your methods and class to fetch data using raw or queries on data base using 
    * following demo example code as:
    */
    public String getUserNameFromDB(){
        String query = "select User_First_Name From "+TABLE_USER_DETAILS;
        Cursor cursor = sqliteDataBase.rawQuery(query, null);
        String userName = null;
        if(cursor.getCount()>0){
            if(cursor.moveToFirst()){
        do{
                    userName = cursor.getString(0);
                }while (cursor.moveToNext());
            }
        }
        return userName;
    }
    
    
    @Override
    public void onCreate(SQLiteDatabase db) {
        // No need to write the create table query.
        // As we are using Pre built data base.
        // Which is ReadOnly.
    }
    
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // No need to write the update table query.
        // As we are using Pre built data base.
        // Which is ReadOnly.
        // We should not update it as requirements of application.
    }   
    }
    

    希望对你有帮助...

  • 6

    关于这个问题,我遇到了其他DatabaseHelpers的麻烦,不知道为什么 .
    这对我有用:

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.util.Log;
    
    public class DatabaseHelper extends SQLiteOpenHelper {
    
      private static final String TAG = DatabaseHelper.class.getSimpleName();
    
      private final Context context;
      private final String assetPath;
      private final String dbPath;
    
      public DatabaseHelper(Context context, String dbName, String assetPath)
          throws IOException {
        super(context, dbName, null, 1);
        this.context = context;
        this.assetPath = assetPath;
        this.dbPath = "/data/data/"
            + context.getApplicationContext().getPackageName() + "/databases/"
            + dbName;
        checkExists();
      }
    
      /**
       * Checks if the database asset needs to be copied and if so copies it to the
       * default location.
       * 
       * @throws IOException
       */
      private void checkExists() throws IOException {
        Log.i(TAG, "checkExists()");
    
        File dbFile = new File(dbPath);
    
        if (!dbFile.exists()) {
    
          Log.i(TAG, "creating database..");
    
          dbFile.getParentFile().mkdirs();
          copyStream(context.getAssets().open(assetPath), new FileOutputStream(
              dbFile));
    
          Log.i(TAG, assetPath + " has been copied to " + dbFile.getAbsolutePath());
        }
    
      }
    
      private void copyStream(InputStream is, OutputStream os) throws IOException {
        byte buf[] = new byte[1024];
        int c = 0;
        while (true) {
          c = is.read(buf);
          if (c == -1)
            break;
          os.write(buf, 0, c);
        }
        is.close();
        os.close();
      }
    
      @Override
      public void onCreate(SQLiteDatabase db) {
      }
    
      @Override
      public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
      }
    }
    
  • 4

    如果您已有数据库,请将其保存在资产文件夹中并将其复制到应用程序中 . 有关更多详细信息,请参阅Android database basics .

  • 325

    您可以使用content provider执行此操作 . 应用程序中使用的每个数据项对应用程序保持私有 . 如果应用程序想要跨应用程序共享数据,则只有使用内容提供程序实现此目的的技术,内容提供程序提供访问该私有数据的接口 .

相关问题