অ্যান্ড্রয়েডে এসেট ফোল্ডার থেকে ডেটাবেজ নিয়ে কাজ করা যায় না। যা আমরা করতে পারি, তা হচ্ছে এসেট ফোল্ডার থেকে ডেটাবেজ কপি করে স্টোরেজে কপি করতে পারি। এরপর পরে ঐ কপি করা ডেটাবেজ ব্যবহার করতে পারি। শুরু করি এসেট ফোল্ডারে একটি ডেটাবেজ রেখে। এই লেখাতে ব্যবহৃত ডেটাবেজটি এখান থেকে ডাউনলোড করা যাবে। ডিফল্ট ভাবে assets ফোল্ডার তৈরি থাকে না। তৈরি করার জন্য প্রজেক্টের উপর রাইট ক্লিক করে New > Folder > Assets ফোল্ডারে ক্লিক করে তৈরি করে নিতে পারি।
এর পরের কাজ হচ্ছে এসেট ফোল্ডার থেকে ডেটাবেজ কপি করে স্টোরেজে রাখা। তার জন্য আমরা একটা ক্লাস তৈরি করে নিতে পারি, যেমন AssetDatabaseOpenHelper:
import android.content.Context; import android.database.sqlite.SQLiteDatabase; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class AssetDatabaseOpenHelper { private Context context; private String DB_NAME; public AssetDatabaseOpenHelper(Context context, String database_name) { this.context = context; this.DB_NAME = database_name; } public SQLiteDatabase saveDatabase() { File dbFile = context.getDatabasePath(DB_NAME); if (!dbFile.exists()) { try { copyDatabase(dbFile); } catch (IOException e) { throw new RuntimeException("Error creating source database", e); } } return SQLiteDatabase.openDatabase(dbFile.getPath(), null, SQLiteDatabase.OPEN_READONLY); } private void copyDatabase(File dbFile) throws IOException { InputStream is = context.getAssets().open(DB_NAME); OutputStream os = new FileOutputStream(dbFile); byte[] buffer = new byte[1024]; while (is.read(buffer) > 0) { os.write(buffer); } os.flush(); os.close(); is.close(); } }
এই ক্লাসকে ইনিশিয়ালাইজ করে এবং saveDatabase মেথড কল করলে ডেটাবেজ স্টোরেজে সেভ হবে। এভাবে করতে পারিঃ
// Copy database AssetDatabaseOpenHelper assetDatabaseOpenHelper = new AssetDatabaseOpenHelper(this, DB_NAME); assetDatabaseOpenHelper.saveDatabase();
ডেটাবেজ কপি হয়েছে কিনা, তা দেখতে চাইলে আমরা অ্যান্ড্রয়েড স্টুডিও থেকে Tools > Android > Android Device Monitor এ ক্লিক করব। এখানে আমাদের যে ডিভাইস বা ভার্চুয়াল ডিভাইসটি কানেক্টেড থাকবে, তার তথ্য দেখাবে। এখান থেকে Data > Data > app id তে ন্যাভিগেট করলে Database নামে ফোল্ডার পাবো। এই ফোল্ডারে ডেটাবেজ দেখাবে। আমরা চাইলে এই ডেটাবেজ কম্পিউটারে এক্সপোর্ট করে দেখতেও পারব। তার জন্য ডেটাবেজ এ ক্লিক করে pull to device আইকনে ক্লিক করে লোকেশন দেখিয়ে দিলে তা কম্পিউটারে দেখতে পারব।
ডেটাবেজ এর ভেতরে কি আছে, তা আমরা দেখতে চাইলে SQLite Database Browser বা এমন যে কোন সফটওয়ার ব্যবহার করতে পারি। ক্রোম ব্রাউজার বা ফায়ারফক্সের এক্সটেনশন ও রয়েছে অনেক।
ডেটাবেজ কপি হওয়ার পর আমরা এবার ডেটাবেজ থেকে ডেটা নিয়ে কাজ করতে পারি। বাকি কাজ গুলো সাধারণ SQLite নিয়ে কাজ করার মত। অ্যান্ড্রয়েড অ্যাপে SQLite ডেটাবেজ ব্যবহার লেখাটিতে ডেটাবেজের সব গুলো অপারেশন নিয়ে লেখা রয়েছে। এখানে শুধু দেখব কিভাবে ডেটাবেজের কোন টেবিল থেকে ডেটা কোয়েরি করা যায়। তার জন্য আমরা DataBaseHelper নামে একটা ক্লাস তৈরি করে নিব। getAllData নামে একটা মেথড লিখব, যেখানে কোন টেবিল পাস করলে ঐ টেবিলের ডেটা গুলো আমাদের রিটার্ণ করবে। DataBaseHelper:
import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DataBaseHelper extends SQLiteOpenHelper { public DataBaseHelper(Context context, String db_name) { super(context, db_name, null, 1); } @Override public void onCreate(SQLiteDatabase db) { } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } public Cursor getAllData(String tableName) { SQLiteDatabase db = this.getWritableDatabase(); Cursor res = db.rawQuery("select * from " + tableName, null); return res; } }
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="me.jakir.prebuilddatabase.MainActivity"> <Button android:id="@+id/btn_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginTop="8dp" android:text="View Data" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/resultView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginTop="8dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/btn_view" /> </android.support.constraint.ConstraintLayout>
MainActivity.java:
import android.database.Cursor; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends AppCompatActivity { String DB_NAME = "hello.db"; String TABLE_NAME = "name"; DataBaseHelper myDBHelper; Button button; TextView result; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Copy database AssetDatabaseOpenHelper assetDatabaseOpenHelper = new AssetDatabaseOpenHelper(this, DB_NAME); assetDatabaseOpenHelper.saveDatabase(); myDBHelper = new DataBaseHelper(this, DB_NAME); result = (TextView) findViewById(R.id.resultView); button = (Button) findViewById(R.id.btn_view); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Cursor res = myDBHelper.getAllData(TABLE_NAME); if (res.getCount() == 0) { result.setText("No Data found, sorry!"); return; } else { StringBuffer buffer = new StringBuffer(); while (res.moveToNext()) { buffer.append("Id: " + res.getString(0) + "\n"); buffer.append("Name: " + res.getString(1) + "\n"); } result.setText(buffer); } } }); } }
ধন্যবাদ, ভাইয়া। এখন এই ডাটাবেইস টা যেন কেউ পুল করে নিয়ে দেখতে না পারে, তার জন্য sqlcipher library কিভাবে ব্যবহার করব ?