سرویسهای مبتنی بر موقعیت
آموزش سرویسهای مبتنی بر موقعیت Location Based در اندروید
Android Location Based Services
API های مکانی اندروید بدون اینکه نیاز باشد به جزئیات مربوط به فن آوری مکان تمرکز کنیم ساخت برنامه های مکان نما را برای ما آسان می کنند . این امر با کمک خدمات Google Play امکان پذیر می شود، که افزودن آگاهی از موقعیت را با تقسیم بندی خودکار موقعیت، geofencing و شناسایی فعالیت آسان می کند.
این آموزش به شما نشان می دهد که چگونه از خدمات مکانی در برنامه ی خود استفاده کنید تا مکان کنونی و آپدیت های دوره ای موقعیت را بگیرید و یا چگونه به دنبال آدرس ها بگردید و غیره.
شئ موقعیت
آبجکت موقعیت نشان می دهد که یک موقعیت جغرافیایی می تواند شامل عرض جغرافیایی، طول جغرافیایی و جدول زمانی و دیگر اطلاعات مانند جهت و ارتفاع باشد. در زیر متد های مهمی وجود دارند که می توانید با شئ مکان برای گرفتن اطلاعات یک مکان خاص از آنها استفاده کنید.
-
float distanceTo(Location dest)
مسافت بین این موقعیت و موقعیت داده شده را به متر برمی گرداند. -
float getAccuracy()
صحت تقریبی این موقعیت را به متر به دست می آورد. -
double getAltitude()
ارتفاع از سطح دریا را، اگر در دسترس باشد، به دست می آورد. -
float getBearing()
جهت را به درجه به دست می آورد. -
double getLatitude()
عرض جغرافیایی را به درجه به دست می آورد. - double getLongitude()
طول جغرافیایی را به درجه به دست می آورد. -
float getSpeed()
سرعت را اگر در دسترس باشد، در متر بر ثانیه به دست می آورد. -
boolean hasAccuracy()
درست، اگر این موقعیت درست باشد. -
boolean hasAltitude()
درست، اگر این موقعیت دارای ارتفاع باشد. -
boolean hasBearing()
درست، اگر این موقعیت دارای جهت باشد. -
boolean hasSpeed()
درست، اگر این موقعیت دارای سرعت باشد. -
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() به خدمات موقعیت (Location Services) متصل شوید و سپس متد getLastLocation() آن را فرا بخوانید. این متد آخرین موقعیت را به فرم شئ موقعیت برمی گرداند که شامل مختصات طول و عرض جغرافیایی و دیگر اطلاعاتی که در بالا توضیح داده شد، می باشد. برای داشتن کاربرد موقعیت محور در فعالیت خود، باید دو اینترفیس را اجرا کنید.
- GooglePlayServicesClient.ConnectionCallbacks
- GooglePlayServicesClient.OnConnectionFailedListener
این اینترفیس ها متد های مهم call back را ارائه می دهند که شما برای اجرای فعالیت گروه خود نیاز دارید. برخی از این متد های مهم عبارتند از:
-
abstract void onConnected(Bundle connectionHint)
این متد callBack زمانی فراخوانده می شود که سرویس موقعیت به موقعیت کابر به طور موفقیت آمیزی متصل شود. شما از متد connect() برای اتصال به موقعیت کاربر استفاده خواهید کرد. -
abstract void onDisconnected()
این متد کال بک زمانی فراخوانده می شود که اتصال کاربرقطع شده باشد. شما از متد disconnect() برای قطع شدن از موقعیت کاربر استفاده خواهید کرد. -
abstract void onConnectionFailed(ConnectionResult result)
این متد کال بک زمانی استفاده می شود که در برقراری ارتباط بین کاربر و سرویس خطا وجود داشته باشد.
شما باید در متد onCreate() از فعالیت گروه خود یک موقعیت کاربر ایجاد کنید، سپس آن را به onStart() متصل کنید، طوری که سرویس های موقعیت در هنگامی که فعالیت شما به طور کامل قابل مشاهده است، موقعیت کنونی را نشان دهد. شما باید کاربر را در متد onStop() قطع کنید، طوری که وقتی برنامه ی شما قابل مشاهده نیست، سرویس های موقعیت، موقعیت کنونی را حفظ نکنند. این عمر به حفظ توان باتری برای مدت طولانی کمک می کند.
گرفتن Updated Location
اگر قادر هستید که آپدیت های موقعیت را داشته باشید، علاوه بر اینترفیس های ذکر شده در بالا، لازم است که اینترفیس LocationListener را نیز اجرا کنید. این اینترفیس متد کال بک زیر را ارائه می دهدکه شما برای اجرای فعالیت گروه خود به آن نیاز دارید.
-
abstract void onLocationChanged(Location location)
این متد کال بک برای دریافت اطلاعیه ها از Location Client زمانی که موقعیت عوض شده، استفاده می شود.
کیفیت موقعیت سرویس(Location Quality of Service)
آبجکت LocationRequest برای درخواست کیفیت سرویس (QoS) برای آپدیت های موقعیت از LocationClient استفاده می شود. متودهای آراینده ای وجود دارند که برای رسیدگی به QoS مفید می باشند و در زیر ارائه شده اند. همچنین متد های گیرنده ی هم ارزی وجود که می توانید در اطلاعات رسمی اندروید آنها را چک کنید.
-
setExpirationDuration(long millis)
زمان این تقاضا را به میلی ثانیه تنظیم می کند. -
setExpirationTime(long millis)
زمان انقضای تقاضا را از زمان بوت به میلی ثانیه تنظیم می کند. -
setFastestInterval(long millis)
واضحا سریعترین وقفه را برای آپدیت های موقعیت به میلی ثانیه تنظیم می کند. -
setInterval(long millis)
وقفه ی درخواستی را برای آپدیت های موقعیت فعال به میلی ثانیه تنظیم می کند. -
setNumUpdates(int numUpdates)
تعداد آپدیت های موقعیت را تنظیم می کند. -
setPriority(int priority)
اولویت درخواست را تنظیم می کند.
اکنون به عنوان مثال اگر برنامه ی شما یک موقعیت با میزان درستی خیلی بالا می خواهد، باید یک درخواست موقعیت با setPriority(int) ایجاد کند، برروی PRIORITY_HIGH_ACCURACY تنظیم کرده و setInterval(long) را روی 5 ثانیه تنظیم کند. همچنین می توانید از وقفه های بزرگتر استفاده کنید و یا از دیگر اولویت ها مانند PRIORITY_LOW_POWER برای صحت در سطح شهر و یا PRIORITY_BALANCED_POWER_ACCURACY برای صحت در سطح بلوک.
فعالیت ها باید توجه داشته باشند که در هنگام ورود زمینه تمام درخواست های موقعیت را حذف کنند (برای مثال در onPause()) یا حداقل درخواست را به یک وقفه ی طولانی تر و کیفیت پایین تر تغییر دهند تا مصرف نیروی باتری را ذخیره کنند.
نمایش آدرس یک موقعیت
زمانی که شما آبجکت موقعیت را دارید می توانید از متد Geocoder.getFromLocation() استفاده کنید تا یک آدرس را برای طول و عرض جغرافایی داده شده به دست آورید. این متد یک متد همزمان (synchronous) می باشد و ممکن است انجام کار آن زمان زیادی بگیرد، بنابراین شما باید متد را از متد doInBackground() از یک گروه AsyncTask فرا بخوانید.
AsyncTask برای استفاده باید به زیرگروه هایی تقسیم شود، و زیر گروه متد doInBackground(Params...) را طی می کند تا یک عمل را در زمینه انجام دهد، و پس ازاینکه شمارگری روی زمینه تمام می شود و زمان نمایش نتیجه می باشد، متد onPostExecute(Result) روی رشته ی UI درخواست می شود. یک متد مهم دیگر هم در AyncTask وجود دارد که execute(Params... params) می باشد، این متد کار را با پارامترهای خاصی انجام می دهد.
مثال زیر را بررسی کنید تا درک بهتری از چگونگی استفاده از AynchTask در هر برنامه ی اندروید داشته باشید. مثال زیر در عمل به شما نشان می دهد که چگونه از Location Services در برنامه ی خود استفاده کنید تا موقعیت کنونی و آدرس مربوط به آن و غیره را به دست آورید.
برای آزمایش با این مثال شما به یک موبایل مجهز شده به آخرین نسخه ی Android OS نیاز خواهید داشت. در غیر این صورت مجبور خواهید بود با شبیه ساز انجام دهید که ممکن است به درستی کار نکند.
نصب سرویس های Google play SDK
قبل از اینکه جلوتر بروید تا حمایت موقعیت ها را در برنامه های اندروید خود داشته باشید، لازم است تا خدمات Google Play SDK را با استفاده از مراحل ساده ی زیر، نصب کنید.
-
شروع کننده ی SDK:
· از Eclipse (با ADT) عبارت Window > Android SDK Manager را انتخاب کنید.
· در ویندوز روی فایل SDK Manager.exe در روت از مسیر Android SDK دابل کلیک کنید.
· روی Mac یا Linux یک پایانه باز کنید و به tools/directory در مسیر Android SDK مسیریابی کنید و سپس android sdk را اجرا کنید. - گزینه ی Google Play services را از لیست پکیج ارائه شده در زیر Extra جستجو کنید و اگر نصب نشده است، آن را نصب کنید. خدمات Google Play SDK در محیط Android SDK شما در <android-sdk>/extras/google/google_play_services/ ذخیره می شود.
- پروژه ی کتابخانه را درموقعیت <android-sdk>/extras/google/google_play_services/libproject/google-play-services_lib/ کپی کنید، جایی که شما برنامه های اندروید خود را نگهداری می کنید. اگر شما در حال استفاده از Eclip هستید، برنامه ی کتابخانه را وارد فضای کار خود کنید. روی File > Import کلیک کنید و Android > Existing Android Code into Workspace را انتخاب کنید و در <android-sdk>/extras/google/google_play_services/libproject/ برنامه ی کتابخانه فهرست کنید تا وارد شود.
ایجاد برنامه ی اندروید
- شما از Eclipse IDE برای ایجاد برنامه ی اندروید استفاده خواهید کرد وآن را زیر بسته ی com.example.lbsdemo به عنوان LBSDemo/i> نامگذاری کنید. هنگام ایجاد این برنامه مطمئن شوید که SDK وCompile را با آخرین ورژن اندروید SDK هدف قرار داده اید تا از سطوح بالاتر API استفاده کنید.
- کتابخانه Google play Service را با دنبال کردن مراحل ساده ی زیر، به برنامه ی خود اضافه کنید.
- فایل src/MainActivity.java را تا حدی تغییر دهید و کدهای لازم را به آن اضافه کنید، همانطور که در زیر نشان داده شده است، تا از موقعیت کنونی به دست آمده و آدرس های هم تراز آن نگهداری کنید.
- فایل نمایه ی XML را به res/layout/activity_main.xml تغییر دهید تا تمام مولفه های GUI را به آن بیفزایید که شامل سه دکمه و دو ویو متن می باشد تا موقعیت یا آدرس را نمایش دهد.
- res/values/strings.xml را تغییر دهید تا مقادیر ثابت لتزم را تعریف کنید
- AndroidManifest.xml را به شکلی که در زیر نشان داده شده تغییر دهید.
- برنامه را اجرا کنید تا شبیه ساز اندروید آغاز به کار کند و نتایج تغییرات انجام شده در برنامه را بررسی کند.
اجازه دهید Google Play Service را در برنامه اضافه کنیم. روی برنامه راست کلیک کنید و Build Path > Configure Build Path > Android > را انتخاب کنید و سپس دکمه ی Add را کلیک کنید که گزینه ی google-play-service_lib اضافه شدن نشان خواهد داد. فقط روی آن دابل کلیک کنید که مرجع مورد نیاز کتابخانه را اضافه خواهد کرد.
در زیر محتوای src/com.example.Tutorialspoint/MainActivity.java را می بینید
package com.example.Tutorialspoint;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends FragmentActivity implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener
{
LocationClient mLocationClient;
private TextView addressLabel;
private TextView locationLabel;
private Button getLocationBtn;
private Button disconnectBtn;
private Button connectBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locationLabel = (TextView) findViewById(R.id.locationLabel);
addressLabel = (TextView) findViewById(R.id.addressLabel);
getLocationBtn = (Button) findViewById(R.id.getLocation);
getLocationBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
displayCurrentLocation();
}
});
disconnectBtn = (Button) findViewById(R.id.disconnect);
disconnectBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mLocationClient.disconnect();
locationLabel.setText("Got disconnected....");
}
});
connectBtn = (Button) findViewById(R.id.connect);
connectBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mLocationClient.connect();
locationLabel.setText("Got connected....");
}
});
// Create the LocationRequest object
mLocationClient = new LocationClient(this, this, this);
}
@Override
protected void onStart() {
super.onStart();
// Connect the client.
mLocationClient.connect();
locationLabel.setText("Got connected....");
}
@Override
protected void onStop() {
// Disconnect the client.
mLocationClient.disconnect();
super.onStop();
locationLabel.setText("Got disconnected....");
}
@Override
public void onConnected(Bundle dataBundle) {
// Display the connection status
Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
}
@Override
public void onDisconnected() {
// Display the connection status
Toast.makeText(this, "Disconnected. Please re-connect.",Toast.LENGTH_SHORT).show();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// Display the error code on failure
Toast.makeText(this, "Connection Failure : " + connectionResult.getErrorCode(),Toast.LENGTH_SHORT).show();
}
public void displayCurrentLocation() {
// Get the current location's latitude & longitude
Location currentLocation = mLocationClient.getLastLocation();
String msg = "Current Location: " +
Double.toString(currentLocation.getLatitude()) + "," +
Double.toString(currentLocation.getLongitude());
// Display the current location in the UI
locationLabel.setText(msg);
// To display the current address in the UI
(new GetAddressTask(this)).execute(currentLocation);
}
/*
* Following is a subclass of AsyncTask which has been used to get
* address corresponding to the given latitude & longitude.
*/
private class GetAddressTask extends AsyncTask<Location, Void, String>{
Context mContext;
public GetAddressTask(Context context) {
super();
mContext = context;
}
/*
* When the task finishes, onPostExecute() displays the address.
*/
@Override
protected void onPostExecute(String address) {
// Display the current address in the UI
addressLabel.setText(address);
}
@Override
protected String doInBackground(Location... params) {
Geocoder geocoder =new Geocoder(mContext, Locale.getDefault());
// Get the current location from the input parameter list
Location loc = params[0];
// Create a list to contain the result address
<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(loc.getLatitude(),loc.getLongitude(), 1);
}
catch (IOException e1) {
Log.e("LocationSampleActivity",IO Exception in getFromLocation());
e1.printStackTrace();
return ("IO Exception trying to get address");
}
catch (IllegalArgumentException e2) {
// Error message to post in the log
String errorString = "Illegal arguments " +
Double.toString(loc.getLatitude()) +" , " +Double.toString(loc.getLongitude()) +" passed to address service";
Log.e("LocationSampleActivity", errorString);
e2.printStackTrace();
return errorString;
}
// If the reverse geocode returned an address
if (addresses != null && addresses.size() > 0) {
// Get the first address
Address address = addresses.get(0);
/*
* Format the first line of address (if available),
* city, and country name.
*/
String addressText = String.format("%s, %s, %s");
// If there's a street address, add it
address.getMaxAddressLineIndex() > 0 ?
address.getAddressLine(0) : "",
// Locality is usually a city
address.getLocality(),
// The country of the address
address.getCountryName());
// Return the text
return addressText;
}
else {
return "No address found";
}
}
}// AsyncTask class
}
کد زیر محتوای فایل res/layout/activity_main.xml خواهد بود.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Location Example"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textSize="30dp" />
<TextView android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tutorials point "
android:textColor="#ff87ff09"
android:textSize="30dp"
android:layout_below="@+id/textView1"
android:layout_alignRight="@+id/imageButton"
android:layout_alignEnd="@+id/imageButton" />
<ImageButton android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton"
android:src="@drawable/abc"
android:layout_below="@+id/textView2"
android:layout_centerHorizontal="true" />
<Button android:id="@+id/getLocation"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/get_location"/>
<Button android:id="@+id/disconnect"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/disconnect"/>
<Button android:id="@+id/connect"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/connect"/>
<TextView
android:id="@+id/locationLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/addressLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
کد زیر محتوای res/values/strings.xml خواهد بود که برای تعریف دو ثابت جدید به کار می رود.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Tutorialspoint</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="get_location">Get Location</string>
<string name="disconnect">Disconnect Service</string>
<string name="connect">Connect Service</string>
</resources>
کد زیر محتوای پیش فرض AndroidManifest.xml می باشد.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.Tutorialspoint"
android:versionCode="1"
android:versionName="1.0" >
<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="com.example.Tutorialspoint.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>
- نوشته شده توسط سعید نوشادی
- بازدید: 5854