С помощью Maps SDK для Android можно добавить поддержку карт в приложение для носимых устройств с операционной системой Wear OS by Google. Это позволит пользователям определять свое местоположение, просто взглянув на экран. Им будут доступны такие функции карт, как определение своего местоположения, изменение масштаба, просмотр информации об объектах и т. п.
На этой странице описываются функциональные возможности API, доступные для носимых устройств, и приводятся рекомендации, которые помогут вам начать разработку приложения.
Начало работы с Wear OS
Приложения для носимых устройств с использованием Maps SDK для Android разрабатываются в целом так же, как и для любых других устройств Android. Различия обусловлены меньшими размерами носимых устройств и необходимостью оптимизировать интерфейс приложения и его производительность.
Инструмент Android Studio является рекомендуемой средой разработки приложений для Wear OS. Он поддерживает настройку проектов, включение библиотек и средства создания пакета приложения.
Мы подготовили рекомендации по разработке приложений для Wear OS и советы, которые помогут вам при создании вашего первого приложения для носимых устройств.
Создание приложения для работы с картами на Wear OS
В этом кратком руководстве предполагается следующее: вы знакомы с Maps SDK для Android; вы создали в своем приложении модуль для носимых устройств, следуя рекомендациям из руководства по разработке для Wear OS; вы хотите добавить поддержку карт в этот модуль.
Добавление зависимостей в модуль для носимых устройств
Убедитесь, что в файл build.gradle
модуля вашего приложения для Wear OS включены следующие зависимости:
dependencies { // ... compileOnly 'com.google.android.wearable:wearable:2.9.0' implementation 'com.google.android.support:wearable:2.9.0' implementation 'com.google.android.gms:play-services-maps:18.2.0' // This dependency is necessary for ambient mode implementation 'androidx.wear:wear:1.3.0' }
Более подробная информация о зависимостях приведена в руководстве по добавлению модуля Wear OS в существующий проект.
Реализация поддержки жеста смахивания, скрывающего окно, и настройка исходного цвета фона
Для показа карты на носимом устройстве рекомендуется использовать класс SwipeDismissFrameLayout
. Класс SwipeDismissFrameLayout
позволяет добавить поддержку жеста смахивания, чтобы пользователи могли закрывать приложение, проводя пальцем по экрану слева направо.
Чтобы изменить исходный цвет фона, используйте XML-атрибут map:backgroundColor
. Заданный цвет будет использоваться при отрисовке, пока не загрузится карта.
Добавьте элементы SwipeDismissFrameLayout
и backgroundColor
в определение макета в качестве контейнера SupportMapFragment
:
<androidx.wear.widget.SwipeDismissFrameLayout android:id="@+id/map_container" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" map:backgroundColor="#fff0b2dd" /> </androidx.wear.widget.SwipeDismissFrameLayout>
После получения объекта SwipeDismissFrameLayout
в своем объекте activity добавьте обратный вызов и задайте для него выполнение необходимого действия закрытия приложения, как показано ниже.
Kotlin
class MainActivity : AppCompatActivity(), OnMapReadyCallback, AmbientModeSupport.AmbientCallbackProvider { public override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) // Set the layout. It only contains a SupportMapFragment and a DismissOverlay. setContentView(R.layout.activity_main) // Enable ambient support, so the map remains visible in simplified, low-color display // when the user is no longer actively using the app but the app is still visible on the // watch face. val controller = AmbientModeSupport.attach(this) Log.d(MainActivity::class.java.simpleName, "Is ambient enabled: " + controller.isAmbient) // Retrieve the containers for the root of the layout and the map. Margins will need to be // set on them to account for the system window insets. val mapFrameLayout = findViewById<SwipeDismissFrameLayout>(R.id.map_container) mapFrameLayout.addCallback(object : SwipeDismissFrameLayout.Callback() { override fun onDismissed(layout: SwipeDismissFrameLayout) { onBackPressed() } }) // Obtain the MapFragment and set the async listener to be notified when the map is ready. mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment mapFragment.getMapAsync(this) } // ... }
Java
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, AmbientModeSupport.AmbientCallbackProvider { public void onCreate(Bundle savedState) { super.onCreate(savedState); // Set the layout. It only contains a SupportMapFragment and a DismissOverlay. setContentView(R.layout.activity_main); // Enable ambient support, so the map remains visible in simplified, low-color display // when the user is no longer actively using the app but the app is still visible on the // watch face. AmbientModeSupport.AmbientController controller = AmbientModeSupport.attach(this); Log.d(MainActivity.class.getSimpleName(), "Is ambient enabled: " + controller.isAmbient()); // Retrieve the containers for the root of the layout and the map. Margins will need to be // set on them to account for the system window insets. final SwipeDismissFrameLayout mapFrameLayout = (SwipeDismissFrameLayout) findViewById( R.id.map_container); mapFrameLayout.addCallback(new SwipeDismissFrameLayout.Callback() { @Override public void onDismissed(SwipeDismissFrameLayout layout) { onBackPressed(); } }); // Obtain the MapFragment and set the async listener to be notified when the map is ready. mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } // ... }
Добавление карты
Используйте метод обратного вызова onMapReady(GoogleMap)
, чтобы получить дескриптор объекта GoogleMap. Обратный вызов выполняется тогда, когда карта готова к использованию. В методе обратного вызова вы можете поместить на карту маркеры или ломаные линии, добавить прослушиватели или переместить камеру. В приведенном ниже примере показано, как добавить маркер рядом с Сиднейским оперным театром.
Kotlin
private val sydney = LatLng(-33.85704, 151.21522) override fun onMapReady(googleMap: GoogleMap) { // Add a marker with a title that is shown in its info window. googleMap.addMarker( MarkerOptions().position(sydney) .title("Sydney Opera House") ) // Move the camera to show the marker. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 10f)) }
Java
private static final LatLng SYDNEY = new LatLng(-33.85704, 151.21522); @Override public void onMapReady(@NonNull GoogleMap googleMap) { // Add a marker with a title that is shown in its info window. googleMap.addMarker(new MarkerOptions().position(SYDNEY) .title("Sydney Opera House")); // Move the camera to show the marker. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 10)); }
Включение спящего режима
Maps SDK для Android поддерживает спящий режим в приложениях для носимых устройств. Приложения, поддерживающие спящий режим, называются всегда включенными. Спящий режим активируется, если пользователь не выполнял никаких действий в приложении в течение некоторого времени. Приложение в этом режиме остается видимым на экране носимого устройства.
Maps SDK для Android поддерживает упрощенную прорисовку карты с приглушенными цветами в спящем режиме. Стиль карты автоматически изменяется, когда приложение переходит из интерактивного режима в спящий. В спящем режиме не отображаются маркеры, объекты и элементы интерфейса. Это позволяет сократить энергопотребление и сделать стиль интерфейса похожим на стиль других всегда включенных приложений, таких как циферблаты часов.
Чтобы обеспечить поддержку спящего режима карты в вашем приложении, выполните следующие действия:
- Обновите Android SDK, включив в него платформу Android 6.0 (API уровня 23) или более поздней версии с API для поддержки перехода приложения в спящий режим. Подробнее о том, как обновить SDK, рассказывается в документации Android по добавлению пакетов SDK.
- В качестве целевой платформы своего приложения укажите Android версии 6.0 или более поздней, указав для параметра
targetSdkVersion
в манифесте приложения значение 23 или выше. - Добавьте в файл
build.gradle
своего приложения зависимости для поддержки носимых устройств. См. пример. - Укажите в манифесте своего приложения общую библиотеку для поддержки носимых устройств согласно инструкциям в этом уроке.
- Добавьте разрешение
WAKE_LOCK
в манифесты приложений для носимых и мобильных устройств согласно инструкциям в этом уроке. - В методе
onCreate()
своего класса activity вызовите методAmbientModeSupport.attach()
. Это сообщит операционной системе о том, что приложение должно быть всегда включено. Тогда при переходе устройства в энергосберегающий режим приложение перейдет в спящий, а не вернется к интерфейсу часов. - Добавьте интерфейс
AmbientModeSupport.AmbientCallbackProvider
для класса Activity, чтобы он получал данные об изменении статуса спящего режима. - Настройте для своей карты поддержку спящего режима. Для этого задайте атрибут
map:ambientEnabled="true"
в XML-файле макета вашего объекта activity. Также можно сделать это программными средствами с помощьюGoogleMapOptions.ambientEnabled(true)
. Так API получит информацию о том, что требуется предварительно загрузить необходимые фрагменты карты, которые будут использоваться в спящем режиме. - Когда объект activity переключается в спящий режим, система вызывает метод
onEnterAmbient()
в заданном вами объектеAmbientCallback
. Переопределите методonEnterAmbient()
, реализовав вызов методаSupportMapFragment.onEnterAmbient(ambientDetails)
илиMapView.onEnterAmbient(ambientDetails)
. API перейдет в неинтерактивный режим отрисовки карты с приглушенными цветами. - Аналогичным образом в методе
onExitAmbient()
вызовите методSupportMapFragment.onExitAmbient()
илиMapView.onExitAmbient()
. API перейдет в нормальный режим отрисовки карты.
Следующий пример кода активирует спящий режим в объекте activity:
Kotlin
class AmbientActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider { private lateinit var mapFragment: SupportMapFragment public override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) // Set the layout. It only contains a SupportMapFragment and a DismissOverlay. setContentView(R.layout.activity_main) // Enable ambient support, so the map remains visible in simplified, low-color display // when the user is no longer actively using the app but the app is still visible on the // watch face. val controller = AmbientModeSupport.attach(this) Log.d(AmbientActivity::class.java.simpleName, "Is ambient enabled: " + controller.isAmbient) // Obtain the MapFragment and set the async listener to be notified when the map is ready. mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment } override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback { return object : AmbientModeSupport.AmbientCallback() { /** * Starts ambient mode on the map. * The API swaps to a non-interactive and low-color rendering of the map when the user is no * longer actively using the app. */ override fun onEnterAmbient(ambientDetails: Bundle) { super.onEnterAmbient(ambientDetails) mapFragment.onEnterAmbient(ambientDetails) } /** * Exits ambient mode on the map. * The API swaps to the normal rendering of the map when the user starts actively using the app. */ override fun onExitAmbient() { super.onExitAmbient() mapFragment.onExitAmbient() } } } }
Java
public class AmbientActivity extends AppCompatActivity implements AmbientModeSupport.AmbientCallbackProvider { private SupportMapFragment mapFragment; public void onCreate(Bundle savedState) { super.onCreate(savedState); // Set the layout. It only contains a SupportMapFragment and a DismissOverlay. setContentView(R.layout.activity_main); // Enable ambient support, so the map remains visible in simplified, low-color display // when the user is no longer actively using the app but the app is still visible on the // watch face. AmbientModeSupport.AmbientController controller = AmbientModeSupport.attach(this); Log.d(AmbientActivity.class.getSimpleName(), "Is ambient enabled: " + controller.isAmbient()); // Obtain the MapFragment and set the async listener to be notified when the map is ready. mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); } @Override public AmbientCallback getAmbientCallback() { return new AmbientCallback() { /** * Starts ambient mode on the map. * The API swaps to a non-interactive and low-color rendering of the map when the user is no * longer actively using the app. */ @Override public void onEnterAmbient(Bundle ambientDetails) { super.onEnterAmbient(ambientDetails); mapFragment.onEnterAmbient(ambientDetails); } /** * Exits ambient mode on the map. * The API swaps to the normal rendering of the map when the user starts actively using the app. */ @Override public void onExitAmbient() { super.onExitAmbient(); mapFragment.onExitAmbient(); } }; } }
Вы можете обновлять экран, когда приложение находится в спящем режиме. Подробная информация о способах обновления контента и о спящем режиме в целом приведена в уроке, из которого разработчики ПО для Android могут узнать, как сделать приложение постоянно видимым.
Использование Просмотра улиц на Wear OS
Просмотр улиц полностью поддерживается на носимых устройствах.
Чтобы разрешить пользователям выходить из приложения при просмотре панорам в Просмотре улиц, используйте интерфейс StreetViewPanorama.OnStreetViewPanoramaLongClickListener, отслеживающий долгие нажатия. Если пользователь нажмет на любую область изображения Просмотра улиц и будет удерживать палец на экране, вы получите событие onStreetViewPanoramaLongClick(StreetViewPanoramaOrientation)
. Вызовите метод DismissOverlayView.show()
, чтобы показать кнопку выхода.
Пример кода
На сайте GitHub приведен пример, который поможет вам начать разработку. В нем показано, как добавлять базовую карту в приложение для Wear OS.
Поддерживаемые функции в Maps API для Wear OS
В этом разделе описываются различия поддерживаемых функций для карт на носимых устройствах в сравнении с мобильными устройствами (телефонами и планшетами). Все функции API, не указанные ниже, должны работать так, как описано в документации к полноценному интерфейсу API.
Функции | |
---|---|
Полностью интерактивный режим и упрощенный режим | Maps SDK для Android можно использовать как в полностью интерактивном, так и в упрощенном режиме. Упрощенный режим позволяет оптимизировать производительность на носимом устройстве и может использоваться, если приложению не нужно поддерживать различные варианты взаимодействия, такие как жесты, панорамирование или масштабирование карты. В упрощенном режиме на носимых устройствах отключена функция запуска мобильного приложения "Google Карты" при нажатии на карту, показанную на экране. Включить эту функцию нельзя. Полный список различий между полностью интерактивным и упрощенным режимами приведен в документации упрощенного режима. |
Панель инструментов на карте | Панель инструментов на карте отключена на носимых устройствах, и включить ее нельзя. |
Элементы управления пользовательского интерфейса | По умолчанию элементы управления пользовательского интерфейса отключены на носимых устройствах. Это относится к кнопкам масштабирования, компасу и кнопке "Мое местоположение". Их можно включить с помощью класса UiSettings .
|
Жесты | Жесты с одним касанием работают обычным образом. Примеры жестов с одним касанием: перетаскивание прокручивает карту, двойное касание увеличивает масштаб, касание двумя пальцами уменьшает масштаб. Поддержка жестов с несколькими касаниями зависит от устройства. Примеры жестов с несколькими касаниями: нажатие двумя пальцами для наклона карты, сведение или разведение двух пальцев для масштабирования, вращение карты двумя пальцами. |
Схемы зданий и строения |
Схемы зданий по умолчанию отключены на носимых устройствах. Их можно включить с помощью метода GoogleMap.setIndoorEnabled(true) . Если схемы зданий включены, то на карте будет отображаться уровень этажа, выбираемый по умолчанию.
Элемент интерфейса для выбора этажа не поддерживается на носимых устройствах. |
Наложения фрагментов карты | Наложения фрагментов карты не поддерживаются на носимых устройствах. |
Рекомендации по разработке приложений с интеграцией API Карт для Wear OS
Для создания максимально удобного пользовательского интерфейса в вашем приложении соблюдайте следующие принципы:
- Карта должна занимать значительную часть экрана. Это необходимо для того, чтобы карту было удобно использовать на носимом устройстве малого размера.
- Дизайн приложения нужно продумать с учетом небольшой емкости аккумуляторов носимых устройств. Постоянно включенный экран и непрерывное отображение карты значительно сократят время работы устройства от аккумулятора.