Интеграция Яндекс.Карт SDK в мобильное приложение
Яндекс.Карты — выбор по умолчанию для российских приложений с картами: лучше покрытие на территории СНГ, русскоязычные топонимы без артефактов транслитерации, работающий транзитный маршрутизатор по городам России. MapKit SDK для Android и iOS существенно изменился начиная с версии 4.x — лайтовая версия переименована, API аннотаций переработан.
Версии SDK: Full vs Lite
Яндекс предоставляет две версии:
| Версия | Размер | Офлайн-карты | Маршруты | Поиск |
|---|---|---|---|---|
| MapKit Full | ~40 МБ | Да | Да | Да |
| MapKit Lite | ~15 МБ | Нет | Нет | Только геокодер |
Для большинства приложений достаточно Lite — если не нужны офлайн и транзитные маршруты.
Инициализация
API key получается в developer.tech.yandex.ru. В отличие от Google Maps, ключ не привязывается к Bundle ID / applicationId при создании — ограничения настраиваются отдельно в кабинете.
Android:
// build.gradle
implementation("com.yandex.android:maps.mobile:4.6.1-full")
// Application.onCreate()
MapKitFactory.setApiKey("YOUR_API_KEY")
MapKitFactory.initialize(this)
iOS (Swift Package Manager):
// Package.swift dependency:
// .package(url: "https://github.com/yandex/mapkit-ios-demo", from: "4.6.1")
// AppDelegate / App init:
import YandexMapsMobile
MapKit.setApiKey("YOUR_API_KEY")
Инициализация должна произойти до создания первого MapView. Забытый MapKitFactory.initialize на Android даёт IllegalStateException с неочевидным сообщением о том, что API key не установлен, хотя setApiKey вызван.
Работа с картой на Android
class MapActivity : AppCompatActivity(), MapObjectTapListener {
private lateinit var mapView: MapView
private lateinit var mapObjects: MapObjectCollection
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_map)
mapView = findViewById(R.id.mapView)
MapKitFactory.getInstance().onStart()
mapView.onStart()
val map = mapView.mapWindow.map
map.move(
CameraPosition(Point(55.7558, 37.6173), 12f, 0f, 0f)
)
mapObjects = map.mapObjects.addCollection()
addMarker(Point(55.7558, 37.6173), "Центр")
}
private fun addMarker(point: Point, text: String) {
val placemark = mapObjects.addPlacemark().apply {
geometry = point
setIcon(ImageProvider.fromBitmap(createBitmapIcon()))
addTapListener(this@MapActivity)
}
val textStyle = TextStyle().apply {
this.size = 12f
placement = TextStyle.Placement.BOTTOM
}
placemark.setText(text, textStyle)
}
override fun onMapObjectTap(mapObject: MapObject, point: Point): Boolean {
Toast.makeText(this, (mapObject as? PlacemarkMapObject)?.getText() ?: "", Toast.LENGTH_SHORT).show()
return true
}
override fun onStop() {
mapView.onStop()
MapKitFactory.getInstance().onStop()
super.onStop()
}
}
Lifecycle-методы mapView.onStart() / mapView.onStop() — обязательны. Пропуск onStop ведёт к утечке памяти и продолжению рендеринга в фоне.
Поиск и геокодирование через Search API
val searchManager = SearchFactory.getInstance()
.createSearchManager(SearchManagerType.COMBINED)
val searchSession = searchManager.submit(
"кафе рядом",
VisibleRegionUtils.toPolygon(mapView.mapWindow.map.visibleRegion),
SearchOptions().apply {
searchTypes = SearchType.BIZ.value
resultPageSize = 20
},
object : Session.SearchListener {
override fun onSearchResponse(response: Response) {
for (item in response.collection.children) {
val point = item.obj?.geometry?.firstOrNull()?.point ?: continue
addMarker(point, item.obj?.name ?: "")
}
}
override fun onSearchError(error: Error) {}
}
)
Маршруты: DrivingRouter
val drivingRouter = DirectionsFactory.getInstance().createDrivingRouter(DrivingRouterType.COMBINED)
val points = listOf(
RequestPoint(Point(55.7558, 37.6173), RequestPointType.WAYPOINT, null, null),
RequestPoint(Point(59.9343, 30.3351), RequestPointType.WAYPOINT, null, null)
)
drivingRouter.requestRoutes(
points,
DrivingOptions().apply { routesCount = 1 },
VehicleOptions(),
object : DrivingSession.DrivingRouteListener {
override fun onDrivingRoutes(routes: MutableList<DrivingRoute>) {
if (routes.isNotEmpty()) {
mapView.mapWindow.map.mapObjects.addPolyline(routes[0].geometry)
}
}
override fun onDrivingRoutesError(error: Error) {}
}
)
Сроки
1–3 дня. Базовая карта с маркерами — 1 день. Поиск + маршруты + кастомные иконки — 2–3 дня. Стоимость рассчитывается индивидуально.







