الدرس الأول
ابدأ مع Google Map
الدرس الثانى
انواع الخرائط والـ Gestures والـ Markers
الدرس الثالث
الموقع الحالى وتحديد الإتجاهات
اذا واجهتك أى مشكلة
قم بطرحها فى جروب
[/mhc_text][/mhc_column][mhc_column type=”3_4″][mhc_post_header admin_label=”عنوان المقالة” title=”on” meta=”off” avatar=”on” author=”on” date=”on” categories=”on” comments=”off” views=”off” text_orientation=”right” text_color=”dark” featured_image=”on” featured_placement=”above” parallax=”on” parallax_method=”off” animation=”off” custom_paddings=”40″ size=”30px” title_bold=”on” text_shadow=”off” text_background=”off” text_bg_color=”#ffffff” overlay=”on” saved_tabs=”all”] [/mhc_post_header][mhc_text admin_label=”نص” background_layout=”light” text_orientation=”right”]فى الدرس السابق Google Maps بالعربية – الدرس الثانى تحدثنا عن انواع الخرائط وكذلك كيفية الاستجابة للضغطات على الخريطة بالاضافة لكيفية اضافة Marker على الخريطة يمكنك اضافة دوائر او مضلعات او ايقونات لكن لن نتطرق الى ذلك الان وسنتحدث عن موضوعين مهمين جدا فى استخدام الخرائط وهما تحديد الموقع الحالى للمستخدم وكذلك تحديد الإتجاهات على الخريطة .
تحديد الموقع الحالى
يمكنك تحديد الموقع الحالى للمستخدم عن طريق ما يعرف بالـ Last Know Location وهو عباره عن اخر موقع معروف للمستخدم والذى فى اغلب الاحيان هو الموقع الحالى لكن قبل أن تقوم ببدء التكويد للحصول على الموقع الحالى مباشرة يجب التحقق من أمرين أولا : صلاحيات الوصول لموقع المستخدم خصوصا لأجهزة مارشميلو عن طريق عمل Request Permission لصلاحيات الـ Location فى الـ Runtime حيث يعد الـ Location من الصلاحيات الخطيرة ويمكنك مراجعة تدوينة الصلاحيات فى أندرويد مارشميلو لمعرفة تفاصيل أكثر عن كيفية طلب الصلاحيات حيث لن اقوم باعادة شرحها هنا لكن سأضع الكود مباشرة اثناء الشرح ،
ثانيا : التأكد من الـ Location او GPS مفعل حاليا من قبل المستخدم ويمكنك استخدام هذا الكود اختصارا للوقت
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){ Toast.makeText(this, "GPS is Enabled in your device", Toast.LENGTH_SHORT).show(); }else{ showGPSDisabledAlertToUser(); }
والميثود showGPSDisabledAlertToUser محتواها كالاتى :
private void showGPSDisabledAlertToUser(){ AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); alertDialogBuilder.setMessage("GPS is disabled in your device. Would you like to enable it?") .setCancelable(false) .setPositiveButton("Goto Settings Page To Enable GPS", new DialogInterface.OnClickListener(){ public void onClick(DialogInterface dialog, int id){ Intent callGPSSettingIntent = new Intent( android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivity(callGPSSettingIntent); } }); alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){ public void onClick(DialogInterface dialog, int id){ dialog.cancel(); } }); AlertDialog alert = alertDialogBuilder.create(); alert.show(); }
وهذا الكود ببساطة يقوم بانشاء Reference من الـ location manager ثم يقوم بفحص اذا ما كان ال gps مفعلا ام لا اذا كان مفعل اظهر toast انه مفعل واذا كان غير مفعل قم باظهار Dialog توضيحية للمستخدم تظهر بها رسالة توضيحية للمستخدم ان ال gps غير مفعل هل تريد تفعيله وزر يذهب مباشرة للاعدادات الخاصة بالLocation لكى يقوم المستخدم بالتفعيل وبالتالى يمكن للتطبيق الخاص بنا تحديد موقعه .
نبدأ الان بكتابة كود تحديد الموقع
أولا سنقوم بإنشاء GoogleAPIClient حيث اننا فى تحديدنا للموقع نعتمد على ال Google API وتحديدا FusedLocationApi سنقوم بذلك كالاتى :
ببساطة قمنا ببناء GoogleApiClient واضفنا له الـ ConnectionCallbacks اى ماذا سيحدث عند الاتصال عند انقطاع الاتصال وهكذا واعطينا this لاننا سنقوم بعمل implement بعد قليل مثلما فعلنا مع ال map سابقا لو تذكر وكذلك الـ listener الخاص بفشل الاتصال اعطيناه this بالاضافة الى اضافة API الـ LocationService
الان سنقوم بعمل implement لـ ConnectionCallbacks و OnConnectionFailedListener حيث اننا اشرنا اليهم اثناء بناء ال googleApiClient بـ this وسيتم ذلك كالتالى :
وطبعا الخط الأحمر هذا يشير الى انه هناك بعض الـ methods التى يجب علينا عمل override لها سنضغط alt+ enter ونختار
وستجد انه تم اضافة الـ Methods للأكتيتفى
الميثود onConnect يتم تنفيذها بعد الاتصال بالـ Google Api مباشرة و onConnectionSuspended تستدعى عندما يتم ايقاف الاتصال والـ onConnectionFailed تستدعى فى حالة فشل الاتصال حتى يتاح لك عمل handel لكل الحالات المختلفة .
الان كل شىء يبدو جيدا وينقص شىء واحد فقط يجب أن نقوم يدويا بعمل connect لل google api client وكذلك يدويا بعمل disconnect لايقاف الاتصال وسنقوم بذلك فى الميثود onStart() والميثود onStop() كاالتالى :
الان يمكننا استخدام الـ googleClientApi للحصول على الموقع الحالى وسنقوم بذلك بداخل ميثود onConnect والتى تستدعى بعد اتمام الاتصال ب googleAPI بنجاح وبالتالى يكون الـ client الخاص بنا جاهز
عن طريق استخدام الميثود getLastLocation والتى تأخذ Google Api Client كباراميتر نقوم بالحصول على الـ Location وكما تلاحظ الان الخط الأحمر بالكود وهو للتنبيه بأننا لم نقم بعمل طلب صلاحيات للمارشميلو وهذا الكود يستلزم تصريح احد الصلاحيات الخطيرة فى الأندرويد لذلك سأقوم بإضافة كود الـ Permissions كالتالى :
نقوم الان بتشغيل التطبيق والتجربة وان قمت بالتجربة على المارشميلو سيطلب الصلاحيات وافق عليها ثم شاهد الـ Logcat
سنقوم بفعل شىء افضل من ذلك وهو ان نضع بالونة على الموقع الحالى للمستخدم هل تتذكر كيفية اضافة Marker فى الدرس السابق ؟
وبعد التشغيل ستجد أنه قام بعرض الموقع الحالى لك وتحريك الكاميرا نحوه
الكود الكامل للأكتيتيفى الان :
package com.hendiware.myfirstmap; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.location.Location; import android.location.LocationManager; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.ActivityCompat; import android.support.v4.app.FragmentActivity; import android.support.v7.app.AlertDialog; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.location.LocationServices; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private GoogleMap mMap; private GoogleApiClient googleApiClient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { Toast.makeText(this, "GPS is Enabled in your devide", Toast.LENGTH_SHORT).show(); } else { showGPSDisabledAlertToUser(); } if (googleApiClient == null) { googleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } } @Override protected void onStart() { googleApiClient.connect(); super.onStart(); } @Override protected void onStop() { googleApiClient.disconnect(); super.onStop(); } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; } @Override public void onConnected(@Nullable Bundle bundle) { if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION}, 1); } else { Location userCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient); if (userCurrentLocation != null) { MarkerOptions currentUserLocation = new MarkerOptions(); LatLng currentUserLatLang = new LatLng(userCurrentLocation.getLatitude(), userCurrentLocation.getLongitude()); currentUserLocation.position(currentUserLatLang); mMap.addMarker(currentUserLocation); mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentUserLatLang, 16)); } } } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { onConnected(null); } else { Toast.makeText(MapsActivity.this, "No Permitions Granted", Toast.LENGTH_SHORT).show(); } } private void showGPSDisabledAlertToUser() { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); alertDialogBuilder.setMessage("GPS is disabled in your device. Would you like to enable it?") .setCancelable(false) .setPositiveButton("Goto Settings Page To Enable GPS", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { Intent callGPSSettingIntent = new Intent( android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivity(callGPSSettingIntent); } }); alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = alertDialogBuilder.create(); alert.show(); } }
تحديد الإتجاهات من مكان لأخر
توفر لنا جوجل من ضمن مجموعة الـ APIs الخاصة بالخرائط الـ Direction API وهو الذى يوفر لنا خدمة تحديد الاتجاهات ورسمها على الخريطة وما يتعلق بذلك من امور
تتيح لك الخدمة معرفة الاتجاهات بين مكانين معينين عن طريق Http Request تعطيه الباراميترز الازمة وتحصل على الـنتيجة كـ json وهى الطريقة العادية بالاضافة للطريقة العادية توفر جوجل مكتبات كـ Client Side أحدها للجافا والتى بنى عليها عدة مكتبات أندرويد تسهل عليك موضوع تحديد الإتجاهات من أشهرهم مكتبة akexorcist/Android-GoogleDirectionLibrary والتى تمكنك من التعامل مع الـ Direction API بسهولة سنقوم الان باضافتها لملف الجرادل
compile 'com.akexorcist:googledirectionlibrary:1.0.4'
وقبل أن نبدأ بكتابة اى كود سنقوم الان بالذهاب للـ Google Console لتفعيل وتمكين استخدام الـ Direction API
وبعد ذلك نقوم بعمل Enable والان تصبح جاهزا ننتقل للأندرويد
كما بالمثال الموضح لاستخدام المكتبة فهى تستخدم كالتالى :
نقوم بكتابة GoogleDirection اسم الكلاس الخاص بالمكتبة ثم الميثود withServerKey نعطيها الـ API Key الخاص بنا الذى حصلنا عليه فى الدرس الاول ثم الميثود from وهو المكان الذى سيتم تحديد الاتجاهات منه على شكل LatLang (خطوط الطول والعرض) يليها الميثود to وتأخذ باراميتر LatLang ايضا بمكان الوجهه او المكان الذى سيتم تحديد الاتجاهات ليه ثم بعد ذلك الميثود execute الخاصة بالتنفيذ وتأخذ باراميتر الـ CallBack الخاص بنتائج الاتصال هل هو ناجح أم فاشل واذا نجح الاتصال هل فشل جلب الاتجاهات ام نجح نقوم الان بتشغيل التطبيق ومشاهدة النتيجة
وستجد انه تم الوصول للاتجاهات بنجاح
ويعنى أنه تم تحديد الاتجاهات بنجاح بين المكانين وطبعا أنت لا تحدد الاتجاهات فقط لمجرد تحديد الاتجاهات بل لتقوم بامر اخر والذى يكون فى اغلب الاحيان رسم خط على الخريطة يوضح هذه الاتجاهات
تأتى نتيجة الاتصال السابق على هيئة List تحتوى على Route أو اكثر حيث أحيانا يكون هناك عدة طرق للوصول لمكان اخر من هذا المكان
يحتوى الـ Route على Leg أو أكثر وهو المسافه بين مكان واخر ويحتوى الـ Leg على step وهى المسافة بين مكان واخر داخل نفس الـ Leg لذلك نستدعى ذلك من النتيجة ونقوم بناءا عليه بإنشاء Polyline ونرسمه على الخريطة بناءا على بيانات الاتجاهات الى حصلنا عليها كما يتضح من الكود التالى
قمنا بجلب الـ Leg ثم استخدمنا الميثود getDirectionPoint والتى تعطى لنا امكانية الحصول على الاتجاهاات على هيئة مصفوفة من خطوط الطول والعرض المتتالية ثم قمنا باستخدام الميثود createPolyline الموجودة بكلاس DirectionCoverter والتى أخذت منا باراميترات (الكونتكست ، ليست الاتجاهات ، سمك الخط ، اللون )
ثم قمنا باضافة هذا الـ polyline للخريطة .
وتكون النتيجة ظهور رسم الاتجاه على الخريطة كالتالى :
[/mhc_text][/mhc_column][/mhc_row][/mhc_section]
مرحبا كيفكم انا متابعتكم من غزة وباحب اشكركم على الجهد الرائع وباتمنى تستمروا في تقديم الشروحات
وحابة اطلب منكم طلب ازا ممكن
يا ريت لو تعملوا شرح كامل ومفصل عن الدفع الالكتروني لانو هي الاشي يلي ناقص ما حكيتوا عنه ومحتاجاه ضروري جدا الفترة الحالية
وشكرا جزيلا لكم