- آموزش برنامه نویسی Android قسمت اول: تاریخچه سیستم عامل اندروید
- آموزش برنامه نویسی Android قسمت دوم: آشنایی با اصطلاحات و نصب محیط توسعه
- آموزش برنامه نویسی Android قسمت سوم: اجرای اولین برنامه Hello World
- آموزش برنامه نویسی Android قسمت چهارم: شروع طراحی رابط کاربری
- آموزش برنامه نویسی Android قسمت پنجم: طراحی LinearLayout
- آموزش برنامه نویسی Android قسمت ششم: طراحی صفحه یک ماشین حساب
- آموزش برنامه نویسی Android قسمت هفتم: طراحی RelativeLayout
- آموزش برنامه نویسی Android قسمت هشتم: ساخت لیست با ListView
- آموزش برنامه نویسی Android قسمت نهم: شروع آموزش زبان Java
- آموزش برنامه نویسی Android قسمت دهم: محاسبات ریاضی و شرط ها
- آموزش برنامه نویسی Android قسمت یازدهم: حلقه ها و آرایه ها
- آموزش برنامه نویسی Android قسمت دوازدهم: شی گرایی بخش اول
- آموزش برنامه نویسی Android قسمت سیزدهم: شی گرایی بخش دوم
- آموزش برنامه نویسی Android قسمت چهاردهم: پروژه نرم افزار مبدل واحد
- آموزش برنامه نویسی Android قسمت پانزدهم: Activity ها را بیشتر بشناسید
- آموزش برنامه نویسی Android قسمت شانزدهم: چرخه حیات اکتیویتی
- آموزش برنامه نویسی Android قسمت هفدهم: Fragment ها
- آموزش برنامه نویسی Android قسمت هجدهم: ساختار داده ها و Data Model ها
- آموزش برنامه نویسی Android قسمت نوزدهم: Shared Preferences
- آموزش برنامه نویسی Android قسمت بیستم: ارتباط با سرور برای دریافت اطلاعات بخش اول
- آموزش برنامه نویسی Android قسمت بیست و یکم: ارتباط با سرور برای دریافت اطلاعات بخش دوم
- آموزش برنامه نویسی Android قسمت بیست و دوم: ارسال اطلاعات به سرور
- آموزش برنامه نویسی Android قسمت بیست و سوم: اندروید و پایگاه داده بخش اول
- آموزش برنامه نویسی Android قسمت بیست و چهارم: اندروید و پایگاه داده بخش دوم
- آموزش برنامه نویسی Android قسمت بیست و پنجم: BroadcastReceiver
در این قسمت قصد داریم برنامه اندرویدی خود را به پایگاه داده SQLite مجهز کنیم.برخی برنامههایی که برای گوشیهای همراه ایجاد میشوند دارای اطلاعات گستردهای هستند که باید با نظم خاصی به نمایش در بیایند، به همین دلیل ناگزیر به استفاده از پایگاه داده هستیم.
اگر با پایگاه داده آشنا نیستید مطلب پایگاه داده چیست را از دست ندهید.
سیستم دیتابیس پیشفرض اندروید SQLite است، هر چند سیستمهای دیگری نیز وجود دارند ولی استفاده از SQLite از سوی گوگل توصیه شده است.
مطلب آشنایی با پایگاه داده SQLite
دیتابیس را به دو روش در اندروید استفاده میکنند:
- ایجاد دیتابیس هنگام اولین اجرای نرم افزار، و دریافت اطلاعات از سمت سرور و یا کاربر و ذخیره آنها درون دیتابیس تازه ایجاد شده.
- استفاده از دیتابیس پیش ساخته و انتقال آن به پوشه نرم افزار و استفاده از اطلاعات آن.
روش اول: در روش اول دیتابیس در اولین اجرای نرم افزار ایجاد میشود و اطلاعات به تدریج در آن قرار میگیرد. فرض کنید یک اپلیکیشن شعر دارید، وقتی کاربر به اینترنت متصل باشد اطلاعات شعرها دریافت میگردد و در اتصالهای بعدی به اینترنت بررسی میشود که شعر جدیدی وجود دارد یا خیر. در صورت موجود بودن شعرهای جدید نیز به پایگاه داده افزوده میشوند.
روش دوم: یک دیتابیس در کامپیوتر خود ایجاد کرده و در پوشه Assets پروژه اندروید قرار میدهیم. در اولین اجرای نرم افزار این دیتابیس را به پوشه مخصوص نرم افزار منتقل کرده و در دفعات بعدی از آن استفاده میکنیم. در این روش نیز میتوان دیتابیس را در دفعات بعدی اجرا از سمت اینترنت بروز رسانی کرد.
ایجاد یک دیتابیس هنگام اجرای نرم افزار
در ادامه قصد داریم با توجه به آموزشهای قسمتهای قبل اطلاعات را از اینترنت دریافت و با استفاده از دیتا مدل Posts دیتابیس را مقدار دهی کنیم.
دیتا مدل Posts را در پکیج ir.hitos.models
به شرح زیر ایجاد میکنیم:
package ir.hitos.models;
public class Posts {
private int id;
private String title;
private String intro;
private String fullPost;
private String date;
private String image;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getIntro() {
return intro;
}
public void setIntro(String intro) {
this.intro = intro;
}
public String getFullPost() {
return fullPost;
}
public void setFullPost(String fullPost) {
this.fullPost = fullPost;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
روی نام پکیج اصلی نرم افزار یعنی ir.hitos.hitos
راست کلیک کرده و روی New و از آن Java Class کلیک کنید. یک کلاس با نام HitosSQLiteOpenHelper ایجاد میکنیم، و درون آن اطلاعات زیر را قرار میدهیم:
package ir.hitos.hitos;
import android.database.sqlite.SQLiteOpenHelper;
public class HitosSQLiteOpenHelper extends SQLiteOpenHelper{
}
همانطور که در بالا میبینید HitosSQLiteOpenHelper در واقع extends شده از SQLiteOpenHelper است.
SQLiteOpenHelper یک کلاس بسیار ضروری است که حجم بالایی از عملیات ایجاد و بروز رسانی پایگاه داده را بر عهده میگیرد. سعی بر آن است که کلیه عملیات درج اطلاعات و فراخوانی و ویرایش آنها را در این کلاس با ایجاد متدهای مربوطه انجام دهیم.
اگر مثال فوق را در اندروید استودیو ببینید زیر نام کلاس یک خط قرمز کشیده میشود، روی نام کلاس کلیک کرده و Alt + Enter را فشار دهید. از لیست نمایش داده شده Implement methods را انتخاب کنید تا متدهای ضروری کلاس SQLiteOpenHelper به کلاس شما افزوده شوند.
دو متد به کلاس جاری افزوده میشود که به شرح زیر هستند:
متد onCreate: این متد زمانی اجرا میشود که پایگاه داده برای اولین بار در حال ایجاد شدن است. این متد به صورت خودکار فراخوانی خواهد شد.
متد onUpgrade: وقتی یک نرم افزار را برای اولین بار در گوشی نصب میکنید طبیعتا دیتابیس نیازی به بروز شدن و استفاده از متد onUpgrade ندارد. حال فرض کنید نرم افزار در گوشی شما موجود است و شما قصد دارید نرم افزار خود را بروز رسانی کنید، و نرم افزار بروز رسانی شده شامل تغییراتی در پایگاه داده باشد. در این حالت متد onUpgrade با توجه به ورژن پایگاه داده (در ادامه معرفی میشود) پایگاه داده قبلی را متناسب با بروز رسانی نرم افزار برای شما ویرایش میکند.
اگر دقت کرده باشید هنوز زیر نام کلاس خط قرمز موجود است که دوباره Alt + Enter را کلیک کرده و Creat Constructors matching super را انتخاب و پنجره باز شده را تایید کنید. یک متد سازنده همنام با نام کلاس شما ایجاد میشود. سورس پیشفرض این سازنده به شرح زیر است: سازنده این کلاس چهار ورودی دارد که در زیر آنها را شرح میدهیم:
public HitosSQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
context: با استفاده از contextها امکان استفاده از Resourceها را پیدا میکنیم.
name: نام پایگاه داده را باید اینجا وارد کنیم، بنابراین میتوانید نام پایگاه داده را برای این ورودی از نوع String وارد کنید.
factory: از این ورودی برای انجام عملیات پیش فرض هنگام هر بار فراخوانی پایگاه داده استفاده میکنند که ما آن را به null تبدیل میکنیم.
version: ورژن فعلی پایگاه داده نرم افزار را در این بخش وارد میکنیم، تا در آینده بروز رسانی پایگاه داده را بوسیله آن بتوانیم انجام دهیم. ورودی این ورودی به صورت int است.
در نهایت پس از ویرایش مقادیر ورودیهای سازنده، آن را به صورت زیر ویرایش میکنیم:
Context context;
public HitosSQLiteOpenHelper(Context context) {
super(context, "Hitos_DB.sqlite", null, 1);
this.context= context;
}
در اولین سطر متغیر context را از نوع Context میسازیم تا بتوانیم در همه جای کلاس از آن استفاده کنیم. با استفاده از سازنده و وردی آن و دستور this.context قصد داریم به هنگام صدا زدن کلاس HitosSQLiteOpenHelper مقدار context را از Activity برنامه به کلاس HitosSQLiteOpenHelper نسبت دهیم.
متد onCreate را برای ایجاد پایگاه داده در نرم افزار به شکل زیر ویرایش میکنیم:
@Override
public void onCreate(SQLiteDatabase db) {
try{
db.execSQL("CREATE TABLE IF NOT EXISTS POSTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, TITLE TEXT, CONTENT TEXT);");
}catch (SQLException e){
Log.e("SQLite Exception", "onCreate" + e.toString() );
}
}
در سطر سه تا هفت یک try catch برای عملیات ایجاد جدول پایگاه داده ایجاد میکنیم. همانطور که میدانید try catch برای جلوگیری کردن از کرش نرم افزار در صورت ایجاد مشکل استفاده میشود.
در سطر چهار متد db.execSQL دستورات SQL را اجرا میکند. در این دستور قصد داریم یک جدول با نام POSTS به پایگاه داده خود اضافه کنیم. اگر با ساختار دستورات SQL آشنا نیستید میتوانید به آموزشهای SQL مراجعه کنید. به صورت خلاصه این دستور را تشریح میکنیم:
- CREATE TABLE IF NOT EXISTS POSTS: این بخش بررسی میکند اگر در پایگاه داده ما جدول با نام POSTS موجود نبود آن را ایجاد کند.
- ID INTEGER PRIMARY KEY AUTOINCREMENT: یک شناسه با نام ID و از نوع INTEGER و به صورت کاملا یکتا (PRIMARY KEY) و به صورت افزایشی خودکار (AUTOINCREMENT) ایجاد میشود. این شناسه در واقع یک ستون از جدول را تشکیل میدهد.
- TITLE TEXT: یک ستون از نوع TEXT یا نوشته و با نام TITLE
- CONTENT TEXT: یک ستون از نوع TEXT یا نوشته و با نام CONTENT
در سطر شش e.toString()
منجر به چاپ خطا در Logهای نرم افزار میشود.
از آن جایی که کلاس HitosSQLiteOpenHelper باید شامل تمام متدهایی ذخیره سازی اطلاعات باشد، یک متد جدید به نام savePosts ایجاد میکنیم، که سورس آن به شرح زیر است:
public Boolean savePosts(List<Posts> posts){
SQLiteDatabase sqLiteDatabase=this.getWritableDatabase();
for (int i = 0; i < posts.size(); i++){
ContentValues cv=new ContentValues();
cv.put("title",posts.get(i).getTitle());
cv.put("intro",posts.get(i).getIntro());
cv.put("fullPost",posts.get(i).getFullPost());
cv.put("date",posts.get(i).getDate());
cv.put("image",posts.get(i).getImage());
long isInserted=sqLiteDatabase.insert("POSTS" , null, cv);
if(isInserted > 0){
Log.i("Insert_DB", "Post Id: "+isInserted);
}else{
Log.i("Insert_DB", "Error!");
}
}
return true;
}
سطر 1: این متد خروجی Boolean دارد و ورودیهایی از جنس لیستی از Postsها دریافت میکند.
سطر 10: یک شی به نام sqLiteDatabase از روی کلاس SQLiteDatabase ایجاد میکنیم. getWritableDatabase()
مجوز نوشتن روی دیتابیس را برای ما صادر میکند، اگر در جایی قصد خواندن اطلاعات از دیتابیس را داشتیم باید از getReadableDatabase()
استفاده کنیم.
سطر 3: حلقهای برای پردازش کل Postsها ایجاد میکنیم.
سطر 4: با استفاده از کلاس ContentValues میتوان اطلاعات را درون پایگاه داده ذخیره کرد.
سطرهای 5 تا 9: با متد put و نام ستون اطلاعات را از posts درون پایگاه داده ذخیره میکنیم.
سطر 11: با دستور sqLiteDatabase.insert اطلاعات پایگاه داده را ذخیره میکنیم. متد insert سه ورودی دارد، که اولی نام جدول پایگاه داده، دوم مشخص میکند که اگر به هر دلیل ContentValues خالی بود متد insert چه چیزی را ذخیره کند و ورودی سوم مقادیر درون ContentValues است.
همانطور که میبینید نتیجه اجرای دستور sqLiteDatabase.insert درون یک متغیر از نوع long با نام isInserted ذخیره میشود. خروجی این دستور که در isInserted ذخیره میشود شماره id آیتم ذخیره شده در پایگاه داده است.
سطر 13 تا 17: این سطرها بررسی میکنند که اگر isInserted بزرگتر از صفر بود یعنی یک آیتم در پایگاه داده با موفقیت ثبت شده است و یک Log با نام Insert_DB برای شما ذخیره میکند. اگر نتیجه isInserted بزرگتر از صفر نبود یعنی خطایی پیش آمده و یک Log خطا برای شما ثبت میشود.
کلاس APIGettingPosts را که در قسمتهای قبلی ایجاد کردیم این جا نیز ایجاد میکنیم:
public class APIGettingPosts {
private Context context;
public APIGettingPosts(Context context) {
this.context = context;
}
public void getPost(final OnPostsReceived onPostsReceived) {
JsonArrayRequest request = new JsonArrayRequest(
Request.Method.GET,
"http://192.168.1.2/getposts.php",
null,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
onPostsReceived.onReceived(ParsingPostJSON(response));
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.i("Get_Error: ", error.toString());
onPostsReceived.onReceived(null);
}
});
request.setRetryPolicy(new DefaultRetryPolicy(8000, 1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
RequestQueue requestQueue = Volley.newRequestQueue(context);
requestQueue.add(request);
}
private List<Posts> ParsingPostJSON(JSONArray response) {
try {
List<Posts> posts = new ArrayList<>();
for (int i = 0; i < response.length(); i++) {
JSONArray postArray = response.getJSONArray(i);
Posts post = new Posts();
post.setTitle(postArray.getString(0));
post.setIntro(postArray.getString(1));
post.setDate(postArray.getString(2));
post.setImage(postArray.getString(3));
posts.add(post);
}
return posts;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
public interface OnPostsReceived {
void onReceived(List<Posts> posts);
}
}
سطر 12: آی پی سیستم شما قرار گرفته است.
توضیحات دیگر این کلاس در قسمتهای قبل موجود است.
کلاس MainActivity را به شرح زیر ویرایش میکنیم:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
APIGettingPosts apiGettingPosts = new APIGettingPosts(this);
apiGettingPosts.getPost(new APIGettingPosts.OnPostsReceived() {
@Override
public void onReceived(List<Posts> posts) {
if (posts == null || posts.isEmpty()){
Toast.makeText(MainActivity.this, "خطا در دریافت اطلاعات", Toast.LENGTH_SHORT).show();
} else {
HitosSQLiteOpenHelper openHelper = new HitosSQLiteOpenHelper(MainActivity.this);
openHelper.savePosts(posts);
Toast.makeText(MainActivity.this, "اطلاعات با موفقیت دریافت و درون پایگاه داده ذخیره شدند", Toast.LENGTH_SHORT).show();
}
}
});
}
این کدها نیز در قسمتهای قبل کاملا تفسیر شده اند.
در سطر 12 شی openHelper را از کلاس HitosSQLiteOpenHelper ایجاد کرده و در سطر 13 متد savePosts را با ورودی posts دریافت شده از سرور صدا زدیم.
اگر به برگه Android Monitor مراجعه کنید خواهید دید در صورت درست بودن سورسها و ارتباط صحیح با سرور شناسه کل اطلاعات ذخیره شده برای شما نمایان خواهد شد.
استخراج پایگاه داده SQlite و مشاهده در کامپیوتر
گاهی نیاز است پایگاه داده اندروید را استخراج و در سیستم خود مشاهده و ویرایش کنید. برای این کار پس از اجرا کردن ماشین مجازی خود از منو Tools اندروید استودیو گزینه Android و از آن Android Device Monitor را انتخاب کنید.
از منو سمت چپ روی نام ماشین مجازی خود کلیک کرده و از برگه File Explorer سمت راست مسیر data و سپس دوباره data را باز کنید.
در مسیر جاری نام پکیج برنامه خود را یافته و از پوشه databases نام پوشه پایگاه داده خود را ببینید.
روی پایگاه داده خود کلیک کرده و از برگه بالای این بخش روی آیکون کوچکی که در تصویر زیر میبینید کلیک کنید تا دیتابیس در دستگاه شما save شود:
حال میتوان این پایگاه داده را در نرم افزاری به نام DB Browser for SQLite باز کرده و محتویات درون آن را دید.
لینک دانلود این نرم افزار:
دانلود نسخه مخصوص سیستم مکینتاش
به سادگی این نرم افزار را میتوان نصب و اجرا کرد. به محض باز کردن این نرم افزار از منو File گزینه Open Detabase را کلیک و دیتابیس را وارد نرم افزار کنید.
تگ ها: android / اندرویددیتابیس و پایگاه دادهandroid studio
متشکرم
مطلب بسیار زیبا و کاملی بود.
بسیار کامل و فلسفی که تمامی خط ها توضیح داده شده بود امید وارم موفق باشید .
و کارتون رو ادامه بدین.
ممنون از لطفتون