خدمات مبتنی بر موقعیت در اندروید
API های موقعیت اندروید باعث می شود که به سادگی بتوانید اپلیکیشن هایی بسازید که از موقعیت آگاه می شوند؛ بدون این که نیاز باشد روی جزئیات تکنولوژی برجسته موقعیت یابی تمرکز کند.
این امر با کمک خدمات گوگل پلی امکان پذیر می شود؛ که با ردیابی خودکار موقعیت؛ مکان یابی و تشخیص فعالیت؛ آگاهی از موقعیت را به اپلیکیشن شما اضافه می کند.
این آموزش به شما نشان می دهد که چگونه می توانید از خدمات مبتنی بر موقعیت در APP خودتان استفاده نمایید تا بتوانید به موقعیت فعلی، به روز رسانی های متناوب موقعیت، جستجوی آدرسها و غیره دست پیدا کنید.
شیء موقعیت
شیء Location ارائه دهنده یک موقعیت جغرافیایی است که می تواند از عرض جغرافیایی، طول جغرافیایی، تایم استمپ و سایر اطلاعات مانند جهت یابی، ارتفاع و سرعت تشکیل شود. روشهای مهم زیر وجود دارد که می توانید با استفاده از شیء Location می توانید اطلاعات خاصی از یک موقعیت ویژه را به دست آورید:
ردیف | متد و توضیح آن |
۱ |
Float distance To(Location dest) فاصله تقریبی بین این موقعیت و موقعیت داده شده را بر حسب متر باز می گرداند. |
۲ |
Float getAccuracy() دقت برآورد شده از این موقعیت بر حسب متر را ایجاد می کند. |
۳ |
Double getAltitude() ارتفاع را در صورت وجود؛ بر حسب متر از سطح دریا ایجاد می کند. |
۴ |
Float getBearing() جهت را بر حسب درجه بیان می کند. |
۵ |
Double getLatitude() عرض جغرافیایی را بر حسب درجه در اختیار شما می گذارد. |
۶ |
Double getLongitude() طول جغرافیایی را بر حسب درجه در اختیار شما می گذارد. |
۷ |
Float getSpeed() اگر سرعت در دسترس باشد؛ بر حسب متر بر ثانیه بر روی زمین در اختیار شما قرار می دهد. |
۸ |
Boolean has Accuracy() اگر این موقعیت؛ دقت داشته باشد؛ True را باز می گرداند. |
۹ |
Boolean has Altitude() اگر این موقعیت یک ارتفاع از سطح دریا داشته باشد؛ True را باز می گرداند. |
۱۰ |
Boolean hasBearing() اگر این موقعیت زاویه حامل داشته باشد؛ True را باز می گرداند. |
۱۱ |
Boolean hasSpeed() اگر این موقعیت سرعتی داشته باشد؛ مقدار True را باز می گرداند. |
۱۲ |
Void reset محتوای موقعیت را پاک می کند. |
۱۳ |
void setAccuracy(float accuracy) دقت برآورد شده این موقعیت را بر حسب متر تنظیم می کند. |
۱۴ |
void setAltitude(double altitude) ارتفاع از سطح دریا را بر حسب متر تنظیم می کند. |
۱۵ |
void setBearing(float bearing) تنظیم زاویه حامل بر حسب درجه |
۱۶ |
void setLatitude (double latitude) عرض جغرافیایی را بر حسب درجه تنظیم می کند. |
۱۷ |
void setLongitude (double longitude) طول جغرافیایی را بر حسب درجه تنظیم می کند. |
۱۸ |
void setSpeed (float speed) سرعت روی زمین را بر حسب متر بر ثانیه تنظیم می کند. |
۱۹ |
String toString() یک رشته را باز می گرداند که توضیحات مختصری از این شیء ارائه می دهد که توسط انسان خوانده می شود. |
دریافت موقعیت فعلی
برای دریافت موقعیت فعلی، یک سرویس دهنده موقعیت مکانی ایجاد می کنید که شیء LocationClient می باشد و با استفاده از متد ()connect آن را به سرویس های موقعیت متصل کرده، و سپس متد ()getLastLocation آن را فراخوانی می کنید. این متد، جدیدترین مکان را به صورت شیء Location باز می گرداند که شامل مختصات طول و عرض جغرافیایی و سایر اطلاعات می باشد که در بالا توضیح داده می شود. برای داشتن عملکردی مبتنی بر موقعیت مکانی در activity تان، باید دو رابط را پیاده سازی کنید –
- GooglePlayServicesClient.ConnectionCallbacks
- GooglePlayServicesClient.OnConnectionFailedListener
این رابط ها؛ متدهای کال بک مهم زیر را فراخوانی می کند که شما برای پیاده سازی کلاس فعالیت خودتان به آنها نیاز دارید:
ردیف | متدهای کال بک و توضیح آنها |
۱ |
abstract void onConnected(Bundle connectionHint) این متد کال بک زمانی فراخوانی می شود که سرویس به صورت موفقیت آمیز به گیرنده خدمات موقعیت متصل شود. شما از متد ()Connect استفاده خواهید کرد تا به گیرنده خدمات موقعیت متصل شوید. |
۲ |
abstract void onDisconnected() این متد کال بک زمانی فراخوانی می شود که ارتباط گیرنده خدمات قطع می شود. شما از متد ()disconnect استفاده می کنید تا ارتباط گیرنده خدمات موقعیت را قطع کنید. |
۳ |
abstract void onConnectionFailed(connectionResult result) این متد کال بک زمانی فراخوانی میشود که برای اتصال گیرنده خدمات موقعیت به آن خدمات، خطایی وجود داشته باشد. |
شما باید در متد ()onCreate کلاس activity یک گیرنده خدمات موقعیت ایجاد کنید؛ سپس آن را به ()onStart متصل کنید؛ به صورتی که خدمات موقعیت، موقعیت فعلی را حفظ می کند، در حالی که activity شما کاملاً قابل رویت است. شما باید ارتباط گیرنده خدمات در متد ()onStop را قطع کنید؛ به صورتی که زمانی که اپلیکیشن شما قابل رویت نباشد؛ خدمات موقعیت، مکان فعلی را حفظ نمی کند. این امر به حفظ باتری و صرفه جویی در انرژی باتری کمک زیادی می کند.
دریافت موقعیت به روز رسانی شده
اگر می خواهید به روز رسانی های موقعیت مکانی را داشته باشید؛ سپس جدا از رابط های ذکر شده؛ شما باید رابط LocationListener را نیز پیاده سازی کنید. این رابط متد کال بک زیر را ارائه می کند؛ که شما باید در کلاس activity خودتان پیاده سازی کنید.
ردیف | متد کال بک و توضیح |
۱ |
Abstract void onLocationChanged(Location location) این متد کال بک، زمانی که موقعیت تغییر کند؛ برای دریافت نوتیفیکیشن ها از LocationClient به کار می رود. |
کیفیت موقعیت مکانی سرویس
شیء LocationRequest برای درخواست کیفیت خدمات (QoS) برای به روز رسانی های موقعیت مکانی از LocationClient به کار می رود. در جدول زیر، روش های مفید تنظیم کننده ای وجود دارد که می توانید از آنها برای کنترل QoS استفاده کنید. روش های معادل گیرنده در دسترس است که می توانید در مستندات رسمی Android بررسی کنید.
ردیف | متد و توضیح آن |
۱ |
setExpirationDuration(long millis) تنظیم مدت زمان درخواست بر حسب میلی ثانیه |
۲ |
setExpirationTime(long millis) تنظیم زمان انقضای درخواست؛ بر حسب میلی ثانیه از زمان بوت شودن |
۳ |
setFastestInterval (long millis) سریعترین فاصله برای به روز رسانی های موقعیت صریحاً بر حسب میلی ثانیه تنظیم می شود |
۴ |
setInterval(long mills) تنظیم فاصله مورد نیاز برای به روز رسانی های موقعیت فعال، بر حسب میلی ثانیه |
۵ |
setNumUpdates(int numUdates) تنظیم تعداد به روز رسانی های موقعیت مکانی |
۶ |
setPrriority(int priority) تنظیم اولویت درخواست |
اکنون برای مثال؛ اگر اپلیکیشن شما؛ موقعیت مکانی با دقت بالایی بخواهد؛ باید یک درخواست موقعیت ایجاد کند؛ همچنین باید (setPriority(int را به PRIORITY_HIGH_ACCURACY تنظیم کنید و نیز (setInterval(long را روی ۵ ثانیه قرار دهید. شما همچنین می توانید از فاصله زمانی بزرگتر و/یا دیگر ویژگی هایی مانند PRIORITY_LOW_POWER برای درخواست دقت در سطح “شهر(city)” یا PRIORITY_BALANCED_POWER_ACCURACY برای درخواست دقت در سطح “بلوک” استفاده کنید.
فعالیت ها هنگام ورود به پس زمینه باید قویاً حذف کل درخواست موقعیت مکانی را در نظر بگیرند (برای مثال از ()onPause استفاده کنند) یا حداقل این که به منظور صرفه جویی در انرژی مصرفی؛ درخواست را با یک فاصله زمانی بزرگتر یا کیفیت پایین تر جا به جا کنند.
نمایش آدرس موقعیت مکانی
زمانی که شما شیء Location را در اختیار دارید؛ می توانید از متد ()Geocoder.getFromLocation استفاده کنید تا آدرس را برای یک طول و عرض جغرافیایی دریافت نمایید. این متد همزمان است و ممکن است برای انجام وظیفه خود؛ وقت زیادی را صرف کند، بنابراین شما باید متد ()doInBackground را از کلاس AsyncTask فراخوانی کنید.
همچنین AsyncTask باید یک کلاس فرعی باشد تا مورد استفاده قرار گیرد و کلاس فرعی متد (doInBackground (Params را اورراید خواهد کرد تا یک وظیفه را در پس زمینه انجام دهد و روش (onPostExecute(Result پس از آن که محاسبات تمام شد و در زمان نمایش نتیجه؛ روی سری پیام های UI فراخوانی می شود. یک متد مهم دیگر در AyncTask وجود دارد که (execute(Params … params می باشد، این متد، وظیفه را با پارامترهای مشخص شده ای انجام می دهد.
مثال
مثال زیر به شما نشان می دهد که چگونه از خدمات Location در اپلیکیشن خودتان استفاده کنید تا به موقعیت مکانی فعلی و آدرس های معادل برای آن دست پیداد کنید.
برای آزمایش این مثال، به یک دستگاه تلفن همراه واقعی مجهز به جدیدترین سیستم عامل اندروید نیاز خواهید داشت، در غیر این صورت مجبور خواهید بود با شبیه ساز درگیر شوید؛ زیرا ممکن است درست کار نکند.
ایجاد یک اپلیکیشن اندروید
مرحله | توضیح |
۱ | شما از استودیو اندروید IDE برای ایجاد اپلیکیشن اندروید استفاده می کنید و آن را تحت بسته ی com.example.tutorialspoint7.mayapplication به صورت Tutorialspoint نام گذاری کنید. |
۲ | افزودن فایل src/GPSTracker.java و کد مورد نیاز |
۳ | اصلاح فایل src/MainActivity.java و افزودن کد مورد نظر همان طور که در ادامه نشان داده است؛ برای مراقبت از دریافت موقعیت فعلی و آدرس معادل آن. |
۴ | اصلاح فایلXMLصفحه بندی res/layout/activity_main.xml برای افزودن تمام مؤلفه های GUI که شامل ۳ دکمه و دو نمایش متنی برای نشان دادن آدرس/موقعیت مکانی است. |
۵ | اصلاح res/values/strings.xml برای تعریف مقادیر ثابت مورد نیاز |
۶ | اصلاح AndroidManifest.xml همان طور که در ادامه نشان داده شده است. |
۷ | اجرای اپلیکیشن برای راه اندازی شبیه ساز اندروید و تأیید این که نتیجه تغییرات در اپلیکیشن انجام شده است. |
در ادامه محتوای فایل activity اصلی اصلاح شده MainActivity.java را مشاهده می کنید:
package com.example.tutorialspoint7.myapplication;
import android.Manifest;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.test.mock.MockPackageManager;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
Button btnShowLocation;
private static final int REQUEST_CODE_PERMISSION = 2;
String mPermission = Manifest.permission.ACCESS_FINE_LOCATION;
// GPSTracker class
GPSTracker gps;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
if (ActivityCompat.checkSelfPermission(this, mPermission)
!= MockPackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{mPermission},
REQUEST_CODE_PERMISSION);
// If any permission above not allowed by user, this condition will
execute every time, else your else part will work
}
} catch (Exception e) {
e.printStackTrace();
}
btnShowLocation = (Button) findViewById(R.id.button);
// show location button click event
btnShowLocation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// create class object
gps = new GPSTracker(MainActivity.this);
// check if GPS enabled
if(gps.canGetLocation()){
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
// n is for new line
Toast.makeText(getApplicationContext(), “Your Location is – nLat: “
+ latitude + “nLong: ” + longitude, Toast.LENGTH_LONG).show();
}else{
// can’t get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
}
}
});
}
}
در ادمه محتوای فایل activity اصلاح شده ی اصلی GPSTracker.java. آورده شده است.
package com.example.tutorialspoint7.myapplication;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
public class GPSTracker extends Service implements LocationListener {
private final Context mContext;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
// Declaring a Location Manager
protected LocationManager locationManager;
public GPSTracker(Context context) {
this.mContext = context;
getLocation();
}
public Location getLocation() {
try {
locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
برنامه نویسی اندروید رو قورت بده! بدون کلاس، سرعت 2 برابر، ماندگاری 3 برابر، پولسازی با ساخت اپلیکیشن و بازی، سه پک زیر جوابت هست:
// getting GPS status
isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled) {
// no network provider is enabled
} else {
this.canGetLocation = true;
// First get location from Network Provider
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d(“Network”, “Network”);
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled) {
if (location == null) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d(“GPS Enabled”, “GPS Enabled”);
if (locationManager != null) {
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
/**
* Stop using GPS listener
* Calling this function will stop using GPS in your app
* */
public void stopUsingGPS(){
if(locationManager != null){
locationManager.removeUpdates(GPSTracker.this);
}
}
/**
* Function to get latitude
* */
public double getLatitude(){
if(location != null){
latitude = location.getLatitude();
}
// return latitude
return latitude;
}
/**
* Function to get longitude
* */
public double getLongitude(){
if(location != null){
longitude = location.getLongitude();
}
// return longitude
return longitude;
}
/**
* Function to check GPS/wifi enabled
* @return boolean
* */
public boolean canGetLocation() {
return this.canGetLocation;
}
/**
* Function to show settings alert dialog
* On pressing Settings button will lauch Settings Options
* */
public void showSettingsAlert(){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle(“GPS is settings”);
// Setting Dialog Message
alertDialog.setMessage(“GPS is not enabled. Do you want to go to settings menu?”);
// On pressing Settings button
alertDialog.setPositiveButton(“Settings”, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
}
});
// on pressing cancel button
alertDialog.setNegativeButton(“Cancel”, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
// Showing Alert Message
alertDialog.show();
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
در بخش زیر محتوای فایل res/layout/activity_main.xml آورده شده است:
<?xml version = “1.0” encoding = “utf-8”?>
<LinearLayout xmlns:android = “http://schemas.android.com/apk/res/android”
android:layout_width = “fill_parent”
android:layout_height = “fill_parent”
android:orientation = “vertical” >
<Button
android:id = “@+id/button”
android:layout_width = “fill_parent”
android:layout_height = “wrap_content”
android:text = “getlocation”/>
</LinearLayout>
محتوای res/values/strings.xml برای تعریف دو ثابت جدید؛ در زیر آورده شده است:
<?xml version = “1.0” encoding = “utf-8”?>
<resources>
<string name = “app_name”>Tutorialspoint</string>
</resources>
در ادامه محتوای پیشفرض AndroidManifest.xml را مشاهده می کنید.
<?xml version = “1.0” encoding = “utf-8”?>
<manifest xmlns:android = “http://schemas.android.com/apk/res/android”
package = “com.example.tutorialspoint7.myapplication”>
<uses-permission android:name = “android.permission.ACCESS_FINE_LOCATION” />
<uses-permission android:name = “android.permission.INTERNET” />
<application
android:allowBackup = “true”
android:icon = “@mipmap/ic_launcher”
android:label = “@string/app_name”
android:supportsRtl = “true”
android:theme = “@style/AppTheme”>
<activity android:name = “.MainActivity”>
<intent-filter>
<action android:name = “android.intent.action.MAIN” />
<category android:name = “android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
</application>
</manifest>
بیایید سعی کنیم اپلیکیشن Tutorialspoint شما را اجرا کنیم. فرض می کنیم که شما دستگاه موبایل اندروید واقعی تان را به کامپیوترتان متصل کرده اید. برای اجرای اپلیکیشن از استودیو اندروید؛ یکی از فایل های activity پروژه خودتان را باز کنید و روی آیکون اجرا کلیک کنید که در قسمت نوار ابزار قرار گرفته است. قبل از این که برنامه تان اجرا شود؛ نصب کننده ی استودیو اندروید پنجره زیر را نشان می دهد تا گزینه ای را انتخاب نمایید که می خواهید اپلیکیشن اندرویدتان را در آن اجرا بکنید.
اکنون برای آن که موقعیت مکانی را ببینید؛ دکمه Get Location را انتخاب کنید که اطلاعات موقعیت مکانی را به صورت زیر نشان می دهد: