فصل سوم : ساخت پروژه در اندروید استودیو، بررسی محیط توسعه و ساختار کلی پروژه

به نام خدا. در این جلسه قصد دارم شما را با محیط اندروید استودیو، ساخت پروژه اندروید و ساختار آن آشنا کنم.

ساخت پروژه اندروید

پنجره اصلی اندروید استودیو

در جلسه قبل با این پنجره آشنا شدیم. ساخت پروژه را آغاز می کنم.

ساخت پروژه اندروید

فیلد Application name مربوط به نام اپلیکیشن است که من نام MyShop را در نظر گرفتم. این نام به همراه آیکون اپلیکیشن به کاربر نمایش داده می شود.
Company domain: اپلیکیشن های شما و سایر توسعه دهندگان اندروید در اپ استورهایی مانند گوگل پلی ، بازار و … بر اساس Package name آنها تشخیص داده و تفکیک می شوند و نام اپلیکیشن ملاک نیست (به عنوان مثال ممکن است چندین اپلیکیشن با نام Shop در مارکتها موجود باشد). دلیل این است تا در هنگام بروزرسانی اپلیکیشن ها توسط کاربر، تداخل بین چند اپلیکیشن بوجود نیاید و اپ استور بتواند برنامه های نصب شده روی دیوایس کاربر را از یکدیگر تشخیص بدهد. به عنوان مثال من در قسمت Company domain ، عبارت android-studio.ir را وارد می کنم. مشاهده می کنید که در قسمت نام پکیج، عبارت ir.android_studio.myshop قید شده. مزیت دامین در این است که اپلیکیشن های توسعه داده شده هر فرد یا شرکت، یک Package name مختص خود را خواهد داشت. اما به این معنا نیست که الزاما باید یک دامین حقیقی با مالیکت خودتان داشته باشید. می توانید یک دامین دلخواه وارد کنید (البته استفاده از دامینی که در اختیار شخص یا شرکت دیگری است مسلما گزینه مناسبی نیست!). در قسمت Project Location مسیر ذخیره پروژه را مشخص کرده، به مرحله بعد می روم.

Minimum SDK & Target SDK

در این مرحله چندین گزینه در اختیار داریم. گزینه Phone and Tablet برای توسعه اپلیکیشن های تلفن همراه و تبلت ، Wear برای اپلیکیشن گجت های پوشیدنی که از سیستم عامل Android Wear استفاده می کنند (مانند ساعت های هوشمند)، TV که برای اپلیکیشن های تلویزیون های هوشمند اندرویدی بکار می رود و Android Auto که برای ساخت اپلیکیشن برای اتومبیل های با سیستم اندروید استفاده می شود.
با توجه به اینکه هدف من ساخت اپلیکیشن برای موبایل و تبلت هست، گزینه اول را انتخاب می کنم.بعد از این انتخاب، باید Minimum SDK پروژه ام را تعیین کنم. واژه Minimum به معنی حداقل بوده و در اینجا به این معنی است که باید تعیین کنم اپلیکیشن من پایین ترین نسخه اندرویدی که پشتیبانی خواهد کرد کدام API است. به عنوان مثال اگر API 10 (Android 2.3.3) را انتخاب کنم، اپلیکیشن روی نسخه های پایین تر از ۲٫۳٫۳ امکان نصب را نخواهد داشت. علت الزامی بودن تعیین مینیمم هم این است که در هر نسخه جدید از اندروید، امکانات و قابلیتهایی اضافه می شود که اگر این امر را لحاظ نکنیم، ممکن است دارندگان دیوایس با نسخه های پایین تر در مواردی با مشکلاتی مواجه شوند. با انتخاب هر گزینه به عنوان مینیمم، اطلاعاتی در مورد آن API و سطح گستردگی آن نمایش داده می شود. در زمان نگارش این متن، API 10 حدودا ۱۰۰% دیوایس های اندرویدی را پوشش می دهد و نیازی نیست از API پایینتری استفاده کنم. با کلیک روی گزینه Help me choose به نمودار کاملی در این خصوص دسترسی خواهید داشت.
نکته: در فصل قبل با SDK و همچنین Platform ها آشنا شدیم و دانستیم که با انتشار هر نسخه از اندروید، API آن نیز منتشر می شود. هر پروژه اندرویدی در سه ویژگی compileSdkVersion، targetSdkVersion و minSdkVersion با Platform ها سروکار دارد. در حالت عادی هنگامی که پروژه جدیدی می سازیم دو ویژگی اول یعنی کامپایل و نسخه هدف (Target) آخرین API نصب شده و ویژگی Minimum همان API ای است که در این مرحله انتخاب می کنیم. بنابراین لازم است همواره آخرین API منتشر شده و همچنین API ای که قصد داریم به عنوان Minimum انتخاب کنیم را نصب داشته باشیم. البته در تعدادی از منابع عنوان شده داشتن API مرتبط با MinimumSDK الزامی نیست، با این حال تا لحظه نگارش این مبحث من به نتیجه قطعی نرسیده ام لذا جانب احتیاط را رعایت می کنم.

انتخاب Activity

اپلیکیشن ها از تعدادی Activity تشکیل شده اند که کاربر محتویات را در قالب این اکتیویتی ها مشاهده کرده و با آنها تعامل دارد. من ساده ترین اکتیویتی یعنی Empty Activity را انتخاب می کنم.

نامگذاری اکتیویتی

هر اکتیویتی از دو بخش “کدهای جاوا” و “رابط کاربری یا Layout (لایه ظاهری)” تشکیل شده است که برای هرکدام باید نام جداگانه ای درنظر گرفت. اکتیویتی که در مرحله قبل انتخاب کردم را در این مرحله می بایست نامگذاری کنم که اندروید استودیو به صورت پیش فرض نامهایی تعیین کرده و نیازی به تغییر ندارد. MainActivity نام فایل مربوط به کدهای جاوا و Layout Name نیز مربوط به لایه ظاهری اکتیویتی است.

بیلد شدن پروژه

حالا منتظر می مانم تا پروژه بیلد (Build) شود. با توجه به سخت افزار سیستم ممکن است این مرحله چند ثانیه تا یک دقیقه یا بیشتر زمان ببرد (ضمن اینکه عموما در ساخت اولین پروژه این مرحله اندکی طولانی تر می شود).
در حین این پروسه با واژه Gradle برخورد می کنیم. بد نیست اطلاعات مختصری در خصوص گریدل بدانیم. به یاد داشته باشید یک برنامه نویس و توسعه دهنده باید فراتر از الزامات مربوط به زبان برنامه نویسی و مباحث فنی بکار رفته در روند توسعه نرم افزار اطلاعات داشته باشد. این یک امتیاز منفی برای شما محسوب خواهد شد اگر شما را به عنوان یک توسعه دهنده اندروید بشناسند اما به عنوان مثال ندانید لینوکس چیست که اندروید بر پایه آن ساخته شده، یا گریدل که در محیط اندروید استودیو بکار رفته چه کاربردی دارد!
گریدل یک بیلد سیستم (Build System) متن باز است که به زبان Groovy نوشته شده و گوگل در سال ۲۰۱۳ اعلام کرد که از این بیلد سیستم برای کامپایل کدها در اندروید استودیو استفاده می کند.
بهتر است به چند خط توضیح بنده کفایت نکرده و چند دقیقه ای را در خصوص گریدل در وب مطالعه کنید.
نکته: ممکن است در انتهای بیلد شدن پروژه ارور یا ارورهایی (عموما مربوط به عدم امکان نصب تعدادی کتابخانه مورد نیاز پروژه) دریافت کنید (به خصوص در ساخت اولین پروژه ها) که از ارائه توضیحات در اینجا اجتناب نموده و شما را به صفحه مشکلات و پرسش های رایج ارجاع می دهم:
باید عادت کنید تا پرسیدن مستقیم مشکلات و مسائلی که در حین ساخت و توسعه پروژه با آنها برخورد می کنید، مرحله آخر باشد. تقریبا ۹۹% مشکلات شما، قبلا مشکل افراد دیگری هم بوده که آن را در فروم ها و وب سایتهایی از جمله stackoverflow.com عنوان کرده و افراد دیگری هم پاسخ یا پاسخهایی ارائه داده اند. لذا با مراجعه به صفحاتی مشابه صفحه پرسش های رایج وب سایت ما و در ادامه آن جستجوی خطاهای دریافتی در گوگل، در اکثر مواقع به پاسخهای جامع و کاملی می رسید که نیاز شما به پرسش از افراد و منتظر ماندن برای دریافت پاسخ بی نیاز می کند. تعداد زیادی از سوالاتی که کاربران از من می پرسند را به تاپیک های مرتبط با آن موضوع در stackoverflow.com ارجاع می دهم. تاپیکهایی که چندین نفر در آن راهکار و توضیحات خود را ارائه داده و در انتها کاربر به پاسخ جامع و کاملی می رسد.

بیلد شدن پروژه

در نهایت پروژه با موفقیت ساخته شد و دو فایل MainActivity.java و activity_main.xml که مربوط به اکتیویتی هستند به صورت باز شده نمایش داده شده است. توصیه می کنم چند دقیقه ای را در رابطه با xml در وب مطالعه کنید.

محیط توسعه اندروید

میانبرها

دکمه های بالا میانبرهایی هستند که تا این جلسه به بررسی آنها پرداخته ایم.
شماره ۱: اجرا (Run) کردن پروژه روی دیوایس مجازی یا حقیقی
شماره ۲: در نسخه ۲ قابلیت Instant Run به اندروید استودیو اضافه شد. تفاوت این ویژگی با Run در این است که در هنگامی که پروژه در حال Run هست و تغییراتی را اعمال کرده اید، با استفاده از این گزینه فقط تغییرات بر روی دیوایس اعمال شده و نیازی به اجرای دوباره و کامل پروژه نیست که در نتیجه مدت زمان این پروسه کاهش می یابد.
شماره ۳: شبیه ساز پیش فرض اندروید (AVD)
شماره ۴: برای Sync (سینک یا همگام سازی) کردن پروژه بکار می رود
شماره ۵: دسترسی به SDK Manager
منوها و همچنین سایر گزینه ها در جلسات آتی معرفی می شود.
ساختار پروژه را بررسی می کنیم.

ساختار پروژه اندرویدی

در زیرمجموعه java دو پوشه قرار دارد که عبارت (androidTest) و (test) در مقابلشان ذکر شده. من به اینها نیازی ندارم و برای خلوت شدن محیط کار، هردو را حذف می کنم (در مرتبه اول delete فقط محتویات درون پوشه ها حذف شده و خود پوشه باقی می ماند که با انتخاب و حذف مجدد، کاملا حذف می شود):

ساختار پروژه اندرویدی

در سمت چپ محیط برنامه نویسی، فولدر app را با زیرشاخه های manifests، java و res مشاهده می کنید. (برای باز کردن فایلها کافیست روی آنها دابل کلیک شود).
Manifest : اطلاعات ضروری و پایه هر اپلیکیشن در داخل این فایل ذخیره می شود.

AndroidManifest

به عنوان مثال اطلاعاتی که در ابتدای کار قابل مشاهده هست، نام پکیجی که موقع ساخت پروژه تعریف کردیم (لاین ۳) ، آیکون اپلیکیشین (لاین ۷) ، نام اپلیکیشن (لاین ۸) ، اکتیویتی تعریف شده در ابتدای کار و … .
Java: کلاس های جاوا در این پوشه قرار می گیرند.
res: این دایرکتوری شامل منابع مختلفی می باشد:
– Drawable: شامل تصاویر مورد استفاده در اپلیکیشن ، برخی فایل های xml مانند بیت مپ ها و … که از طریق کلاس R.drawable قابل دسترسی هستند.
– Layout: که شامل لایه های طراحی واسط کاربری هست (مانند activity_main.xml) که از طریق کلاس R.layout قابل دسترسی می باشند.
– mipmap: تصاویر مربوط به آیکون اپلیکیشن در این پوشه قرار می گیرد.
– Values: فایل های xml با محتوای آرایه ها (strings.xml) ، استایل ها (styles.xml) ، رنگ ها (colors.xml) ، ابعاد (dimens.xml) و … در این دایرکتوری قرار می گیرند.

build.gradle

در نهایت دو فایل build.gradle را معرفی می کنم.
فایل اول که در مقابل آن Project نوشته شده مربوط به تنظیمات کلی پروژه بوده و معمولا کاری با آن نداریم. Jcenter() مخزنی است (آنلاین) که کتابخانه های مورد نیاز پروژه از آن دریافت می شود.
فایل دوم (Module: app) شامل تنظیمات و اطلاعات اصلی اپلیکیشن است:

build.gradle

جزئیات مربوط به این فایل در مباحث آتی بیان خواهد شد.

دانلود فایل آموزشی با فرمت PDF
تعداد صفحات : ۱۴
حجم : ۱ مگابایت
قیمت : رایگان

سوالاتی که مشمول موارد زیر باشد تایید و پاسخ داده نخواهد شد :
۱ : جزء موارد پاسخ داده شده در مطلب "مشکلات و پرسش های رایج" باشد
۲ : سوال قبلا توسط افراد در دیدگاهها مطرح و پاسخ داده شده باشد
۳ : سوال خارج از مبحث آموزشی موجود در این صفحه باشد
  • محسن گفت:

    سلام
    خداییش اگه کسی بلده راهنمایی کنه
    برنامه من همش این خطا رو میده چیکار کنم
    Could not find baseLibrary.jar (com.android.databinding:baseLibrary:3.1.3).
    Searched in the following locations:
    https://dl.google.com/dl/android/maven2/com/android/databinding/baseLibrary/3.1.3/baseLibrary-3.1.3.jar

  • الهام گفت:

    سلام..ممنون از توضیحات کامل و واضحتون..موفق باشید

  • دانلود سریال 2018 گفت:

    سلام.ممنون .خیلی خوب بود.از دست اندرکاران
    وبسایت به این خوبی سپاسگزارم

  • معین گفت:

    سلام ببخشید اندروید استدیوی من بعداز ساخت پروژه درپایین این پیغامو میده:Gradle sync failed: Could not find builder.jar (com.android.tools.build:builder:3.1.1)ودربالا هم در یک کادر زرد رنگ اینو مینویسه : gradle project sync failed.basic functionality (e.g. editing ,debugging) will not work properly

    1. سید مهدی مطهری (مدیر) گفت:

      یه بار پروژه رو ReBuild کنید شاید درست شد

  • علی گفت:

    با سلام و تشکر از زحمات شما
    وقتی گریدل رو سینک می‌کنم در پایان خطای زیر را می‌دهد. در نت سرچ کردم چیزی ندیدم. ممنون می‌شم کمک کنید.
    could not download support-fragment.aar

    1. سید مهدی مطهری (مدیر) گفت:

      مطلب پرسش های رایج (تغییر آی پی)

  • berna.ir گفت:

    اقا لینک مطلبو من پیدا نکردم.میشه راهنماییم کنید؟

    1. سید مهدی مطهری (مدیر) گفت:

      کدوم مطلب؟

  • دانلود رایگان سریال گفت:

    سلام.واقعا وبسایت خوبی دارید

  • میلاد گفت:

    سلام
    ممنون از اطلاعات
    من یک تازه کار هستم و همین ابتدای کار به مشکل برخوردم
    من ورژن جدید انروید استادیو رو زدم ولی الان از قسمت NEW نمیتونم گزینه Activity رو پیدا کنم.
    اصلا در این قسمت هیچ کدام از گزینه های دارای آیکون سبز نیست.
    به نظر شما چیکار باید کنم ؟
    البته چند باری پاک و دوباره نصب کردم وحتی ورژن دیگه ای رو زدم ولی تاثیری نداره.

    1. سید مهدی مطهری (مدیر) گفت:

      دقت کنید کجا راست کلیک میکنید. مثلا روی layout راست کلیک کنید خب New Activity نمیاره دیگه

  • مریم گفت:

    با سلام خدمت شما جناب مطهری
    ممنون از وقتی که میزارید و اموزشهای خوب و کاملی رو قرار دادید و واقعا همه چیز رو توضیح دادید. من هنوز از اموزشهای پولی تون استفاده نکردم ولی قطعا کامل هستند. و ممنون بخاطر زحمتی که میکشید و اپدیتهارو اینجا مرتب میگزارید.
    دوست عزیز من طبق اموزشهای شما تقریبا امدم جلو و نصب هامو هم اپدیت کردم با سرور گوگل. اما حالا وقتی یه پروژه ساختم نمای گرافیکی xml بمن نشان داده نمیشهو خطایی که بالای صفحه میگیره اینه gradel project sunc faile.
    , ودر قسمت پیامها چندتا پیام خطا هست که دوسه تاش مربوط یه اینه
    unable to resolve dependency for ‘:app@debug/compileClasspath’: Could not resolve com.android.support:appcompat-v7:26.1.0.
    من همه جارو چک کردم، سایت اورفلو رو رفتم روشهاشون رو رفتم، حتی یه پیشنهاد داشت خود gradle که یه فولدر جدید میساختی و مسیر جدید میدادی و بعد تو قسمت environmet باید مسیری که بود رو عوض میکردی، حتی دانلود های جدید کردم اما مشکلم حل نمیشه. من با قندشکن هم وصل میشم و ادرس پروکسی بهش دادم راحت sdkاپدیت میشه ولی ظاهرا gradleنمیتونه به نت وصل بشه و سینگرون بشه.اگر بتونید کمکم کنید بسیارممنون خواهم شد.
    در ضمن من وقتی genymotion رو نصب کردم نصبش کامل شده اما ایکونش رو نوار استدیو نمیاد، راه حا انم نمیدونم،و و نمیدونم آیا اینها بهم ربطی دارند؟؟

    1. سید مهدی مطهری (مدیر) گفت:

      – یا IP رو تغییر بدید و مجدد سینک کنید تا appcompat ای که تو ارور هم ورژنش مشخصه رو از سرور دانلود کنه یا طبق آموزش زیر از ورژن موجود در SDK استفاده کنید:
      https://android-studio.ir/style-and-material-theme-in-android

  • m گفت:

    با سلام. من وقتی در نسخه ۳٫۰ اندروید میخواهم پروژه جدید ایجاد کنم، موقعی که میخواهم نسخه API را انتخاب کنم، برای تمام نسخه هایی که انتخاب میکنم (حتی نسخه های پایین) می گوید که این نسخه کمتر از ۱% دستگاه ها را پوشش می دهد.در صورتی که در ورژه قبلی اندروید، درصد واقعی را نشان میداد و مثلا میگفت ۹۸% پوشش دارد. میخواستم ببینم که مشکل از کجاست؟ و چرا اینطور میشه؟ چه راهی برای رفع این مشکل پیشنهاد میکنید؟ با تشکر

    1. سید مهدی مطهری (مدیر) گفت:

      البته این چیزی نیست که مشکلساز باشه و بخواید دنبال رفعش باشید. عددی که نشون میده صرفا جهت اطلاعه. فکر میکنم در نسخه ۳، آمار رو از سرور میگیره که وقتی با آی پی ایران متصل باشید درصدها رو ۱ میزنه

      1. m گفت:

        ممنون. یعنی بعدا مشکلی در جای دیگه و در اجرای برنامه ایجاد نمیشه؟ و فقط چون اینجا به سرور وصل نیست، مینویسه؟

        1. سید مهدی مطهری (مدیر) گفت:

          بزرگوار توضیحات کامنت قبلی بنده واضح بود. اینکه سوال رو دوباره بپرسید و منتظر پاسخ مجدد باشید وقت خودتونو میگیره فقط

  • mahdi گفت:

    سلام وقت بخیر ،من با درست کردن پروژه با این ارور مواجه میشم که نمیدونم چیکارش کنم.
    Error:Failed to open zip file.
    Gradle’s dependency cache may be corrupt (this sometimes occurs after a network connection timeout.)
    Re-download dependencies and sync project (requires network)
    Re-download dependencies and sync project (requires network)
    خطا: فایل زیپ باز نشد
    حافظه وابستگی Gradle ممکن است فاسد باشد (این گاهی اوقات پس از اتصال به زمان اتصال شبکه رخ می دهد.)
    وابستگی های مجدد و همگام سازی پروژه (نیاز به شبکه)
    وابستگی های مجدد و همگام سازی پروژه (نیاز به شبکه)

    1. سید مهدی مطهری (مدیر) گفت:

      ظاهرا در اتصال به نت مشکل داره (طبق مطلب پرسش های رایج مطمئن بشید آی پی به درستی تغییر کرده)

  • حبیب گفت:

    سلام
    اندروید استدیو ورژن ۳ استفاده میکنم
    پروژه م همه چی کامله وهیچ ایرادی نشون نمیده
    وقتی میخام run بگیرم اخراش این ارور میاد

    ErrorExecution failed for task ‘apptransformClassesWithDesugarForDebug’.
    com.android.build.api.transform.TransformException java.lang.RuntimeException java.lang.RuntimeException com.android.ide.common.process.ProcessException Error while executing java process with main class com.google.devtools.build.android.desugar.Desugar with arguments {@CUsersASADIDesktopSaifChatSoftappbuildintermediatestmpdesugar_args27136588803337456}

    میشه راهنماییم کنین این مربوط به چی هست؟
    متشکرم

    1. سید مهدی مطهری (مدیر) گفت:

      متاسفانه ایده ای به ذهنم نمیرسه. اگه یه پروژه جدید و خالی هم بسازید و ران بگیرید باز مشکل دارید؟

  • درود

    در مورد این جمله ای که ذکر کردید به نتیجه رسیدید؟

    در تعدادی از منابع عنوان شده داشتن API مرتبط با MinimumSDK الزامی نیست، با این حال تا لحظه نگارش این مبحث من به نتیجه قطعی نرسیده ام لذا جانب احتیاط را رعایت می کنم.

    1. سید مهدی مطهری (مدیر) گفت:

      نه متاسفانه. فرصتی نشده پیگیر بشم

  • mahsa گفت:

    من تو اجرای پروژه ها این ارور ها رو میگیرم.حتی حافظه رو درvirtualboxزیاد کردم.هرچی هم سرچ میکنم جز این راه چیز دیگه ای پیدا نمیکنم.
    ۱۱-۱۵ ۱۵:۳۹:۳۸٫۲۱۹ ۱۴۵۷-۱۴۶۳/? E/jdwp: Failed sending reply to debugger: Broken pipe
    ۱۱-۱۵ ۱۵:۳۹:۳۸٫۳۱۵ ۱۴۵۷-۱۴۵۷/? E/dalvikvm: Could not find class ‘android.graphics.drawable.RippleDrawable’, referenced from method android.support.v7.widget.AppCompatImageHelper.hasOverlappingRendering
    ۱۱-۱۵ ۱۵:۳۹:۳۸٫۴۳۵ ۱۴۵۷-۱۴۵۷/? E/OpenGLRenderer: Getting MAX_TEXTURE_SIZE from GradienCache
    ۱۱-۱۵ ۱۵:۳۹:۳۸٫۴۳۵ ۱۴۵۷-۱۴۵۷/? E/OpenGLRenderer: MAX_TEXTURE_SIZE: 16384
    ۱۱-۱۵ ۱۵:۳۹:۳۸٫۴۴۳ ۱۴۵۷-۱۴۵۷/? E/OpenGLRenderer: Getting MAX_TEXTURE_SIZE from Caches::initConstraints()
    ۱۱-۱۵ ۱۵:۳۹:۳۸٫۴۴۳ ۱۴۵۷-۱۴۵۷/? E/OpenGLRenderer: MAX_TEXTURE_SIZE: 16384

    1. سید مهدی مطهری (مدیر) گفت:

      با این مسئله برخوردی نداشتم بزرگوار. لطفا سرچ بفرمایید. باید پاسخ های زیادی در وب موجود باشه

  • علی گفت:

    اگر برنامه ایی با api24ساخته شده باشه برای اجرا روی سیستم دیگه حتما باید api24رو داشته باشیم یا api25کفایت میکنه؟

    1. سید مهدی مطهری (مدیر) گفت:

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

  • علی ج گفت:

    سلام من ی پروژه که با نسخه ۲٫۲٫۲ساخته شده بود رو میخوام رو سیستم خودم باز کنم(۲٫۳٫۳) ولی پیغام زیر رو بهم میده
    Migrate Project to Gradle?
    This project does not use the Gradle build system. We recommend that you migrate to using the Gradle build system.
    اگر ممکنه راهنماییم کنین.ممنون

    1. سید مهدی مطهری (مدیر) گفت:

      متن رو ترجمه کنید واضحه. گفته پروژه از گریدل استفاده نکرده و توصیه میشه تبدیل به گریدل بشه که تایید میکنید

      1. مهدی گفت:

        سلام
        چجوری پروژرو کلا حذف کنم ؟؟

        1. سید مهدی مطهری (مدیر) گفت:

          مسیری که پروژه رو ساختید برید و پوشه رو پاک کنید

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

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

کد امنیتی *