دليل مطوري Android لواجهة برمجة تطبيقات خدمات الموقع من Google

نشرت: 2022-03-11

تعد معرفة موقع المستخدم معلومات مفيدة في العديد من التطبيقات التي نطورها ونستخدمها اليوم. هناك الكثير من التطبيقات الشائعة القائمة على الموقع والتي تجعل حياتنا أسهل ، فضلاً عن تغيير طريقة استخدامنا لهذه الخدمات. ومن الأمثلة على ذلك التطبيق الشائع للغاية Foursquare ، حيث غالبًا ما يربح المستخدمون الذين يترددون على إحدى المؤسسات و "يسجلون الوصول" خصومات. Uber ، التي تساعدك في الحصول على مشوار من هاتفك المحمول بسعر أقل من سيارة الأجرة العادية. القائمة كبيرة وما زالت تتزايد.

خدمات الموقع API

في هذه المقالة ، سننشئ تطبيق Android بسيطًا لتحديد خط الطول وخط العرض للمستخدم باستخدام واجهة برمجة تطبيقات خدمات الموقع في Google على Android. عند تطوير تطبيقات Android ، هناك طريقتان للحصول على موقع المستخدم.

حزمة "android.location"

كانت الحزمة "android.location" متاحة منذ تقديم Android لأول مرة ، وهي تتيح لنا الوصول إلى خدمات الموقع. تسمح هذه الخدمات للتطبيقات بالحصول على تحديثات دورية للموقع الجغرافي للجهاز.

توفر الحزمة وسيلتين للحصول على بيانات الموقع:

  • LocationManager.GPS_PROVIDER: يحدد الموقع باستخدام الأقمار الصناعية. اعتمادًا على الشروط ، قد يستغرق هذا المزود بعض الوقت لإعادة إصلاح الموقع.

  • LocationManager.NETWORK_PROVIDER: يحدد الموقع بناءً على توفر الأبراج الخلوية القريبة ونقاط وصول WiFi. هذا أسرع من GPS_PROVIDER.

عندما تبحث عن موقع المستخدم ، عليك أن تلعب مع هؤلاء المزودين وتوافرهم. من الناحية المثالية ، تحصل على الموقع الأول باستخدام NETWORK_PROVIDER ، والذي قد لا يكون بالدقة نفسها ، ولكنه أسرع بكثير. يمكنك بعد ذلك محاولة زيادة الدقة من خلال الاستماع إلى تحديد موقع أفضل باستخدام GPS_PROVIDER.

تعد واجهات برمجة التطبيقات التي توفرها هذه الحزمة منخفضة المستوى إلى حد ما ، وتتطلب من مطور التطبيق التعامل مع التفاصيل الدقيقة لتحديد وقت طلب بيانات الموقع وجدولة المكالمات إلى واجهة برمجة التطبيقات بطريقة محسّنة. لتحسين تجربة المطور مع خدمات النظام المستندة إلى الموقع وتسهيل عملية تطوير التطبيقات المدركة للموقع ، قدمت Google طريقة جديدة لطلب موقع المستخدم باستخدام خدمات Google Play. إنه يوفر واجهة برمجة تطبيقات أبسط ذات دقة أعلى ، وسياج جغرافي منخفض الطاقة ، وغير ذلك الكثير.

واجهة برمجة تطبيقات خدمات الموقع من Google

تُعد واجهة برمجة تطبيقات خدمات الموقع من Google ، والمعروفة أيضًا باسم FusedLocationProviderApi ، طريقة موصى بها من Google للحصول على موقع المستخدم. يوفر أفضل دقة بناءً على احتياجاتنا. بعض مزايا استخدام واجهة برمجة التطبيقات هذه على السابقة هي:

  • البساطة: على عكس واجهة برمجة التطبيقات السابقة ، لم تعد مضطرًا للتعامل مع عدة مزودين. بدلاً من ذلك ، تحدد احتياجات عالية المستوى ، مثل "دقة عالية" أو "طاقة منخفضة" ، وسوف تتخذ نهجًا مناسبًا.

  • التوفر: يمنح تطبيقك وصولاً فوريًا إلى أفضل وأحدث موقع معروف. عادة ما تكون هذه المعلومات متاحة بسهولة ، ما عليك سوى طلبها.

  • كفاءة الطاقة: تقلل من استخدام التطبيق للطاقة.

  • تعدد الاستخدامات: يلبي مجموعة واسعة من الاحتياجات ، من الاستخدامات الأمامية - التي تتطلب بيانات موقع عالية الدقة ، إلى الاستخدامات الخلفية - تتطلب فقط تحديثات دورية للموقع مع تأثير ضئيل على الطاقة.

دعونا نبني تطبيق Android يعتمد على الموقع باستخدام واجهة برمجة التطبيقات هذه. لهذا ، سنستخدم IDE الذي اقترحته Google لتطوير تطبيقات Android - Android Studio. يعد بدء استخدام Android Studio أمرًا بسيطًا جدًا. يصف موقع الويب الخاص بهم الإجراء الذي يتضمن تثبيت Android Studio وتكوينه بتفصيل كبير ، بما في ذلك كيفية تمهيد تطبيق Android الأول للتطوير.

يجب أن يجعل Android Studio الأمور سهلة للغاية بالنسبة لنا. ومع ذلك ، سنحتاج إلى البدء بتكوين النص البرمجي للبناء وإضافة خدمات Google Play كاعتماد لهذا التطبيق. يمكن القيام بذلك عن طريق تعديل ملف "build.gradle" على النحو التالي:

 dependencies { compile 'com.android.support:appcompat-v7:21.0.3' compile 'com.google.android.gms:play-services:6.5.87' // Add this line }

في الوقت الذي أكتب فيه هذا المقال ، كان أحدث إصدار من خدمات Google Play متاحًا هو 6.5.87. تأكد من التحقق دائمًا من أحدث إصدار متاح قبل البدء. في حالة ظهور إصدارات أحدث لاحقًا وقررت تحديثها لمشاريعك الخاصة ، اختبر جميع الميزات المتعلقة بالموقع مقابل جميع إصدارات Android التي تدعمها.

في هذه المرحلة ، يجب أن نكون قادرين على بدء العمل الفعلي لتطبيقنا.

طلب الإذن وتهيئة AndroidManifest.xml

تتمتع أجهزة Android بميزات أمان محددة تمنع أي تطبيق تعسفي من طلب موقع مستخدم دقيق. لحل هذه المشكلة ، نحتاج إلى تعديل "AndroidManifest.xml" وإضافة الإذن الذي نطلبه لهذا التطبيق:

 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

أثناء وجودنا فيه ، يجب علينا أيضًا تحديد إصدار خدمات Google Play التي نستخدمها لهذا التطبيق:

 <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

التحقق من توفر خدمات Google Play

قبل الوصول إلى الميزات التي توفرها خدمات Google Play ، يجب أن نتحقق مما إذا كان الجهاز يحتوي على خدمات Google Play مثبتة ، وأن الإصدار هو الإصدار الذي نعتزم استخدامه (6.5.87).

 private boolean checkGooglePlayServices(){ int checkGooglePlayServices = GooglePlayServicesUtil .isGooglePlayServicesAvailable(mContext); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { /* * Google Play Services is missing or update is required * return code could be * SUCCESS, * SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, * SERVICE_DISABLED, SERVICE_INVALID. */ GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, mContext, REQUEST_CODE_RECOVER_PLAY_SERVICES).show(); return false; } return true; }

ستتحقق هذه الطريقة من خدمات Google Play ، وفي حالة عدم تثبيت الجهاز (هذا نادر ، لكنني رأيت مثل هذه الحالات) ، فسيتم فتح مربع حوار به الخطأ المقابل ودعوة المستخدم للتثبيت / التحديث خدمات Google Play من متجر Google Play.

خدمات جوجل بلاي

بعد أن يكمل المستخدم الحل المقدم من "GooglePlayServicesUtil.getErrorDialog ()" ، يتم تشغيل طريقة رد الاتصال "onActivityResult ()" ، لذلك يتعين علينا تنفيذ بعض المنطق للتعامل مع هذا الاستدعاء:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_RECOVER_PLAY_SERVICES) { if (resultCode == RESULT_OK) { // Make sure the app is not already connected or attempting to connect if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(mContext, "Google Play Services must be installed.", Toast.LENGTH_SHORT).show(); finish(); } } }

الوصول إلى Google APIs

للوصول إلى Google APIs ، نحتاج فقط إلى تنفيذ خطوة أخرى: إنشاء مثيل GoogleApiClient. يوفر Google API Client نقطة دخول مشتركة لجميع خدمات Google Play ، ويدير اتصال الشبكة بين جهاز المستخدم وكل خدمة من خدمات Google. خطوتنا الأولى هنا هي بدء الاتصال. عادةً ما أسمي هذا الرمز من طريقة "onCreate" للنشاط:

 protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); }

من خلال تسلسل سلسلة من استدعاءات الطريقة ، فإننا نحدد تنفيذ واجهة رد الاتصال وواجهة برمجة تطبيقات خدمة الموقع التي نريد استخدامها. سيتلقى تنفيذ الواجهة ، في هذه الحالة "this" ، استجابة لطريقة "connect ()" غير المتزامنة عندما ينجح الاتصال بخدمات Google Play أو يفشل أو يتم تعليقه. بعد إضافة هذا الرمز ، يجب أن يبدو "MainActivity" الخاص بنا على النحو التالي:

 package com.bitwoo.userlocation; import android.content.Intent; import android.location.Location; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; 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.common.api.GoogleApiClient; import com.google.android.gms.location.LocationServices; public class MainActivity extends ActionBarActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private static int REQUEST_CODE_RECOVER_PLAY_SERVICES = 200; private GoogleApiClient mGoogleApiClient; private Location mLastLocation; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (checkGooglePlayServices()) { buildGoogleApiClient(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.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(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } private boolean checkGooglePlayServices() { int checkGooglePlayServices = GooglePlayServicesUtil .isGooglePlayServicesAvailable(this); if (checkGooglePlayServices != ConnectionResult.SUCCESS) { /* * google play services is missing or update is required * return code could be * SUCCESS, * SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED, * SERVICE_DISABLED, SERVICE_INVALID. */ GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices, this, REQUEST_CODE_RECOVER_PLAY_SERVICES).show(); return false; } return true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE_RECOVER_PLAY_SERVICES) { if (resultCode == RESULT_OK) { // Make sure the app is not already connected or attempting to connect if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) { mGoogleApiClient.connect(); } } else if (resultCode == RESULT_CANCELED) { Toast.makeText(this, "Google Play Services must be installed.", Toast.LENGTH_SHORT).show(); finish(); } } } protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); } @Override public void onConnected(Bundle bundle) { } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(ConnectionResult connectionResult) { } }

ثم في طريقة onStart الخاصة بنا ، نسمي طريقة "connect" وننتظر استدعاء طريقة رد الاتصال "onConnected":

 @Override protected void onStart() { super.onStart(); if (mGoogleApiClient != null) { mGoogleApiClient.connect(); } }

ستبدو طريقة "onConnected" بالشكل التالي:

 @Override public void onConnected(Bundle bundle) { mLastLocation = LocationServices.FusedLocationApi.getLastLocation( mGoogleApiClient); if (mLastLocation != null) { Toast.makeText(this, "Latitude:" + mLastLocation.getLatitude()+", Longitude:"+mLastLocation.getLongitude(),Toast.LENGTH_LONG).show(); } }

يتم تشغيل رد الاتصال هذا عندما تكون خدمات Google Play متصلة ، مما يعني أنه يجب أن يكون لدينا آخر موقع معروف. ومع ذلك ، يمكن أن يكون هذا الموقع فارغًا (إنه نادر ولكنه ليس مستحيلًا). في هذه الحالة ، ما أوصي به هو الاستماع إلى تحديثات الموقع التي سيتم تغطيتها بعد ذلك.

الاستماع لتحديثات الموقع

بعد استدعاء "getLastLocation" ، قد ترغب في طلب تحديثات دورية من موفر الموقع المدمج. اعتمادًا على طلبك ، قد تكون هذه الفترة قصيرة أو طويلة. على سبيل المثال ، إذا كنت تقوم ببناء تطبيق يتتبع موقع المستخدم أثناء القيادة ، فستحتاج إلى الاستماع إلى التحديثات على فترات زمنية قصيرة. من ناحية أخرى ، إذا كان التطبيق الخاص بك يتعلق بمشاركة موقع المستخدم مع صديقه ، فربما تحتاج فقط إلى طلب الموقع من حين لآخر.

يعد إنشاء طلب أمرًا سهلاً للغاية - يمكنك استدعاء هذه الطريقة داخل طريقة "onCreate":

 protected void createLocationRequest() { mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(20000); mLocationRequest.setFastestInterval(5000); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); }

نقوم بإنشاء كائن LocationRequest جديد. اضبط الفاصل الزمني على 20 ثانية (20000 مللي ثانية). علاوة على ذلك ، قمنا بتعيين معدل تحديث مخنق على 5 ثوان. يخبر هذا واجهة برمجة التطبيقات بتقديم تحديثات كل 20 ثانية (يفضل) ، ولكن إذا كان هناك تغيير متاح خلال فترة 5 ثوانٍ ، فيجب أن توفر ذلك أيضًا. أخيرًا ، قمنا بتعيين الأولوية إلى "PRIORITY_HIGH_ACCURACY" ، من بين خيارات الأولوية الأخرى المتاحة: PRIORITY_BALANCED_POWER_ACCURACY ، PRIORITY_LOW_POWER ، PRIORITY_NO_POWER.

بمجرد إنشاء الطلب ، تكون جاهزًا لبدء الاستماع إلى تحديثات الموقع بعد تشغيل طريقة "onConnected ()":

 protected void startLocationUpdates() { LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, mLocationRequest, this); }

كل ما تبقى الآن هو تنفيذ طريقة رد الاتصال لتلبية واجهة LocationListener:

 public class MainActivity extends ActionBarActivity implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener { // ... @Override public void onLocationChanged(Location location) { mLastLocation = location; Toast.makeText(this, "Latitude:" + mLastLocation.getLatitude()+", Longitude:"+mLastLocation.getLongitude(),Toast.LENGTH_LONG).show(); } } 

توقف عن الاستماع إلى التحديثات

توقف عن الاستماع للتحديثات

من المهم التوقف صراحةً عن الاستماع إلى التحديثات عندما لا تحتاج إليها بعد الآن ، أو إذا ترك المستخدم التطبيق الخاص بك. يجب استدعاء الطريقة التالية من داخل رد الاتصال "onPause":

 protected void stopLocationUpdates() { if (mGoogleApiClient != null) { LocationServices.FusedLocationApi.removeLocationUpdates( mGoogleApiClient, this); } }

... وفصل Google API:

 @Override protected void onStop() { super.onStop(); if (mGoogleApiClient != null) { mGoogleApiClient.disconnect(); } }

تغليف

كما ترى ، فإن الأفكار الأساسية وراء تنفيذ تطبيقات معرفة الموقع في Android بسيطة للغاية. علاوة على ذلك ، مع واجهات برمجة التطبيقات المتاحة التي تتميز بسهولة الاستخدام والفهم ، يجب ألا يكون من المنطقي إنشاء تطبيقات أساسية تعتمد على الموقع لنظام Android. الغرض من تطبيق العينة الصغير الذي أنشأناه هنا هو توضيح ذلك بالضبط. يمكنك العثور على الكود المصدري الكامل لهذا على جيثب. يرجى ملاحظة أنه لتبسيط الأمور ، لا يتعامل التطبيق مع طريقة رد الاتصال “onConnectionFailed”.

نأمل أن يساعدك هذا البرنامج التعليمي على البدء في استخدام واجهة برمجة تطبيقات خدمات الموقع من Google.