ایجاد و استفاده از دیتابیس

بسم الله الرحمن الرحیم

ایجاد و  استفاده از   دیتابیس

فصل ششم-بخش سوم

همان   طور  که  تا  حال   مشاهده   کرده اید   تمام  تکنو لوژ های   موجود  یک  راه   قدیمی  برای   ذخیره  مجموع  ای از  داده ها دارند.  برای   ذخیره  داده های  ارتباطی (Realation Date)   استفاده از   دیتابیس   بسیار   کارامد  می باشد.  به عنوان مثال   اگر  شما می خواهید نتایج   امتحانات   دانش آموزان  یک  مدرسه را   ذخیره  کنید   استفاده از   دیتابیس  بسیار    کارا مد  می باشد  زیرا  شما می توانید query  های را برای  بازیابی   دانش آموزان   تعیین کنید    علاوه بر این    استفاده  از دیتابیس  شما  قادر  می  سازد     تا  یکپارچه  سازی  داده ها را  با  استفاده از  از   رابط  بین   محموعه از  داده ها به  اجرا  در آورید.

اندروید از   دیتابیس     SQLite  استفاده می  کند. دیتابیس که  شما   برای   برنامه   کاربردی   خود   ایجاد  می کنید    فقط  از  طریق  همان  برنامه  قابل  دسترسی و  دیگر  برنامه  به  آن دسترسی  ندارند.

در   این  بخش   شما  یاد  می  گیرید  که  چگونه می توان با  برنامه نویسی  یک  دیتابیس   SQLiteبرای  برنامه  کاربردی ایجاد  کرد  برای  اندروید    دیتابیسی که  شما  از  طریق  برنامه نویسی   ایجاد  می کنید  همیشه  در مسیر /data/data/<package_name>/databases  ذخیره می شود

 

ایجاد  کلاس کمک  کنندDBAdapter

یک  تمرین  خوب برای   کار با  دیتابیس   ایجاد   یک    کلاس  کمک  کننده می باشد که از پیچیدگی های  دسترسی به داده های   جلوگیری می کند و   شما  کافی   متد های  آن را فراخوانی کنید از  این  رو  در این  بخش از  برنامه   شما یک  کلاس  کمک کننده  به نام  DBAdapter ایجاد  می  کنید  که  این  کلاس  دیتابیس  را    ایجاد   -  باز -  بسته و  و از  دیتابیس Sqlite  استفاده می کنید

در این  مثال شما   دیتابیسی به نامMyDB  ایجاد می کنید  که دارای جدولی  به نام contacts. می باشد و  این  جدول   3    ستون  به نام _id, name, , emailدارد مانند  شکل  زیر

دیتاببیس در اندروید

دیتابیس در اندروید

پروژه  جدیدی به نام  ایجاد  Databases.کنید

کلاس  جدیدی  به نام  DBAdapter ایجاد  کنید

در  فایل DBAdapter.java دستورات  زیر  را   وارد  نمایید.


package com.MehrdadJavididatabases;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
static final String KEY_ROWID = "_id";
static final String KEY_NAME = "name";
static final String KEY_EMAIL = "email";
static final String TAG = "DBAdapter";
static final String DATABASE_NAME = "MyDB";
static final String DATABASE_TABLE = "contacts";
static final int DATABASE_VERSION = 1;
static final String DATABASE_CREATE =
"create table contacts (_id integer primary key autoincrement, "
+ "name text not null, email text not null);";
final Context context;
DatabaseHelper DBHelper;
SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
try {
db.execSQL(DATABASE_CREATE);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS contacts");
onCreate(db);
}
}
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
//---insert a contact into the database---
public long insertContact(String name, String email)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_EMAIL, email);
return db.insert(DATABASE_TABLE, null, initialValues);
}
//---deletes a particular contact---
public boolean deleteContact(long rowId)
{
return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
//---retrieves all the contacts---
public Cursor getAllContacts()
{
return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,
KEY_EMAIL}, null, null, null, null, null);
}
//---retrieves a particular contact---
public Cursor getContact(long rowId) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
KEY_NAME, KEY_EMAIL}, KEY_ROWID + "=" + rowId, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
//---updates a contact---
public boolean updateContact(long rowId, String name, String email)
{
ContentValues args = new ContentValues();
args.put(KEY_NAME, name);
args.put(KEY_EMAIL, email);
return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}
}

توضیحات

شما  ابتدا    ثابت  های  را  برای  را که برابر  فیلد های  جدول در  دیتابیسی که می خواهید  ایجاد  کنید میباشد


static final String KEY_ROWID = "_id";
static final String KEY_NAME = "name";
static final String KEY_EMAIL = "email";
static final String TAG = "DBAdapter";
static final String DATABASE_NAME = "MyDB";
static final String DATABASE_TABLE = "contacts";
static final int DATABASE_VERSION = 1;
static final String DATABASE_CREATE =
"create table contacts (_id integer primary key autoincrement, "
+ "name text not null, email text not null);";

در  اینجا    ثابت DATABASE_CREATE  شامل   دستور   SQL برای    ساخت  جدول در  دیتابیس  MyDBمی  می باشد

 در   کلاس DBAdapter ,شما  یک  کلاس  محلی      تعریف  کرده اید  که از  کلاسSQLiteOpenHelper مشتق  شده است   که  این  کلاس  کمک  می کند  تا    ساخت  دیتابیس  و     نسخه های مختلف    دیتابیس را  کنترل  کنید.

به  طور   خاص شما  متد های onCreate() and onUpgrade  را  override کردید

public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db)
{
try {
db.execSQL(DATABASE_CREATE);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS contacts");
onCreate(db);
}
}

متد  onCreate() دیتابیس  جدیدی را  در  صورتی  که  وجود  نداشته باشد  ایجاد  می کند و متد  onUpgrade() زمانی فروخوانی می شود که   دیتابیس    نیازدارد تا  به  Upgradeشود این  کار  با  چک  کردن   ثابت DATABASE_VERSION و  به  کاربردن  در متد  می  شود که شما  به  سادگی می  توانید در  متدonUpgrade()  به  کار ببرید  و   جدول را   حذف  و  مجدد ایجاد  کنید.

 

شما  می  توانید    متد های  دیگر را برای   باز کردن   و بستن  دیتابیس و  همجین    اضافه کردن  ویرایش  و  باز  گرداند  مقادیر    جدول  در د یتابیس  تعریف  کیند.

public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
//---insert a contact into the database---
public long insertContact(String name, String email)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_EMAIL, email);
return db.insert(DATABASE_TABLE, null, initialValues);
}
//---deletes a particular contact---
public boolean deleteContact(long rowId)
{
return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
//---retrieves all the contacts---
public Cursor getAllContacts()
{
return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,
KEY_EMAIL}, null, null, null, null, null);
}
//---retrieves a particular contact---
public Cursor getContact(long rowId) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
KEY_NAME, KEY_EMAIL}, KEY_ROWID + "=" + rowId, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
//---updates a contact---
public boolean updateContact(long rowId, String name, String email)
{
ContentValues args = new ContentValues();
args.put(KEY_NAME, name);
args.put(KEY_EMAIL, email);
return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}

توجه  کنید  که  کلاس   مقادیر Cursor را  برای  query  بر می گردداند  این  طور  فکر  کنید  که   کلاس Cursor  اشاره  به  یک  محموعه  از نتایج  query  های  دیتابیس  دارد.

استفاد از  کلاس Cursor شما  قادر  می سازد  تا   بسیار  کار ها  بر روی  سطر های  و    ستون ها را  مدیریت   کنید

شما  از  کلاس ContentValues برای  مقادیر  name/value  استفاده می کنید  متد  put() شما را  قادر می  سازد  تا  key های  با  نوع داده های   متفاوت     اضافه کنید.

 

برای  ساخت    دیتابیس  برنامه    توسط  کلاس DBAdapter شما یک  نمونه از  ایجاد DBAdapter کردید


public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}

که این  سازنده DBAdapter یک  نمونه  از  کلاس DatabaseHelper برای  ساخت  دیتابیس  ایجاد  می کند

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

استفاده از DataBase 

شما  DBAdapter  کلاس  ایجاد  کردید  حال   لازم  است  که از  آن  برای  دیتابیس  استفاده  کنید در    قسمت زیر شما  یاد  می  گیرید که   چکونه CRUD  (create, read, update and delete) را انجام  دهید  عملیات  های که با  دیتابیس انجام می شود.

 

اضافه کردن Contacts

در ادامه  شرح می دهیم که  چگونه یک contact اضافه  کنید(  عملیات اضافه کردن در دیتابیس)

به  پروژه   قبل  رفته و  فایل MainActivity.java به  صورت زیر   تغیر دهید


package com.MehrdadJavididatabases;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBAdapter db=new DBAdapter(this);
//---add a contact---
db.open();
long id = db.insertContact("Mehrdad Javidi", "Mehrdad.j16367@Gmail.com");
id = db.insertContact("Ali Javidi", "ali@Example.Com");
db.close();
}
}

توضیحات

در اینجا شما  یک نمونه از  کلاس DBAdapter ایجاد  کردید.

DBAdapter db = new DBAdapter(this);

  متد insertContact()  در  صورت  درج   سطر جدید یک ID را  بر می گرداند در  غیر این  صورت 1- را بر  می گرداند

شما در  DDMS, می توانید  دیتابیس   ایجاد  شده را مشاهده کنید

دیتابیس در اندروید

بر گرداندن   تمام Contacts  (تمام   سطر های  جدول)

برای  بر گردان  تمام  Contact های جدول  از متد  getAllContacts()  در   کلاس DBAdapter  استفاده  می  کنیم

فایل Main/activity.java به  صورت زیر   تغییر  می دهیم

package com.MehrdadJavididatabases;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBAdapter db=new DBAdapter(this);
//---add a contact---
//db.open();
//long id = db.insertContact("Mehrdad Javidi", "Mehrdad.j16367@Gmail.com");
//id = db.insertContact("Ali Javidi", "ali@Example.Com");
//db.close();
db.open();
Cursor c = db.getAllContacts();
if (c.moveToFirst())
{
do {
DisplayContact(c);
} while (c.moveToNext());
}
db.close();
}
public void DisplayContact(Cursor c)
{
Toast.makeText(this,
"id:" + c.getString(0) +"\n" +
"Name:" + c.getString(1) +"\n" +
"Email:" + c.getString(2),
Toast.LENGTH_LONG).show();
}
}
}

برنامه را با F11 اجرا   کنید با استفاده از  کلاس Toast  اطلاعت  تمام Contact ها  را نمایش می دهیم

دیتابیس در اندروید

توضیحات

متد  getAllContacts() تمام contact های  ذخیره   شده در دیتابیس   را بر می می گرداند  نتیجه یک  شی Cursor می باشد  برای   نمایش  تمام contact ها  شما  باید از  متد moveToFirst() استفاده  کنید  اگر  موفقیت آمیز  بود   یعنی  این که  حداقل  یک  سطر  وجود  دارد   سپس شما   جزئیات آن را با متد DisplayContact() نمایش میدهید

 

بازگردانی  فقط یک  contact   (یک  سطر)

باز گرداند یک contact  با  استفاده ID,  آن .

متد  getContact() در  کلاس DBAdapter این  کار  را  انجام  میدهید

فایل MainActiviy.java به  صورت  زیر  تغییر دهید


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBAdapter db = new DBAdapter(this);
/*
//---add a contact---
...
//--get all contacts---
...
db.close();
*/
//---get a contact---
db.open();
Cursor c = db.getContact(2);
if (c.moveToFirst())
DisplayContact(c);
else
Toast.makeText(this, “No contact found”, Toast.LENGTH_LONG).show();
db.close();
}

برنامه را   اجرا   کنید در  صورت  پیدا شدن  آن را   نمایش میدهید  در   غیر  این  صورت  پیغام  مناسب  نمایش داده می شود.

توضیحات

متد  getContact() یک  contact را   توسط  ID   بر می گرداند شما  ID ان را می دهید. که در اینجا  شما 2  را  دادید


Cursor c = db.getContact(2);

که در اینجا  یک شی Cursor  بر می گرداند که  توسط  متد DisplayContact()  جزئیات آن نمایش میدیم.

به  روز  رسانی Contact

برای  بروز  رسانی  یک contact   خاص از  متد updateContact()  در   کلاس DBAdapter استفاده می کنید  که   Id   را  دریافت  می کند

فایل DatabasesActivity.java  به صورت  زیر تغیر دهید


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBAdapter db = new DBAdapter(this);
/*
//---add a contact---
...
//--get all contacts---
...
//---get a contact---
...
db.close();
*/
//---update contact---
db.open();
if (db.updateContact(1, “Wei-Meng Lee”, “weimenglee@gmail.com”))
Toast.makeText(this, “Update successful.”, Toast.LENGTH_LONG).show();
else
Toast.makeText(this, “Update failed.”, Toast.LENGTH_LONG).show();
db.close();
}

برنامه را اجرا کنید در   صورت  موفقیت آمیز  بودن  به  روز  رسانی پیغام  مناسبی دریافت  می کنید

توضیحات

 متد   updateContact() در  کلاس DBAdapter جزئیات  contact را  به   روز  رسانی  می کند این  متد یک  مقدار Boolean را  بر می گرداند در   صورت  با  موفقیت  بودن True در  غیر  این صورت  False را بر می گرداند

حذف کردن contact

برای  حذف   کردن contact از  متد deleteContact() در  کلاس DBAdapter استفاده می کنید

که  ID را  دریافت  می  کند

 

فایل DatabasesActivity.java  به  صورت  زیر تغییر دهید

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBAdapter db = new DBAdapter(this);
/*
//---add a contact---
...
//--get all contacts---
...
//---get a contact---
...
//---update contact---
...
db.close();
*/
//---delete a contact---
db.open();
if (db.deleteContact(1))
Toast.makeText(this, “Delete successful.”, Toast.LENGTH_LONG).show();
else
Toast.makeText(this, “Delete failed.”, Toast.LENGTH_LONG).show();
db.close();
}

برنامه را  اجرا  کنید یک  پیغام  به منزله  کوفقیت آمیز  بودن  حذف نمایش میدهد

توضیحات

  متد  deleteContact() یک ID را دریافت  می  کندو بر  اساس آن  contact را   حذف می کند

 و یک  مقدار  Boolean  بر می گرداند

 

 

Upgrading کردن  دیتابیس

بعد از  ایجاد  و استفاده از   دیتابس  شما ممکن است  جداول  اضافه  کنید یا   ساختار  جدول  را  تغییر دهید  یا   ستون های را  به  جدول   اضافه  کنید

برای این  کار  شما   ثابت DATABASE_VERSION  به  مقدار   بالاتر   تغییر دهید به  عنوان  مثال در  اینجا از    1  به   2  تغییر دهید.


public class DBAdapter {
static final String KEY_ROWID = “_id”;
static final String KEY_NAME = “name”;
static final String KEY_EMAIL = “email”;
static final String TAG = “DBAdapter”;
static final String DATABASE_NAME = “MyDB”;
static final String DATABASE_TABLE = “contacts”;
static final int DATABASE_VERSION = 2;

قبل از  اجرای     دستور  Delete بالا را     غیر    فعال   کنید   در  غیر   این   صورت حذف  جدول   با   خطا   مواجه می شود

وقتی  برنامه را   اجرا  می  کنید شما  در پنجره  LogCat  پیغام  زیر  را   مشاهده می  کنید

DBAdapter(8705): Upgrading database from version 1 to 2, which
will destroy all old data

در  بالا شما  به   سادگی   جدول  دیتابیس  را  حذف  کردید و  جدول  جدیدی  در آن   اضافه  کردید.  ولی در   واقعیت شما   ابتدا   یک   Backup  ایجاد می کنید  سپس   جدول را حذف  می کنید.

ساخت   دیتابیس  از  قبل  و  بدون   نیاز به  کد  نویسی

در   واقعیت شما   جدول  را   قبل از  اجرای  برنامه   و  بون  نیاز   به  کد  نویسی  ایجاد  می کنید و این  کار بسیار  کارامد تر می باشد

 

برای ساخت   دیتابیس SQLite  از قبل یک   نرم  افزار  وجود دارد به نام SQLite Database Browser  که  این  کار  را  انجام میدهد. که شما  می  توانید آن را  از  آدرس زیر  دانلود  کنید

http://sourceforge.net/projects/sqlitebrowser/

 

زمانی که   SQLite Database Browser  را  نصب کردید   شما می توانید به   صورت  رابط  گرافیکی جدول Contact را  ایجاد  کنید

ابزار پایگاه داده  اندروید SqlitBrowser

رکورد های  هم می توانید  به  آن  اضافه  کنید

ابزار پایگاه داده  اندروید SqlitBrowser

قدم  بعدی  آن  است که ان را در  برنامه استفاده   کنید

 

به  پروژه  قبلی   بروید   و  دیتابیسی  که  ایجاد  کردید را در   فولدر assets  بکشید  و رها  کنید  (Drog and Drop).

ابزار پایگاه داده  اندروید SqlitBrowser

 

توجه  کنید   نام  فایل  باید   حتما  باید  با  حروف کوچک باشد

 

فایل DatabasesActivity.java به  صورت  زیر  تغییر  دهید


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.widget.Toast;
public class DatabasesActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DBAdapter db = new DBAdapter(this);
try {
String destPath = “/data/data/” + getPackageName() +
“/databases”;
File f = new File(destPath);
if (!f.exists()) {
f.mkdirs();
f.createNewFile();
//---copy the db from the assets folder into
// the databases folder---
CopyDB(getBaseContext().getAssets().open(“mydb”),
new FileOutputStream(destPath + “/MyDB”));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//---get all contacts---
db.open();
Cursor c = db.getAllContacts();
if (c.moveToFirst())
{
do {
DisplayContact(c);
} while (c.moveToNext());
}
db.close();
}
public void CopyDB(InputStream inputStream,
OutputStream outputStream) throws IOException {
//---copy 1K bytes at a time---
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}
public void DisplayContact(Cursor c)
{
Toast.makeText(this,
“id: “ + c.getString(0) + “\n” +
“Name: “ + c.getString(1) + “\n” +
“Email: “ + c.getString(2),
Toast.LENGTH_LONG).show();
}
}

برنامه را  اجرا  کنید  فایل mydb  به   مسیر /data/data/com.MehrdadJavididatabases/databases/ کپی می  شود

توضیحات

شما یک    متد  به نام CopyDB() ایجاد  کردید که  یک  دیتابیس را از  یک  مکان  به  مکان  دیگر  کپی  می  کند.


public void CopyDB(InputStream inputStream,
OutputStream outputStream) throws IOException {
//---copy 1K bytes at a time---
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
inputStream.close();
outputStream.close();
}

نکته این  است  که  شی InputStream  فایل  مبدا را می خواند. سپس با شی OutputStream  در  مقصد  می نویسید زمانی که  برنامه   اجرا  می  شود فایل  در    فولدر assets  به /data/data/com.MehrdadJavididatabases/databases/          کپی  می شود 

try {
String destPath = “/data/data/” + getPackageName() +
“/databases”;
File f = new File(destPath);
if (!f.exists()) {
f.mkdirs();
f.createNewFile();
//---copy the db from the assets folder into
// the databases folder---
CopyDB(getBaseContext().getAssets().open(“mydb”),
new FileOutputStream(destPath + “/MyDB”));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

هر  زمان که شما  بر نامه  را  اجرا  می کنید   دیتابیس در   پوشه  به  کپی می شود و  داده های   قبلی  حذف  می وشد  برای   جلوگیر ی از  ای ن  کار  دیتابیس  را   حذف  کنید

ابزار پایگاه داده  اندروید SqlitBrowser

نظرات (۰)

هيچ نظري هنوز ثبت نشده است
ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی