نقشه در اندروید(Location-Based Services)
بسم الله الرحمن الرحیم
نقشه در اندروید(Location-Based Services)
فصل نهم
آنچه در پایان فصل یاد خواهید گرفت:
- نصب پکیج های لازم در sdk برای ایجاد برنامه های که با نقشه ها سر کار دارند.
- تنظیم دستگاه برای تست برنامه
- نمایش نقشه گوگل در برنامه کاربردی
در سال های اخیر برنامه های موبایل رشد زیادی د
بسم الله الرحمن الرحیم
نقشه در اندروید(Location-Based Services)
فصل نهم
آنچه در پایان فصل یاد خواهید گرفت:
- نصب پکیج های لازم در sdk برای ایجاد برنامه های که با نقشه ها سر کار دارند.
- تنظیم دستگاه برای تست برنامه
- نمایش نقشه گوگل در برنامه کاربردی
در سال های اخیر برنامه های موبایل رشد زیادی داشته است. اما دسته ای از برنامه های که یسیار مشهور می باشند location-based services می باشد که به LBS. مشهور می باشند. برنامه های LBS. مکان که شما هستید را ردیابی می کند . همچنین امکانات اضافی از قبیل نمایش مکان های رفاهی نزدیک شما را نمیاش می دهد یا پیشنهاد خود را برای برنامه ریزی مسیر حرکت و .. را به شما میدهد.یکی از اجزای اصلی برنامه LBS نقشه های می باشند که تصویر ی از محل زندگی شما را نشان می دهد.
نصب پکیج های لازم در sdk
امکان تست برنامه های کابردی که نقشه ها به کار می گیرند در دستگاه مجازی وجود ندارد. باید حتما روی دستگاه واقعی تست شود
|
برای کار با نقشه ها باید پکیج های را نصب کنیم که به وسیله آن می توانیم نقشه را در برنامه کاربردی استفاده و برنامه ها نوشته شده را در دستگاه واقعی تست کنیم.
برای نصب پکیج های به مسیر مشخص شده بروید:
بعدر از نصب پکیج های بالا باید درایور مربوط به دستگاهی که می خواهیم برنامه های خود را روی آن تست کنیم دانلود و نصب کنیم.
چون در اینجا قصد دارم برنامه ها را نوشته شده رو بر روی گوشی های Samsung تست کنم باید درایور مربوط به گوشی های های سامسونگ را دانلود و نصب کنیم. که مراحل زیر را انجام می دهم.
بعد از نصب درایور باید تنظیماتی را روی دستگاه خود انجام دهیم که مرا حلی زیر را انجام می دهیم.
به محیط Eclipse بروید
دستگاه را با کابل usb به کامپیوتر وصل نمایید.
به محیط گوشی وارد شوید و تنظیمات زیر را انجام دهید.
اگر گزینه DEVELOPER OPTIONS را مشاهده نمی کنید مراحل زیر را بروید
به قسمت About DeVice بروید
به قسمت Developer Options بروید.
بعد از اینکه usb debugging فعال کردید پیغامی شبیه زیر به شما نمایش داده می شود.
بعد از تنظیمات بالا باید در قسمت Devices در DDMS دستگاه شما نمایش داده شود.
اگر تنظیمات بالا را انجام دادید ولی هنوز دستگاه نمایش داده نمی شود . راه حل های زیر را امتحان کنید :
چک کنید که تنظیمات دستگاه را به صورت زیر باشد :
گوشی خود را ReStart کنید
اگر باز هم دستگاه نمایش داده نشد . به شما پیشنهاد می کنم که نرم افزار MoboRobo را نصب کنید.
بعد از نصب نرم افزار را وقتی کابل usb را به گوشی نصب کنید این نرم افزار به صورت اتوماتیک گوشی شما را تشخیص می دهد و در صورت لزوم درایور های آن را دانلود و نصب می کند .
ودر دستگاه پیغامی شبیه را می بینید.
Eclipse را یک بار ReStart کنید
کامپیوتر را ReStart کنید. و دوباره وارد Eclipse شوید.
ایجاد پروژه و تست آن بر روی دستگاه
پروژه جدیدی به نام MyFirstMap ایجاد کنید
بعد از ایجاد پروژه آن را به صورت زیر اجرا کنید
به محیط دستگاه بروید همان طور که مشاهده می کنید برنامه بر روی دستگاه شما اجرا شده است.
نمایش نقشه گوگل در برنامه کاربردی
در قسمت قبل تنظیمات لازم برای تست برنامه در دستگاه واقعی را انجام دادیم. حال قصد داریم که نقشه را در برنامه کاربردی استفاده کنیم.برای نمایش نقشه مراحل مختلفی را( از جمله دادن Permission های لارم به برنامه گرفتن ApiKey و ..) باید انجام دهیم که در ادامه مراحل را به شما آموزش می دهیم.
مرحله اول : تنظیم permission ها
برای نمایش نقشه باید یک سری Permission های را به برنامه خود بدهیم . برای این کار به فایل AndroidManifest.xml پروژه بروید و آن به صورت زیر تغییر دهید.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.MehrdadJavidi.myfirstmap"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="14" />
<permission android:name="com.MehrdadJavidi.myfirstmap.MAPS_RECEIVE" />
<uses-permission android:name="com.MehrdadJavidi.myfirstmap.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.providers.gsf.permission.READ_GSERVICES"/>
<uses-feature android:glEsVersion="0x00020000"
android:required="true"
/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
توضیحات :
برا ی نمایش نقشه باید به اینترنت دسترسی داشته باشیم از این رو باید Permission ها زیر را به برنامه بدهیم.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
برای اینکه از سرویس نقشه گوگل استفاده می کنیم باید Permission زیررا تعیین کنیم.
<uses-permission android:name="com.google.providers.gsf.permission.READ_GSERVICES"/>
دقیقا باید به شکل بالا نوشته شود به حروف کوچک و بزرگ دقت کنید
همچنین ما از google api ورژن 2 استفاده می کنیم که توسط تگ زیر باید آن را تعیین کنیم.
<uses-feature android:glEsVersion="0x00020000"
android:required="true"
/>
ودر زیر Persmission ی را تعیین کردیم که مشخص می کند که برنامه ما امکان نمایش نقشه را دارد و ApiKey مورد نظر را از گوگل دریافت کرده ایم
<permission android:name="com.MehrdadJavidi.myfirstmap.MAPS_RECEIVE" />
: باید Package Name برنامه باشد
2 : MAPS_RECEIVE باید با حروف بزرگ نوشته شود
بعد Permission بالا را در برنامه استفاده کنیم.
<uses-permission android:name="com.MehrdadJavidi.myfirstmap.MAPS_RECEIVE"/>
مرحله دوم: گرفتن apiKey
مرحله دوم برای نمایش نقشه دریافت یک Api Key از گوگل می باشد . به عبارت دیگر ما به اطلاعات برنامه خود را به گوگل اعلام می کنیم . یک کد منحصر به فرد به نام Api Key به ما می دهد که به وسیله آن کد می توانیم از امکانات سرویس نقشه گوگل استفاده کرد.
برای دریافت apiKey از سایت گوگل به صورت زیر استفاده می کنیم:
برای بدست آوردن کد SHA1 به مسیر تعیین شده در Eclipse بروید
فایل androidManefist.xml را به صورت زیر تغییر دهید.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.MehrdadJavidi.myfirstmap"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="14" />
<permission android:name="com.MehrdadJavidi.myfirstmap.MAPS_RECEIVE" />
<uses-permission android:name="com.MehrdadJavidi.myfirstmap.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.providers.gsf.permission.READ_GSERVICES"/>
<uses-feature android:glEsVersion="0x00020000"
android:required="true"
/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyCAB5b_HksbzUrTMt_3QoiLtIOS0JDcO8" />
</application>
</manifest>
مرحله سوم استفاده از Google Play Services
همان طور که قبلا بیان کردیم برای نمایش نقشه ها باید پکیج Google Plays Services را باید نصب کنیم و آن را در به برنامه اضافه کنیم تا بتوانیم با کلاس های که در اختیار ما قرار می دهد نقشه را در برنامه به کار بگیریم. برای این کار مراحل زیر را انجام دهید.
به فایل androidManifestبروید وآن به صورت زیر تغییر دهید
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.MehrdadJavidi.myfirstmap"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="14" />
<permission android:name="com.MehrdadJavidi.myfirstmap.MAPS_RECEIVE" />
<uses-permission android:name="com.MehrdadJavidi.myfirstmap.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.providers.gsf.permission.READ_GSERVICES"/>
<uses-feature android:glEsVersion="0x00020000"
android:required="true"
/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyCAB5b_HksbzUrTMt_3QoiLtIOS0JDcO8" />
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"
/>
</application>
</manifest>
برای اینکه اطمینان حاصل کنیم که آیا عملیات بالا با موفقیت انجام شده یا خیر به فایل MainActivity.java بروید ویک شی از کلاس GoogleMap ایجاد کنید .
public class MainActivity extends Activity {
GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
.....
مرحله چهارم
برای اینکه نقشه در دستگاه قابل نمایش باشد باید Google Play Services روی دستگاه نصب باشد (در اکثر گوشی ها نصب می باشد).
اگر Googe Play Services نصب نباشد امکان نمایش نقشه وجود ندارد.
ما باید قبل از اینکه نقشه نمایش داده شود چک کنیم که آیا Google Play Service نصب می باشد یا خیر . اگر نصب بود نقشه نمایش داده شود در غیر این صورت دیالوگ را به کاربر نمایش دهد تا از کاربر بخواهد تا GooglePlay Services را نصب یا به روز رسانی کند. برای این کار به صورت زیر عمل می کنیم.
به فایل MainActivity.java بروید وآن را به صورت زیر تغییر دهید.
package com.MehrdadJavidi.myfirstmap;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;
public class MainActivity extends Activity {
GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (servicesOk()) {
Toast.makeText(this, "Ready To Map", Toast.LENGTH_LONG).show();
} else {
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
/** Inflate the menu; this adds items to the action bar if it is present. */
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
/** Handle action bar item clicks here. The action bar will
automatically handle clicks on the Home/Up button, so long
as you specify a parent activity in AndroidManifest.xml. */
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private boolean servicesOk() {
int isAvailable = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (isAvailable == ConnectionResult.SUCCESS) {
return true;
} else if (GooglePlayServicesUtil.isUserRecoverableError(isAvailable)) {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(isAvailable,
this, 901);
dialog.show();
} else {
Toast.makeText(this, "Cant Access To Service", Toast.LENGTH_LONG)
.show();
}
return false;
}
}
توضیحات
private boolean servicesOk() {
int isAvailable = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (isAvailable == ConnectionResult.SUCCESS) {
return true;
} else if (GooglePlayServicesUtil.isUserRecoverableError(isAvailable)) {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(isAvailable,
this, 901);
dialog.show();
} else {
Toast.makeText(this, "Cant Access To Service", Toast.LENGTH_LONG)
.show();
}
return false;
}
متد به نام ServicesOk را تعریف کرده ایم که به وسیله آن چک می کنیم که آیا Google Play Services رو دستگاه نصب می باشد یا خیر .
اگر نصب بود مقدار True را بر می گر داند
اگر مشکل قابل بر طرف بود دیالوگ مناسبی را به کار نمایش می دهد
در غیر این صورت پیغام مبنی بر اینکه Google Play Service در دسترس نمی باشد را به کاربر نمایش و مقدار False را بر می گرداند.
وآخر هم آن را درمتد OnCreate استفاده کرده ایم. اگر Google Play services نصب بود پیغام مناصبی را نمایش دهد.
if (servicesOk()) {
Toast.makeText(this, "Ready To Map", Toast.LENGTH_LONG).show();
} else {
}
مرحله پنجم نمایش نقشه
در قسمت قبل تمام تنظیماتی را که لازم بود تا بتوان نقشه را نمایش دهیم انجام داده ایم حال وقت آن رسیده که نقشه نشان دهیم .
چندین روش برای نمایش نقشه ها وجو دارد یک استفاده از یک Fragment ، دو استفاده از View ی به نام MapView که در ادامه هر کدام را شرح می دهیم.
روش اول : نمایش نقشه با Fragment
یک فایل LayOut در مسیر res\layout به نام map_activity.xml ایجاد کنید آن را به صورت زیر تغییر دهید
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
به فایل mainActivity بروید و محتوای آن را به صورت زیر تغییر دهید.
package com.MehrdadJavidi.myfirstmap;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;
public class MainActivity extends FragmentActivity {
GoogleMap mMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (servicesOk()) {
Toast.makeText(this, "Ready To Map", Toast.LENGTH_LONG).show();
setContentView(R.layout.map_activity);
} else {
setContentView(R.layout.activity_main);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
/** Inflate the menu; this adds items to the action bar if it is present. */
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
/** Handle action bar item clicks here. The action bar will
automatically handle clicks on the Home/Up button, so long
as you specify a parent activity in AndroidManifest.xml. */
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private boolean servicesOk() {
int isAvailable = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (isAvailable == ConnectionResult.SUCCESS) {
return true;
}
else if (GooglePlayServicesUtil.isUserRecoverableError(isAvailable)) {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(isAvailable,
this, 901);
dialog.show();
} else {
Toast.makeText(this, "Cant Access To Service", Toast.LENGTH_LONG)
.show();
}
return false;
}
}
برنامه را F11 اجرا کنید
روش دوم : نمایش نقشه با MapView
به فایل activity_main.xml بروید و آن را به صورت زیر تغییر دهید
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.gms.maps.MapView
android:id="@+id/mapView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
توضیحات
در بالا View ی به نام MapView را تعریف کرده ایم که به وسیله آن می توانیم نقشه را نمایش دهیم. Id آن را mapView1 قرا داده ایم و width و height آن طوری تعیین کرده ایم که کل activity را در بر بگیرد.
به فایل mainActivity.java بروید و آن را به صورت زیر تغییر دهید.
package com.MehrdadJavidi.myfirstmap;
import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
public class MainActivity extends FragmentActivity {
GoogleMap mMap;
MapView mapView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** if (servicesOk()) {
Toast.makeText(this, "Ready To Map", Toast.LENGTH_LONG).show();
setContentView(R.layout.map_activity);
} else {
setContentView(R.layout.activity_main);
} */
setContentView(R.layout.activity_main);
mapView = (MapView) findViewById(R.id.mapView1);
mapView.onCreate(savedInstanceState);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
/** Inflate the menu; this adds items to the action bar if it is present. */
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
/** Handle action bar item clicks here. The action bar will
automatically handle clicks on the Home/Up button, so long
as you specify a parent activity in AndroidManifest.xml. */
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private boolean servicesOk() {
int isAvailable = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (isAvailable == ConnectionResult.SUCCESS) {
return true;
}
else if (GooglePlayServicesUtil.isUserRecoverableError(isAvailable)) {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(isAvailable,
this, 901);
dialog.show();
} else {
Toast.makeText(this, "Cant Access To Service", Toast.LENGTH_LONG)
.show();
}
return false;
}
@Override
protected void onDestroy() {
/** TODO Auto-generated method stub */
super.onDestroy();
mapView.onDestroy();
}
@Override
public void onLowMemory() {
// TODO Auto-generated method stub
super.onLowMemory();
mapView.onLowMemory();
}
@Override
protected void onPause() {
/** TODO Auto-generated method stub */
super.onPause();
mapView.onPause();
}
@Override
protected void onResume() {
/** TODO Auto-generated method stub */
super.onResume();
mapView.onResume();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
/** TODO Auto-generated method stub */
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
}
توضیحات
ابتدا بک شی از کلاس ایجاد تعریف کردهایم تا به MapView1 دسترسی (Refrence )داشته باشیم
public class MainActivity extends FragmentActivity {
GoogleMap mMap;
MapView mapView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** if (servicesOk()) {
Toast.makeText(this, "Ready To Map", Toast.LENGTH_LONG).show();
setContentView(R.layout.map_activity);
} else {
setContentView(R.layout.activity_main);
} */
setContentView(R.layout.activity_main);
mapView = (MapView) findViewById(R.id.mapView1);
mapView.onCreate(savedInstanceState);
}
برای اینکه نقشه در mapView نمایش داده شود باشد متد های زیر را فراخوانی کنیم
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** if (servicesOk()) {
Toast.makeText(this, "Ready To Map", Toast.LENGTH_LONG).show();
setContentView(R.layout.map_activity);
} else {
setContentView(R.layout.activity_main);
} */
setContentView(R.layout.activity_main);
mapView = (MapView) findViewById(R.id.mapView1);
mapView.onCreate(savedInstanceState);
}
@Override
protected void onDestroy() {
/** TODO Auto-generated method stub */
super.onDestroy();
mapView.onDestroy();
}
@Override
public void onLowMemory() {
/** TODO Auto-generated method stub */
super.onLowMemory();
mapView.onLowMemory();
}
@Override
protected void onPause() {
/** TODO Auto-generated method stub */
super.onPause();
mapView.onPause();
}
@Override
protected void onResume() {
/** TODO Auto-generated method stub */
super.onResume();
mapView.onResume();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
/** TODO Auto-generated method stub */
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
جمال
واقعا دستتون درد نکنه آموزشتون کامل و مفید بود هر جا دیدم به این خوبی نبود
اسماعیلشیدایی
با عرض سلام