Android - службы на основе местоположения
API-интерфейсы определения местоположения Android упрощают создание приложений, учитывающих местоположение, без необходимости сосредоточиваться на деталях базовой технологии определения местоположения.
Это становится возможным с помощью Google Play services, который упрощает добавление информации о местоположении в ваше приложение с помощью автоматического отслеживания местоположения, геозоны и распознавания активности.
В этом руководстве показано, как использовать службы геолокации в приложении для получения текущего местоположения, периодических обновлений местоположения, поиска адресов и т. Д.
Объект местоположения
В LocationОбъект представляет географическое местоположение, которое может состоять из широты, долготы, отметки времени и другой информации, такой как азимут, высота и скорость. Существуют следующие важные методы, которые вы можете использовать с объектом Location для получения информации о местоположении:
Sr. No. | Метод и описание |
---|---|
1 | float distanceTo(Location dest) Возвращает приблизительное расстояние в метрах между этим местоположением и заданным местоположением. |
2 | float getAccuracy() Получите приблизительную точность этого местоположения в метрах. |
3 | double getAltitude() Получите высоту, если возможно, в метрах над уровнем моря. |
4 | float getBearing() Получите азимут в градусах. |
5 | double getLatitude() Получите широту в градусах. |
6 | double getLongitude() Получите долготу в градусах. |
7 | float getSpeed() Получите скорость, если она доступна, в метрах / секунду относительно земли. |
8 | boolean hasAccuracy() Истинно, если это местоположение имеет точность. |
9 | boolean hasAltitude() Истинно, если у этого местоположения есть высота. |
10 | boolean hasBearing() Верно, если это место имеет азимут. |
11 | boolean hasSpeed() Верно, если у этой локации есть скорость. |
12 | void reset() Очищает содержимое локации. |
13 | void setAccuracy(float accuracy) Задайте расчетную точность этого местоположения в метрах. |
14 | void setAltitude(double altitude) Установите высоту в метрах над уровнем моря. |
15 | void setBearing(float bearing) Установите азимут в градусах. |
16 | void setLatitude(double latitude) Установите широту в градусах. |
17 | void setLongitude(double longitude) Установите долготу в градусах. |
18 | void setSpeed(float speed) Установите скорость относительно земли в метрах / секунду. |
19 | String toString() Возвращает строку, содержащую краткое, удобочитаемое описание этого объекта. |
Получить текущее местоположение
Чтобы получить текущее местоположение, создайте клиент местоположения, который LocationClient объект, подключите его к службам определения местоположения, используя connect() метод, а затем вызовите его getLastLocation()метод. Этот метод возвращает самое последнее местоположение в видеLocationобъект, который содержит координаты широты и долготы и другую информацию, как описано выше. Чтобы иметь функциональность на основе местоположения в вашей деятельности, вам нужно будет реализовать два интерфейса:
- GooglePlayServicesClient.ConnectionCallbacks
- GooglePlayServicesClient.OnConnectionFailedListener
Эти интерфейсы предоставляют следующие важные методы обратного вызова, которые вам необходимо реализовать в своем классе активности:
Sr. No. | Методы и описание обратного вызова |
---|---|
1 | abstract void onConnected(Bundle connectionHint) Этот метод обратного вызова вызывается, когда служба определения местоположения успешно подключается к клиенту определения местоположения. Вы будете использоватьconnect() метод подключения к клиенту местоположения. |
2 | abstract void onDisconnected() Этот метод обратного вызова вызывается при отключении клиента. Вы будете использоватьdisconnect() метод отключения от клиента местоположения. |
3 | abstract void onConnectionFailed(ConnectionResult result) Этот метод обратного вызова вызывается, когда произошла ошибка при подключении клиента к службе. |
Вы должны создать клиент местоположения в onCreate() метод вашего класса активности, затем подключите его в onStart(), чтобы службы геолокации поддерживали текущее местоположение, пока ваши действия полностью видны. Вы должны отключить клиента в onStop(), поэтому, когда ваше приложение не отображается, службы геолокации не поддерживают текущее местоположение. Это в значительной степени помогает экономить заряд аккумулятора.
Получить обновленное местоположение
Если вы хотите получать обновления местоположения, то помимо вышеупомянутых интерфейсов вам нужно будет реализовать LocationListenerинтерфейс. Этот интерфейс предоставляет следующий метод обратного вызова, который вам необходимо реализовать в своем классе активности:
Sr. No. | Метод и описание обратного вызова |
---|---|
1 | abstract void onLocationChanged(Location location) Этот метод обратного вызова используется для получения уведомлений от LocationClient при изменении местоположения. |
Местоположение Качество обслуживания
В LocationRequest объект используется для запроса качества обслуживания (QoS) для обновлений местоположения от LocationClient. Существуют следующие полезные методы установки, которые вы можете использовать для обработки QoS. Доступны эквивалентные методы получения, которые вы можете проверить в официальной документации Android.
Sr. No. | Метод и описание |
---|---|
1 | setExpirationDuration(long millis) Задайте продолжительность этого запроса в миллисекундах. |
2 | setExpirationTime(long millis) Установите время истечения срока действия запроса в миллисекундах с момента загрузки. |
3 | setFastestInterval(long millis) Явно задайте самый быстрый интервал для обновления местоположения в миллисекундах. |
4 | setInterval(long millis) Установите желаемый интервал для обновления активного местоположения в миллисекундах. |
5 | setNumUpdates(int numUpdates) Установите количество обновлений местоположения. |
6 | setPriority(int priority) Установите приоритет запроса. |
Теперь, например, если вашему приложению требуется высокая точность определения местоположения, оно должно создать запрос местоположения с setPriority(int) установите PRIORITY_HIGH_ACCURACY и setInterval(long)до 5 секунд. Вы также можете использовать больший интервал и / или другие приоритеты, такие как PRIORITY_LOW_POWER для запроса точности уровня «города» или PRIORITY_BALANCED_POWER_ACCURACY для точности уровня «блока».
Действиям следует настоятельно рассмотреть возможность удаления всех запросов местоположения при входе в фоновый режим (например, в onPause ()) или, по крайней мере, заменить запрос на больший интервал и более низкое качество для экономии энергопотребления.
Отображение адреса местонахождения
Как только у вас есть Location объект, вы можете использовать Geocoder.getFromLocation()для получения адреса по заданной широте и долготе. Этот метод является синхронным, и выполнение его работы может занять много времени, поэтому вам следует вызвать метод изdoInBackground() метод AsyncTask класс.
В AsyncTask должен быть подклассом для использования, и подкласс переопределит doInBackground(Params...) метод для выполнения задачи в фоновом режиме и onPostExecute(Result)Метод вызывается в потоке пользовательского интерфейса после завершения фоновых вычислений и во время отображения результата. В AyncTask есть еще один важный метод:execute(Params... params), этот метод выполняет задачу с указанными параметрами.
пример
Следующий пример показывает вам на практике, как использовать службы определения местоположения в вашем приложении, чтобы получить текущее местоположение и его эквивалентные адреса и т. Д.
Чтобы поэкспериментировать с этим примером, вам понадобится настоящее мобильное устройство с последней версией ОС Android, иначе вам придется бороться с эмулятором, который может не работать.
Создать приложение для Android
Шаг | Описание |
---|---|
1 | Вы будете использовать Android Studio IDE для создания Android-приложения и назовете его Tutorialspoint в пакете com.example.tutorialspoint7.myapplication . |
2 | добавьте файл src / GPSTracker.java и добавьте требуемый код. |
3 | Измените файл src / MainActivity.java и добавьте требуемый код, как показано ниже, чтобы получить текущее местоположение и его эквивалентный адрес. |
4 | Измените XML-файл макета res / layout / activity_main.xml, чтобы добавить все компоненты графического интерфейса, которые включают три кнопки и два текстовых представления для отображения местоположения / адреса. |
5 | Измените файл res / values / strings.xml, чтобы определить необходимые постоянные значения. |
6 | Измените AndroidManifest.xml, как показано ниже. |
7 | Запустите приложение, чтобы запустить эмулятор Android и проверить результат изменений, внесенных в приложение. |
Ниже приводится содержание измененного файла основной деятельности. 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();
}
}
});
}
}
Ниже приводится содержание измененного файла основной деятельности. 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;
}
}
Ниже будет содержание 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применение. Я предполагаю, что вы подключили свое настоящее мобильное устройство Android к компьютеру. Чтобы запустить приложение из Android Studio, откройте один из файлов активности вашего проекта и щелкните
Теперь, чтобы увидеть местоположение, нажмите кнопку Получить местоположение, которая отобразит информацию о местоположении следующим образом: