Android - Dịch vụ dựa trên vị trí
API vị trí của Android giúp bạn dễ dàng tạo các ứng dụng nhận biết vị trí mà không cần tập trung vào chi tiết của công nghệ vị trí cơ bản.
Điều này trở nên khả thi với sự trợ giúp của Google Play services, tạo điều kiện thuận lợi cho việc thêm nhận thức về vị trí vào ứng dụng của bạn với tính năng theo dõi vị trí tự động, xác định địa lý và nhận dạng hoạt động.
Hướng dẫn này chỉ cho bạn cách sử dụng Dịch vụ vị trí trong APP của bạn để nhận vị trí hiện tại, cập nhật vị trí định kỳ, tra cứu địa chỉ, v.v.
Đối tượng Vị trí
Các Locationđối tượng đại diện cho một vị trí địa lý có thể bao gồm vĩ độ, kinh độ, dấu thời gian và các thông tin khác như độ cao, độ cao và vận tốc. Có các phương pháp quan trọng sau mà bạn có thể sử dụng với đối tượng Vị trí để nhận thông tin cụ thể về vị trí -
Sr.No. | Phương pháp & Mô tả |
---|---|
1 | float distanceTo(Location dest) Trả về khoảng cách gần đúng tính bằng mét giữa vị trí này và vị trí đã cho. |
2 | float getAccuracy() Nhận độ chính xác ước tính của vị trí này, tính bằng mét. |
3 | double getAltitude() Lấy độ cao nếu có, tính bằng mét trên mực nước biển. |
4 | float getBearing() Lấy vòng bi, tính bằng độ. |
5 | double getLatitude() Lấy vĩ độ, tính bằng độ. |
6 | double getLongitude() Lấy kinh độ, tính bằng độ. |
7 | float getSpeed() Nhận tốc độ nếu có, tính bằng mét / giây so với mặt đất. |
số 8 | boolean hasAccuracy() Đúng nếu vị trí này có độ chính xác. |
9 | boolean hasAltitude() Đúng nếu vị trí này có độ cao. |
10 | boolean hasBearing() Đúng nếu vị trí này có ổ trục. |
11 | boolean hasSpeed() Đúng nếu vị trí này có tốc độ. |
12 | void reset() Xóa nội dung của vị trí. |
13 | void setAccuracy(float accuracy) Đặt độ chính xác ước tính của vị trí này, mét. |
14 | void setAltitude(double altitude) Đặt độ cao, tính bằng mét trên mực nước biển. |
15 | void setBearing(float bearing) Đặt ổ trục, theo độ. |
16 | void setLatitude(double latitude) Đặt vĩ độ, tính bằng độ. |
17 | void setLongitude(double longitude) Đặt kinh độ, tính bằng độ. |
18 | void setSpeed(float speed) Đặt tốc độ, tính bằng mét / giây trên mặt đất. |
19 | String toString() Trả về một chuỗi chứa mô tả ngắn gọn, con người có thể đọc được về đối tượng này. |
Nhận vị trí hiện tại
Để có được vị trí hiện tại, hãy tạo một ứng dụng khách định vị LocationClient đối tượng, kết nối nó với Dịch vụ vị trí bằng connect() và sau đó gọi nó getLastLocation()phương pháp. Phương thức này trả về vị trí gần đây nhất ở dạngLocationđối tượng có chứa vĩ độ và kinh độ và các thông tin khác như đã giải thích ở trên. Để có chức năng dựa trên vị trí trong hoạt động của bạn, bạn sẽ phải triển khai hai giao diện -
- GooglePlayServicesClient.ConnectionCallbacks
- GooglePlayServicesClient.OnConnectionFailedListener
Các giao diện này cung cấp các phương thức gọi lại quan trọng sau đây mà bạn cần triển khai trong lớp hoạt động của mình -
Sr.No. | Phương thức gọi lại & Mô tả |
---|---|
1 | abstract void onConnected(Bundle connectionHint) Phương thức gọi lại này được gọi khi dịch vụ vị trí được kết nối thành công với máy khách vị trí. Bạn sẽ sử dụngconnect() phương pháp để kết nối với máy khách định vị. |
2 | abstract void onDisconnected() Phương thức gọi lại này được gọi khi máy khách bị ngắt kết nối. Bạn sẽ sử dụngdisconnect() phương pháp ngắt kết nối khỏi ứng dụng khách vị trí. |
3 | abstract void onConnectionFailed(ConnectionResult result) Phương thức gọi lại này được gọi khi có lỗi khi kết nối máy khách với dịch vụ. |
Bạn nên tạo ứng dụng khách vị trí trong onCreate() phương pháp của lớp hoạt động của bạn, sau đó kết nối nó trong onStart(), để Dịch vụ vị trí duy trì vị trí hiện tại trong khi hoạt động của bạn hiển thị đầy đủ. Bạn nên ngắt kết nối khách hàng trong onStop()để khi ứng dụng của bạn không hiển thị, Dịch vụ vị trí sẽ không duy trì vị trí hiện tại. Điều này giúp tiết kiệm pin ở mức độ lớn.
Nhận vị trí cập nhật
Nếu bạn sẵn sàng cập nhật vị trí, thì ngoài các giao diện được đề cập ở trên, bạn sẽ cần phải triển khai LocationListenergiao diện. Giao diện này cung cấp phương thức gọi lại sau đây mà bạn cần triển khai trong lớp hoạt động của mình -
Sr.No. | Phương pháp gọi lại & Mô tả |
---|---|
1 | abstract void onLocationChanged(Location location) Phương thức gọi lại này được sử dụng để nhận thông báo từ LocationClient khi vị trí đã thay đổi. |
Vị trí Chất lượng Dịch vụ
Các LocationRequest đối tượng được sử dụng để yêu cầu chất lượng dịch vụ (QoS) cho các bản cập nhật vị trí từ LocationClient. Có các phương pháp setter hữu ích sau đây mà bạn có thể sử dụng để xử lý QoS. Có sẵn các phương pháp getter tương đương mà bạn có thể kiểm tra trong tài liệu chính thức của Android.
Sr.No. | Phương pháp & Mô tả |
---|---|
1 | setExpirationDuration(long millis) Đặt thời lượng của yêu cầu này, tính bằng mili giây. |
2 | setExpirationTime(long millis) Đặt thời gian hết hạn yêu cầu, tính bằng mili giây kể từ khi khởi động. |
3 | setFastestInterval(long millis) Đặt rõ ràng khoảng thời gian cập nhật vị trí nhanh nhất, tính bằng mili giây. |
4 | setInterval(long millis) Đặt khoảng thời gian mong muốn để cập nhật vị trí đang hoạt động, tính bằng mili giây. |
5 | setNumUpdates(int numUpdates) Đặt số lượng cập nhật vị trí. |
6 | setPriority(int priority) Đặt mức độ ưu tiên của yêu cầu. |
Ví dụ: nếu ứng dụng của bạn muốn vị trí có độ chính xác cao, nó sẽ tạo một yêu cầu vị trí với setPriority(int) đặt thành PRIORITY_HIGH_ACCURACY và setInterval(long)đến 5 giây. Bạn cũng có thể sử dụng khoảng thời gian lớn hơn và / hoặc các mức độ ưu tiên khác như PRIORITY_LOW_POWER để yêu cầu độ chính xác cấp "thành phố" hoặc PRIORITY_BALANCED_POWER_ACCURACY cho độ chính xác cấp "khối".
Các hoạt động nên xem xét việc loại bỏ tất cả yêu cầu vị trí khi vào nền (ví dụ tại onPause ()), hoặc ít nhất là hoán đổi yêu cầu sang khoảng thời gian lớn hơn và chất lượng thấp hơn để tiết kiệm điện năng tiêu thụ.
Hiển thị Địa chỉ Vị trí
Một khi bạn có Location đối tượng, bạn có thể sử dụng Geocoder.getFromLocation()để lấy địa chỉ cho một vĩ độ và kinh độ nhất định. Phương thức này là đồng bộ và có thể mất nhiều thời gian để thực hiện công việc của nó, vì vậy bạn nên gọi phương thức từdoInBackground() phương pháp của một AsyncTask lớp học.
Các AsyncTask phải được phân lớp để được sử dụng và lớp con sẽ ghi đè doInBackground(Params...) phương pháp để thực hiện một tác vụ trong nền và onPostExecute(Result)phương thức được gọi trên chuỗi giao diện người dùng sau khi quá trình tính toán nền kết thúc và tại thời điểm hiển thị kết quả. Có một phương pháp quan trọng hơn có sẵn trong AyncTask làexecute(Params... params), phương thức này thực thi tác vụ với các tham số được chỉ định.
Thí dụ
Ví dụ sau đây cho bạn thấy thực tế cách sử dụng Dịch vụ vị trí trong ứng dụng của bạn để nhận vị trí hiện tại và các địa chỉ tương đương của nó, v.v.
Để thử nghiệm với ví dụ này, bạn sẽ cần thiết bị Di động thực tế được trang bị Hệ điều hành Android mới nhất, nếu không, bạn sẽ phải vật lộn với trình giả lập có thể không hoạt động.
Tạo ứng dụng Android
Bươc | Sự miêu tả |
---|---|
1 | Bạn sẽ sử dụng Android studio IDE để tạo một ứng dụng Android và đặt tên là Tutorialspoint theo gói com.example.tutorialspoint7.myapplication . |
2 | thêm tệp src / GPSTracker.java và thêm mã bắt buộc. |
3 | Sửa đổi tệp src / MainActivity.java và thêm mã bắt buộc như được hiển thị bên dưới để xử lý vị trí hiện tại và địa chỉ tương đương của nó. |
4 | Sửa đổi tệp XML bố cục res / layout / activity_main.xml để thêm tất cả các thành phần GUI bao gồm ba nút và hai dạng xem văn bản để hiển thị vị trí / địa chỉ. |
5 | Sửa đổi res / giá trị / string.xml để xác định các giá trị hằng số bắt buộc |
6 | Sửa đổi AndroidManifest.xml như hình dưới đây |
7 | Chạy ứng dụng để khởi chạy trình giả lập Android và xác minh kết quả của các thay đổi được thực hiện trong ứng dụng. |
Sau đây là nội dung của tệp hoạt động chính được sửa đổi 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();
}
}
});
}
}
Sau đây là nội dung của tệp hoạt động chính được sửa đổi 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);
// 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;
}
}
Sau đây sẽ là nội dung của res/layout/activity_main.xml tập tin -
<?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>
Sau đây sẽ là nội dung của res/values/strings.xml để xác định hai hằng số mới -
<?xml version = "1.0" encoding = "utf-8"?>
<resources>
<string name = "app_name">Tutorialspoint</string>
</resources>
Sau đây là nội dung mặc định của 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>
Hãy cố gắng chạy Tutorialspointứng dụng. Tôi giả định rằng, bạn đã kết nối thiết bị di động Android thực tế với máy tính của mình. Để chạy ứng dụng từ Android Studio, hãy mở một trong các tệp hoạt động của dự án của bạn và nhấp vào
Bây giờ để xem vị trí, hãy chọn nút Lấy vị trí sẽ hiển thị thông tin vị trí như sau: