Processing:Библиотеки/Processing for Android/Месторасположение и разрешения

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску


Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.



Месторасположение и разрешения[1]

Это руководство объясняет, как получить доступ к GPS-данным о месторасположении и правильно настроить разрешения скетча на устройствах с операционной системой Android версии 6+.

API Android для определения месторасположения

Устройство Android может определить свое месторасположение с точностью до нескольких градусов при помощи информации от сетей, к которым оно подключено (WiFi, сотовой связи), или при помощи сигналов от GPS-спутников (от англ. «global positioning system», т.е. «глобальная система позиционирования»). Данные о месторасположении, полученные с помощью GPS, получаются более точными, но этот метод требует, чтобы устройство находилось вне помещения, расходует больше заряда батареи и обновляется реже, чем при определении месторасположения с помощью сетей.

Создание менеджера месторасположения

Базовая структура скетча, получающего доступ к данным о месторасположении, очень похожа на ту, которую мы уже видели в скетчах-примерах для работы с [wikihandbk.com/wiki/Processing:Библиотеки/Processing_for_Android/Руководства/Использование_датчиков другими датчиками]. Вначале мы берем менеджера месторасположения из контекста приложения, «живых» обоев или циферблата при помощи функции surface.getContext() (если версия режима программирования Android – 4.0 и выше) или просто считываем указатель на активность при помощи функции getActivity() (если у вас версия 3). После этого мы подключаем «слушателя» к менеджеру:

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.Manifest;

LocationManager locationManager;
MyLocationListener locationListener;

boolean hasLocation = false;

void setup () {
  fullScreen();
  orientation(PORTRAIT);  
  textFont(createFont("SansSerif", 26 * displayDensity));
  textAlign(CENTER, CENTER);
  requestPermission("android.permission.ACCESS_FINE_LOCATION", "initLocation");
}

void draw() {
}

void initLocation(boolean granted) {
  if (granted) {    
    Context context = getContext();
    locationListener = new MyLocationListener();
    locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);    
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
    hasLocation = true;
  } else {
    hasLocation = false;
  }
}

class MyLocationListener implements LocationListener {
  public void onLocationChanged(Location location) {
    println(location.getLatitude(), location.getLongitude());
  }

  public void onProviderDisabled (String provider) { }

  public void onProviderEnabled (String provider) { }

  public void onStatusChanged (String provider, int status, Bundle extras) {
  }
}

Мы здесь явно запрашиваем разрешение при помощи функции requestPermission(), а также помещаем код с инициализацией менеджера и слушателя внутрь функции initLocation(), а не внутрь setup(), как в предыдущих примерах. Причина в том, что в последних версиях Android (6.0 и новее) разрешения поделены на две группы: обычные и опасные. Разрешения, классифицированные как «опасные», касаются доступа к личным данным пользователя – вроде данных о месторасположении или списка контактов – и требуют, чтобы пользователь принимал решения по каждому из этих разрешений отдельно во время запуска приложения, а не его установки.

Приложение покажет диалоговое окно, спрашивающее о том, что сделать – дать или отклонить разрешение. Лишь после этого будет вызвана функция initLocation(), которая – в зависимости от булева значения в аргументе granted – либо запустит, либо не запустит процесс определения местонахождения. Этой функцией, которая должна содержать инициализирующий код, соответствующий запрашиваемому разрешению, не обязательно должна быть initLocation(). Она может называться по-другому, но должна отвечать двум важным критериям – во-первых, она должна принимать булев аргумент, а во-вторых, ее название должно быть указано аргументом в функции requestPermission().

Кроме того, вам надо будет задать разрешения, необходимые для работы этого скетча. Для этого кликните в PDE на Android > Sketch Permissions, а затем поставьте галочки у пунктов ACCESS_COARSE_LOCATION (для обнаружения местонахождения с помощью сетей) и ACCESS_FINE_LOCATION (для обнаружения местонахождения с помощью GPS):

Переменная location, которую мы получаем в «слушателе» данных о локации, содержит всю информацию, необходимую для указания месторасположения при помощи широты и долготы:

class MyLocationListener implements LocationListener {
  public void onLocationChanged(Location location) {
    currentLatitude  = (float)location.getLatitude();
    currentLongitude = (float)location.getLongitude();
    currentAccuracy  = (float)location.getAccuracy();
    currentProvider  = location.getProvider();
  }

  public void onProviderDisabled (String provider) { 
    currentProvider = "";
  }

  public void onProviderEnabled (String provider) { 
    currentProvider = provider;
  }

  public void onStatusChanged (String provider, int status, Bundle extras) {
  }
}

Проверка наличия данных о месторасположении

Даже если задать в PDE необходимые разрешения для скетча, пользователь по-прежнему может отклонить запрос на использование этих функций при запуске приложения на устройстве. То есть нам в скетче необходим код, который бы обрабатывал ситуацию, при которой данные о месторасположении не доступны. Поэтому мы также пишем в коде функцию checkPermission(), чтобы удостовериться, что необходимое разрешение действительно получено и мы можем получить доступ к соответствующему функционалу:

void draw() {
  background(0);
  if (hasPermission("android.permission.ACCESS_FINE_LOCATION")) {
    text("Latitude: " + currentLatitude + "\n" +
         "Longitude: " + currentLongitude + "\n" +
         "Accuracy: " + currentAccuracy + "\n" +
         "Provider: " + currentProvider, 0, 0, width, height);
     //  "Широта: "
     //  "Долгота: "
     //  "Точность: "
     //  "Провайдер: "
  } else {
    text("No permissions to access location", 0, 0, width, height);
     //  "Нет разрешения на доступ к данным о месторасположении"
  }
}

Полный код этого скетча-примера можно найти тут. Запустив этот скетч на устройстве с Android версии 6 и новее, вы должны увидеть на экране следующее диалоговое окно, запрашивающее разрешение на получение данных о местонахождении:

Разрешив приложению доступ к данным о месторасположении своего устройства, вы получите значения широты и долготы, считанные при помощи «класса-слушателя».

См.также

Внешние ссылки