Kotlin 04.1 में बेहतर Android: Android Google Maps

1. शुरू करने से पहले

Google Maps की मदद से ऐप्लिकेशन बनाने पर, आपको अपने ऐप्लिकेशन में कई सुविधाएं जोड़ने का विकल्प मिलता है. जैसे, सैटलाइट इमेज, मैप के लिए मज़बूत यूज़र इंटरफ़ेस (यूआई) कंट्रोल, जगह की जानकारी ट्रैक करने की सुविधा, और जगह के मार्कर. अपने डेटासेट से मिली जानकारी को Google Maps में दिखाया जा सकता है. इससे Google Maps को ज़्यादा बेहतर बनाया जा सकता है. जैसे, मछली पकड़ने या चढ़ाई करने के लिए मशहूर जगहों की जानकारी. ऐसे गेम भी बनाए जा सकते हैं जिनमें प्लेयर को असल दुनिया में एक्सप्लोर करना होता है. जैसे, खजाने की खोज या ऑगमेंटेड रिएलिटी वाले गेम.

इस लेसन में, आपको Wander नाम का एक Google Maps ऐप्लिकेशन बनाना है. यह ऐप्लिकेशन, पसंद के मुताबिक बनाए गए मैप दिखाता है और उपयोगकर्ता की जगह की जानकारी दिखाता है.

ज़रूरी शर्तें

इनके बारे में जानकारी होना ज़रूरी है:

  • Android Studio का इस्तेमाल करके, बुनियादी Android ऐप्लिकेशन बनाने और उसे चलाने का तरीका.
  • स्ट्रिंग जैसे संसाधनों को बनाने और मैनेज करने का तरीका.
  • Android Studio का इस्तेमाल करके, कोड को फिर से व्यवस्थित करने और वैरिएबल का नाम बदलने का तरीका.
  • उपयोगकर्ता के तौर पर Google मैप का इस्तेमाल कैसे करें.
  • रनटाइम अनुमतियां सेट करने का तरीका.

आपको क्या सीखने को मिलेगा

  • Google API Console से एपीआई पासकोड पाने और उसे अपने ऐप्लिकेशन के साथ रजिस्टर करने का तरीका
  • अपने ऐप्लिकेशन में Google Maps को इंटिग्रेट करने का तरीका
  • अलग-अलग तरह के मैप कैसे दिखाए जाते हैं
  • Google Maps की स्टाइल बदलने का तरीका
  • अपने मैप में मार्कर जोड़ने का तरीका
  • उपयोगकर्ता को किसी लोकप्रिय जगह (पीओआई) पर मार्कर लगाने की सुविधा कैसे चालू करें
  • जगह की जानकारी ट्रैक करने की सुविधा चालू करने का तरीका
  • Google Maps को एम्बेड करने वाला Wander ऐप्लिकेशन बनाने का तरीका
  • अपने ऐप्लिकेशन के लिए मार्कर और स्टाइलिंग जैसी कस्टम सुविधाएं बनाने का तरीका
  • अपने ऐप्लिकेशन में जगह की जानकारी ट्रैक करने की सुविधा चालू करने का तरीका

2. ऐप्लिकेशन की खास जानकारी

इस कोडलैब में, Wander ऐप्लिकेशन बनाया जाता है. यह ऐप्लिकेशन, Google मैप को कस्टम स्टाइल में दिखाता है. Wander ऐप्लिकेशन की मदद से, जगहों पर मार्कर लगाए जा सकते हैं, ओवरले जोड़े जा सकते हैं, और अपनी जगह की रीयल-टाइम जानकारी देखी जा सकती है.

5b12eda7f467bc2f.png

3. टास्क: प्रोजेक्ट सेट अप करना और एपीआई पासकोड पाना

Android के लिए Maps SDK टूल के लिए, एपीआई पासकोड ज़रूरी है. एपीआई पासकोड पाने के लिए, एपीआई और सेवाएं पेज पर जाकर अपना प्रोजेक्ट रजिस्टर करें. एपीआई कुंजी, एक डिजिटल सर्टिफ़िकेट से जुड़ी होती है. यह सर्टिफ़िकेट, ऐप्लिकेशन को उसके डेवलपर से लिंक करता है. डिजिटल सर्टिफ़िकेट इस्तेमाल करने और ऐप्लिकेशन पर हस्ताक्षर करने के बारे में ज़्यादा जानने के लिए, अपने ऐप्लिकेशन पर हस्ताक्षर करना लेख पढ़ें.

इस कोडलैब में, डीबग सर्टिफ़िकेट के लिए एपीआई पासकोड का इस्तेमाल किया जाता है. डीबग सर्टिफ़िकेट को डिज़ाइन के हिसाब से सुरक्षित नहीं माना जाता है. इसके बारे में अपनी डीबग बिल्ड पर हस्ताक्षर करना लेख में बताया गया है. पब्लिश किए गए Android ऐप्लिकेशन में Android के लिए Maps SDK का इस्तेमाल किया जाता है. इसके लिए, दूसरे एपीआई पासकोड की ज़रूरत होती है: रिलीज़ सर्टिफ़िकेट का पासकोड. रिलीज़ सर्टिफ़िकेट पाने के बारे में ज़्यादा जानकारी के लिए, एपीआई कुंजी पाना लेख पढ़ें.

Android Studio में Google Maps Activity टेंप्लेट शामिल होता है. यह टेंप्लेट, काम का टेंप्लेट कोड जनरेट करता है. टेंप्लेट कोड में google_maps_api.xml फ़ाइल शामिल होती है. इसमें एक ऐसा लिंक होता है जिसकी मदद से, एपीआई पासकोड आसानी से पाया जा सकता है.

पहला चरण: मैप टेंप्लेट की मदद से Wander प्रोजेक्ट बनाना

  1. Android Studio में नया प्रोजेक्ट बनाएं.
  2. Google Maps गतिविधि टेंप्लेट चुनें.

d6b874bb19ea68cd.png

  1. प्रोजेक्ट को नाम दें Wander.
  2. कम से कम एपीआई लेवल को एपीआई 19 पर सेट करें. पक्का करें कि भाषा Kotlin हो.
  3. पूरा करें पर क्लिक करें.
  4. ऐप्लिकेशन बनाने के बाद, अपने प्रोजेक्ट और Maps से जुड़ी इन फ़ाइलों को देखें. ये फ़ाइलें, Android Studio आपके लिए बनाता है:

google_maps_api.xml—इस कॉन्फ़िगरेशन फ़ाइल का इस्तेमाल, एपीआई पासकोड को सेव करने के लिए किया जाता है. यह टेंप्लेट, दो google_maps_api.xml फ़ाइलें जनरेट करता है: एक डीबग करने के लिए और दूसरी रिलीज़ करने के लिए. डीबग सर्टिफ़िकेट के लिए एपीआई पासकोड वाली फ़ाइल, src/debug/res/values में मौजूद होती है. रिलीज़ सर्टिफ़िकेट के लिए एपीआई पासकोड वाली फ़ाइल, src/release/res/values में मौजूद होती है. इस कोडलैब में, सिर्फ़ डीबग सर्टिफ़िकेट का इस्तेमाल किया जाता है.

activity_maps.xml—इस लेआउट फ़ाइल में एक फ़्रैगमेंट होता है, जो पूरी स्क्रीन पर दिखता है. SupportMapFragment क्लास, Fragment क्लास की सबक्लास है. SupportMapFragment, किसी ऐप्लिकेशन में मैप जोड़ने का सबसे आसान तरीका है. यह मैप के व्यू के चारों ओर एक रैपर होता है, ताकि ज़रूरी लाइफ़साइकल की ज़रूरतों को अपने-आप मैनेज किया जा सके.

किसी भी ViewGroup में name एट्रिब्यूट के साथ <fragment> टैग का इस्तेमाल करके, लेआउट फ़ाइल में SupportMapFragment को शामिल किया जा सकता है.

android:name="com.google.android.gms.maps.SupportMapFragment"

MapsActivity.javaMapsActivity.kt फ़ाइल, onCreate() तरीके में SupportMapFragment को इंस्टैंशिएट करती है. साथ ही, क्लास के getMapAsync() का इस्तेमाल करके, मैप सिस्टम और व्यू को अपने-आप शुरू करती है. जिस गतिविधि में SupportMapFragment शामिल है उसे OnMapReadyCallback इंटरफ़ेस और उस इंटरफ़ेस के onMapReady() तरीके को लागू करना होगा. मैप लोड होने पर, onMapReady() तरीके को कॉल किया जाता है.

दूसरा चरण: एपीआई पासकोड पाना

  1. google_maps_api.xml फ़ाइल का डीबग वर्शन खोलें.
  2. फ़ाइल में, लंबे यूआरएल वाली टिप्पणी ढूंढें. यूआरएल के पैरामीटर में, आपके ऐप्लिकेशन के बारे में खास जानकारी शामिल होती है.
  3. यूआरएल को कॉपी करें और किसी ब्राउज़र में चिपकाएं.
  4. एपीआई और सेवाएं पेज पर, प्रोजेक्ट बनाने के लिए दिए गए निर्देशों का पालन करें. दिए गए यूआरएल में मौजूद पैरामीटर की वजह से, पेज को Maps SDK for Android को अपने-आप चालू करने के बारे में पता चलता है.
  5. एपीआई पासकोड बनाएं पर क्लिक करें.
  6. अगले पेज पर, एपीआई पासकोड सेक्शन में जाएं और उस पासकोड पर क्लिक करें जिसे आपने अभी बनाया है.
  7. एपीआई पासकोड का इस्तेमाल सिर्फ़ Android ऐप्लिकेशन के लिए करने की अनुमति देने के लिए, एपीआई पासकोड पर पाबंदी लगाएं पर क्लिक करें. इसके बाद, Android के लिए Maps SDK चुनें.
  8. जनरेट किए गए एपीआई पासकोड को कॉपी करें. यह "AIza"" से शुरू होता है.
  9. google_maps_api.xml फ़ाइल में, कुंजी को google_maps_key स्ट्रिंग में चिपकाएं. यह स्ट्रिंग YOUR_KEY_HERE के बगल में मौजूद होती है.
  10. अपना ऐप्लिकेशन चलाएं. आपको अपनी गतिविधि में एक एम्बेड किया गया मैप दिखेगा. इसमें ऑस्ट्रेलिया के सिडनी शहर में एक मार्कर सेट किया गया होगा. (सिडनी मार्कर, टेंप्लेट का हिस्सा है. इसे बाद में बदला जा सकता है.)

34dc9dd877c90996.png

तीसरा चरण: mMap का नाम बदलें

MapsActivity के पास mMap नाम का एक निजी lateinit var है. यह GoogleMap टाइप का है. Kotlin के नाम रखने के नियमों का पालन करने के लिए, mMap का नाम बदलकर map करें.

  1. MapsActivity में, mMap पर राइट क्लिक करें. इसके बाद, Refactor > Rename... पर क्लिक करें

e713ccb3384450c6.png

  1. वैरिएबल का नाम बदलकर map कर दो.

ध्यान दें कि onMapReady() फ़ंक्शन में mMap के सभी रेफ़रंस भी map में बदल जाते हैं.

4. टास्क: मैप टाइप जोड़ना

Google Maps में कई तरह के मैप शामिल हैं: सामान्य, हाइब्रिड, सैटलाइट, इलाके की बनावट, और "कोई नहीं" (कोई मैप नहीं).

सामान्य मैप

सैटलाइट मैप

हाइब्रिड मैप

इलाके वाला मैप

हर तरह के मैप से अलग-अलग तरह की जानकारी मिलती है. उदाहरण के लिए, कार में नेविगेशन के लिए Maps का इस्तेमाल करते समय, सड़कों के नाम देखना मददगार होता है. इसलिए, सामान्य विकल्प का इस्तेमाल किया जा सकता है. हाइकिंग के दौरान, इलाके के मैप से यह तय करने में मदद मिल सकती है कि आपको ऊपर तक पहुंचने के लिए और कितना चढ़ना है.

इस टास्क में आपको:

  1. विकल्प मेन्यू वाला ऐप्लिकेशन बार जोड़ें. इससे उपयोगकर्ता को मैप का टाइप बदलने की सुविधा मिलती है.
  2. मैप की शुरुआती जगह को अपने घर की जगह पर ले जाएं.
  3. मार्कर के लिए सहायता जोड़ी गई है. ये मार्कर, मैप पर किसी एक जगह को दिखाते हैं और इनमें लेबल शामिल हो सकता है.

मैप टाइप के लिए मेन्यू जोड़ना

इस चरण में, विकल्पों वाले मेन्यू के साथ एक ऐप्लिकेशन बार जोड़ा जाता है. इससे उपयोगकर्ता को मैप का टाइप बदलने की सुविधा मिलती है.

  1. नई मेन्यू XML फ़ाइल बनाने के लिए, अपनी res डायरेक्ट्री पर राइट क्लिक करें. इसके बाद, New > Android Resource File को चुनें.
  2. डायलॉग बॉक्स में, फ़ाइल को नाम दें map_options.
  3. संसाधन के टाइप के लिए, मेन्यू चुनें.
  4. ठीक है पर क्लिक करें.
  5. मैप मेन्यू के विकल्प बनाने के लिए, नई फ़ाइल में मौजूद कोड को यहां दिए गए कोड से बदलें. इसके लिए, कोड टैब पर जाएं. "कोई नहीं" मैप टाइप को शामिल नहीं किया गया है, क्योंकि "कोई नहीं" चुनने पर कोई मैप नहीं दिखता. इस चरण में गड़बड़ी होती है. हालांकि, अगले चरण में इसे ठीक कर दिया जाता है.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
   <item
       android:id="@+id/normal_map"
       android:title="@string/normal_map"
       app:showAsAction="never" />
   <item
       android:id="@+id/hybrid_map"
       android:title="@string/hybrid_map"
       app:showAsAction="never" />
   <item
       android:id="@+id/satellite_map"
       android:title="@string/satellite_map"
       app:showAsAction="never" />
   <item
       android:id="@+id/terrain_map"
       android:title="@string/terrain_map"
       app:showAsAction="never" />
</menu>
  1. गड़बड़ियों को ठीक करने के लिए, strings.xml में title एट्रिब्यूट के लिए संसाधन जोड़ें.
<resources>
   ...
   <string name="normal_map">Normal Map</string>
   <string name="hybrid_map">Hybrid Map</string>
   <string name="satellite_map">Satellite Map</string>
   <string name="terrain_map">Terrain Map</string>
   <string name="lat_long_snippet">Lat: %1$.5f, Long: %2$.5f</string>
   <string name="dropped_pin">Dropped Pin</string>
   <string name="poi">poi</string>
</resources>
  1. MapsActivity में, onCreateOptionsMenu() तरीके को बदलें और map_options रिसॉर्स फ़ाइल से मेन्यू को बड़ा करें.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
   val inflater = menuInflater
   inflater.inflate(R.menu.map_options, menu)
   return true
}
  1. MapsActivity.kt में, onOptionsItemSelected() तरीके को बदलें. उपयोगकर्ता के चुने गए विकल्प को दिखाने के लिए, map-type कॉन्स्टेंट का इस्तेमाल करके मैप का टाइप बदलें.
override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
   // Change the map type based on the user's selection.
   R.id.normal_map -> {
       map.mapType = GoogleMap.MAP_TYPE_NORMAL
       true
   }
   R.id.hybrid_map -> {
       map.mapType = GoogleMap.MAP_TYPE_HYBRID
       true
   }
   R.id.satellite_map -> {
       map.mapType = GoogleMap.MAP_TYPE_SATELLITE
       true
   }
   R.id.terrain_map -> {
       map.mapType = GoogleMap.MAP_TYPE_TERRAIN
       true
   }
   else -> super.onOptionsItemSelected(item)
}
  1. ऐप्लिकेशन चलाएं.
  2. मैप का टाइप बदलने के लिए, 428da163b831115b.png पर क्लिक करें. ध्यान दें कि अलग-अलग मोड के बीच मैप का लुक कैसे बदलता है.

6fa42970d87f5dc7.png

5. टास्क: मार्कर जोड़ना

डिफ़ॉल्ट रूप से, onMapReady() कॉलबैक में ऐसा कोड शामिल होता है जो ऑस्ट्रेलिया के सिडनी में एक मार्कर लगाता है. Google Maps को यहीं बनाया गया था. डिफ़ॉल्ट कॉलबैक, मैप को सिडनी पर पैन करने के लिए ऐनिमेट भी करता है.

इस टास्क में, मैप के कैमरे को अपने घर की जगह पर ले जाया जाता है. साथ ही, उसे आपके तय किए गए लेवल पर ज़ूम किया जाता है और वहां एक मार्कर लगाया जाता है.

पहला चरण: अपने घर की जगह पर ज़ूम करें और मार्कर जोड़ें

  1. MapsActivity.kt फ़ाइल में, onMapReady() तरीका ढूंढें. इसमें मौजूद उस कोड को हटाओ जो सिडनी में मार्कर लगाता है और कैमरे को घुमाता है. अब आपका तरीका ऐसा दिखना चाहिए.
override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

}
  1. इन निर्देशों का पालन करके, अपने घर का अक्षांश और देशांतर ढूंढें.
  2. अक्षांश और देशांतर के लिए वैल्यू बनाएं. इसके बाद, उनकी फ़्लोट वैल्यू डालें.
val latitude = 37.422160
val longitude = -122.084270
  1. homeLatLng नाम का नया LatLng ऑब्जेक्ट बनाएं. homeLatLng ऑब्जेक्ट में, अभी बनाई गई वैल्यू पास करें.
val homeLatLng = LatLng(latitude, longitude)
  1. मैप को कितना ज़ूम इन करना है, इसके लिए val बनाएं. ज़ूम लेवल 15f का इस्तेमाल करें.
val zoomLevel = 15f

ज़ूम लेवल से यह तय होता है कि मैप पर कितना ज़ूम इन किया गया है. यहां दी गई सूची से आपको यह पता चलेगा कि ज़ूम करने के हर लेवल पर कितनी जानकारी दिखती है:

  • 1: दुनिया
  • 5: भूखंड/महाद्वीप
  • 10: शहर
  • 15: सड़कें
  • 20: इमारतें
  1. map ऑब्जेक्ट पर moveCamera() फ़ंक्शन को कॉल करके, कैमरे को homeLatLng पर ले जाएं. साथ ही, CameraUpdateFactory.newLatLngZoom() का इस्तेमाल करके CameraUpdate ऑब्जेक्ट पास करें. homeLatLng ऑब्जेक्ट और zoomLevel पास करें.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
  1. मैप में homeLatLng पर एक मार्कर जोड़ो.
map.addMarker(MarkerOptions().position(homeLatLng))

आपका फ़ाइनल तरीका कुछ ऐसा दिखना चाहिए:

override fun onMapReady(googleMap: GoogleMap) {
   map = googleMap

   //These coordinates represent the latitude and longitude of the Googleplex.
   val latitude = 37.422160
   val longitude = -122.084270
   val zoomLevel = 15f

   val homeLatLng = LatLng(latitude, longitude)
   map.moveCamera(CameraUpdateFactory.newLatLngZoom(homeLatLng, zoomLevel))
   map.addMarker(MarkerOptions().position(homeLatLng))
}
  1. अपना ऐप्लिकेशन चलाएं. मैप को आपके घर की जगह पर पैन होना चाहिए, मनचाहे लेवल पर ज़ूम होना चाहिए, और आपके घर पर मार्कर लगाना चाहिए.

fc939024778ee76.png

दूसरा चरण: उपयोगकर्ताओं को लंबे समय तक क्लिक करके मार्कर जोड़ने की अनुमति देना

इस चरण में, आपको एक मार्कर जोड़ना होता है. यह मार्कर तब दिखता है, जब उपयोगकर्ता मैप पर किसी जगह को टैप करके रखता है.

  1. MapsActivity में setMapLongClick() नाम का एक मेथड स्टब बनाएं, जो GoogleMap को आर्ग्युमेंट के तौर पर लेता है.
  2. मैप ऑब्जेक्ट में setOnMapLongClickListener लिसनर अटैच करें.
private fun setMapLongClick(map:GoogleMap) {
   map.setOnMapLongClickListener { }
}
  1. setOnMapLongClickListener() में, addMarker() तरीके को कॉल करें. MarkerOptions ऑब्जेक्ट में, पास किए गए LatLng के हिसाब से नई पोज़िशन सेट करें.
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. onMapReady() तरीके के आखिर में, map के साथ setMapLongClick() को कॉल करें.
override fun onMapReady(googleMap: GoogleMap) {
   ...
  
   setMapLongClick(map)
}
  1. अपना ऐप्लिकेशन चलाएं.
  2. किसी जगह पर मार्कर लगाने के लिए, मैप को दबाकर रखें.
  3. मार्कर पर टैप करें. इससे मार्कर, स्क्रीन के बीच में आ जाएगा.

4ff8d1c1db3bca9e.png

तीसरा चरण: मार्कर के लिए जानकारी वाला विंडो जोड़ना

इस चरण में, आपको एक InfoWindow जोड़ना है. इससे मार्कर पर टैप करने पर, मार्कर के निर्देशांक दिखेंगे.

  1. setMapLongClick()setOnMapLongClickListener() में, snippet के लिए val बनाएं. स्निपेट, टाइटल के बाद दिखने वाला अतिरिक्त टेक्स्ट होता है. स्निपेट में, मार्कर का अक्षांश और देशांतर दिखता है.
private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       // A snippet is additional text that's displayed after the title.
       val snippet = String.format(
           Locale.getDefault(),
           "Lat: %1$.5f, Long: %2$.5f",
           latLng.latitude,
           latLng.longitude
       )
       map.addMarker(
           MarkerOptions()
               .position(latLng)
       )
   }
}
  1. addMarker() में, मार्कर के title को R.string.dropped_pin स्ट्रिंग रिसॉर्स का इस्तेमाल करके, ड्रॉप किए गए पिन पर सेट करें.
  2. मार्कर के snippet को snippet पर सेट करें.

पूरा किया गया फ़ंक्शन ऐसा दिखता है:

private fun setMapLongClick(map: GoogleMap) {
   map.setOnMapLongClickListener { latLng ->
       // A Snippet is Additional text that's displayed below the title.
       val snippet = String.format(
           Locale.getDefault(),
           "Lat: %1$.5f, Long: %2$.5f",
           latLng.latitude,
           latLng.longitude
       )
       map.addMarker(
           MarkerOptions()
               .position(latLng)
               .title(getString(R.string.dropped_pin))
               .snippet(snippet)
              
       )
   }
}
  1. अपना ऐप्लिकेशन चलाएं.
  2. जगह का मार्कर जोड़ने के लिए, मैप को दबाकर रखें.
  3. जानकारी विंडो दिखाने के लिए, मार्कर पर टैप करें.

63f210e6e47dfa29.png

चौथा चरण: POI लिसनर जोड़ना

डिफ़ॉल्ट रूप से, मैप पर लोकप्रिय जगहें (पीओआई) और उनसे जुड़े आइकॉन दिखते हैं. दिलचस्पी की जगहों में पार्क, स्कूल, सरकारी इमारतें वगैरह शामिल हैं. मैप टाइप को normal पर सेट करने पर, कारोबार की दिलचस्पी वाली जगहों (पीओआई) की जानकारी भी मैप पर दिखती है. कारोबार के पीओएस, कारोबारों को दिखाते हैं. जैसे, दुकानें, रेस्टोरेंट, और होटल.

इस चरण में, आपको मैप में GoogleMap.OnPoiClickListener जोड़ना है. यह क्लिक लिसनर, उपयोगकर्ता के किसी लोकप्रिय जगह पर क्लिक करने के तुरंत बाद, मैप पर मार्कर लगाता है. क्लिक लिसनर, जानकारी वाली एक विंडो भी दिखाता है. इसमें पीओआई का नाम होता है.

  1. MapsActivity में setPoiClick() नाम का एक मेथड स्टब बनाएं, जो GoogleMap को आर्ग्युमेंट के तौर पर लेता है.
  2. setPoiClick() तरीके में, पास किए गए GoogleMap पर OnPoiClickListener सेट करें.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->

   }
}
  1. setOnPoiClickListener() में, मार्कर के लिए val poiMarker बनाएं .
  2. इसे मार्कर पर सेट करें. इसके लिए, map.addMarker() का इस्तेमाल करें. साथ ही, MarkerOptions का इस्तेमाल करके title को लोकप्रिय जगह के नाम पर सेट करें.
private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
   }
}
  1. setOnPoiClickListener() फ़ंक्शन में, poiMarker पर showInfoWindow() को कॉल करें, ताकि जानकारी वाली विंडो तुरंत दिख सके.
poiMarker.showInfoWindow()

setPoiClick() फ़ंक्शन के लिए आपका फ़ाइनल कोड ऐसा दिखना चाहिए.

private fun setPoiClick(map: GoogleMap) {
   map.setOnPoiClickListener { poi ->
       val poiMarker = map.addMarker(
           MarkerOptions()
               .position(poi.latLng)
               .title(poi.name)
       )
       poiMarker.showInfoWindow()
   }
}
  1. onMapReady() के आखिर में, setPoiClick() को कॉल करो और map में पास करो.
override fun onMapReady(googleMap: GoogleMap) {
   ...

   setPoiClick(map)
}
  1. अपना ऐप्लिकेशन चलाएं और कोई पीओएस ढूंढें. जैसे, पार्क या कॉफ़ी शॉप.
  2. किसी जगह पर मार्कर लगाने और जानकारी वाली विंडो में जगह का नाम दिखाने के लिए, उस जगह पर टैप करें.

f4b0972c75d5fa5f.png

6. टास्क: अपने मैप को स्टाइल करना

Google Maps को कई तरीकों से अपनी पसंद के मुताबिक बनाया जा सकता है. इससे आपके मैप को एक अलग लुक और फ़ील मिलता है.

आपके पास उपलब्ध एक्सएमएल एट्रिब्यूट का इस्तेमाल करके, MapFragment ऑब्जेक्ट को अपनी पसंद के मुताबिक बनाने का विकल्प होता है. ठीक वैसे ही जैसे किसी अन्य फ़्रैगमेंट को पसंद के मुताबिक बनाया जाता है. हालांकि, इस चरण में GoogleMap ऑब्जेक्ट पर मौजूद तरीकों का इस्तेमाल करके, MapFragment के कॉन्टेंट के लुक और स्टाइल को पसंद के मुताबिक बनाया जाता है.

अपने मैप के लिए पसंद के मुताबिक स्टाइल बनाने के लिए, एक JSON फ़ाइल जनरेट करें. इसमें यह जानकारी होती है कि मैप में सुविधाएं कैसे दिखेंगी. आपको इस JSON फ़ाइल को मैन्युअल तरीके से बनाने की ज़रूरत नहीं है. Google, Maps Platform स्टाइलिंग विज़र्ड उपलब्ध कराता है. इसकी मदद से, मैप को विज़ुअल स्टाइल देने के बाद, आपके लिए JSON जनरेट किया जाता है. इस टास्क में, आपको मैप को रेट्रो थीम के हिसाब से स्टाइल करना है. इसका मतलब है कि मैप में विंटेज रंगों का इस्तेमाल किया जाएगा और आपको रंगीन सड़कें जोड़नी होंगी.

पहला चरण: अपने मैप के लिए स्टाइल बनाना

  1. अपने ब्राउज़र में https://mapstyle.withgoogle.com/ पर जाएं.
  2. स्टाइल बनाएं को चुनें.
  3. रेट्रो को चुनें.

208b3d3aeab0d9b6.png

  1. ज़्यादा विकल्प पर क्लिक करें.

4a35faaf9535ee82.png

  1. सड़क > भरें को चुनें.
  2. सड़कों का रंग बदलकर अपनी पसंद का कोई भी रंग (जैसे कि गुलाबी) चुनें.

92c3293749293a4c.png

  1. पूरा करें पर क्लिक करें.

f1bfe8585eb69480.png

  1. नतीजे के तौर पर मिले डायलॉग से JSON कोड कॉपी करें. अगर आपको अगले चरण में इसका इस्तेमाल करना है, तो इसे सादे टेक्स्ट वाले नोट में सेव करें.

3c32168b299d6420.png

दूसरा चरण: अपने मैप में स्टाइल जोड़ना

  1. Android Studio में, res डायरेक्ट्री में, एक संसाधन डायरेक्ट्री बनाएं और उसका नाम raw रखें. raw डायरेक्ट्री के संसाधनों का इस्तेमाल किया जाता है. जैसे, JSON कोड.
  2. res/raw में map_style.json नाम की फ़ाइल बनाओ.
  3. स्टैश किए गए JSON कोड को नई संसाधन फ़ाइल में चिपकाएं.
  4. MapsActivity में, onCreate() तरीके से ऊपर TAG क्लास वैरिएबल बनाएं. इस कुकी का इस्तेमाल लॉगिंग के लिए किया जाता है.
private val TAG = MapsActivity::class.java.simpleName
  1. साथ ही, MapsActivity में एक setMapStyle() फ़ंक्शन बनाएं, जो GoogleMap को इनपुट के तौर पर लेता है.
  2. setMapStyle() में, try{} ब्लॉक जोड़ें.
  3. try{} ब्लॉक में, स्टाइलिंग के लिए val success बनाएं. (आपने यह कैच ब्लॉक जोड़ा है.)
  4. try{} ब्लॉक में, मैप के लिए JSON स्टाइल सेट करें. इसके बाद, GoogleMap ऑब्जेक्ट पर setMapStyle() को कॉल करें. MapStyleOptions ऑब्जेक्ट पास करें, जो JSON फ़ाइल को लोड करता है.
  5. नतीजे को success को असाइन करें. setMapStyle() वाला तरीका, एक बूलियन वैल्यू दिखाता है. इससे स्टाइलिंग फ़ाइल को पार्स करने और स्टाइल सेट करने की स्थिति के बारे में पता चलता है.
private fun setMapStyle(map: GoogleMap) {
   try {
       // Customize the styling of the base map using a JSON object defined
       // in a raw resource file.
       val success = map.setMapStyle(
           MapStyleOptions.loadRawResourceStyle(
               this,
               R.raw.map_style
           )
       )
   }
}
  1. success के फ़ॉल्स होने पर, if स्टेटमेंट जोड़ें. अगर स्टाइलिंग नहीं हो पाती है, तो एक लॉग प्रिंट करें, जिसमें पार्सिंग के काम न करने की जानकारी हो.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   }
}
  1. स्टाइल फ़ाइल मौजूद न होने की स्थिति को मैनेज करने के लिए, catch{} ब्लॉक जोड़ें. catch ब्लॉक में, अगर फ़ाइल लोड नहीं की जा सकती, तो Resources.NotFoundException दिखाएं.
private fun setMapStyle(map: GoogleMap) {
   try {
       ...
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}

पूरा होने के बाद, यह तरीका इस कोड स्निपेट जैसा दिखना चाहिए:

private fun setMapStyle(map: GoogleMap) {
   try {
       // Customize the styling of the base map using a JSON object defined
       // in a raw resource file.
       val success = map.setMapStyle(
           MapStyleOptions.loadRawResourceStyle(
               this,
               R.raw.map_style
           )
       )

       if (!success) {
           Log.e(TAG, "Style parsing failed.")
       }
   } catch (e: Resources.NotFoundException) {
       Log.e(TAG, "Can't find style. Error: ", e)
   }
}
  1. आखिर में, onMapReady() तरीके में setMapStyle() तरीके को कॉल करें और अपना GoogleMap ऑब्जेक्ट पास करें.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   setMapStyle(map)
}
  1. अपना ऐप्लिकेशन चलाएं.
  2. मैप को normal मोड पर सेट करें. इसके बाद, आपको नई स्टाइल में रेट्रो थीम और अपनी पसंद के रंग की सड़कें दिखनी चाहिए.

b59d6cb81f02a14f.png

तीसरा चरण: मार्कर को स्टाइल करना

मैप मार्कर की स्टाइल बदलकर, मैप को अपनी पसंद के मुताबिक बनाया जा सकता है. इस चरण में, डिफ़ॉल्ट रूप से मौजूद लाल मार्कर को ज़्यादा आकर्षक बनाया जाता है.

  1. डिफ़ॉल्ट मार्कर का इस्तेमाल करने के लिए, onMapLongClick() तरीके में कंस्ट्रक्टर के MarkerOptions() में कोड की यह लाइन जोड़ें. हालांकि, इसका रंग बदलकर नीला कर दें.
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))

अब onMapLongClickListener() ऐसा दिखता है:

map.setOnMapLongClickListener { latLng ->
   // A snippet is additional text that's displayed after the title.
   val snippet = String.format(
       Locale.getDefault(),
       "Lat: %1$.5f, Long: %2$.5f",
       latLng.latitude,
       latLng.longitude
   )
   map.addMarker(
       MarkerOptions()
           .position(latLng)
           .title(getString(R.string.dropped_pin))
           .snippet(snippet)
         .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
   )
}
  1. ऐप्लिकेशन चलाएं. अब आपको लंबे समय तक क्लिक करने के बाद दिखने वाले मार्कर, नीले रंग में दिखेंगे. ध्यान दें कि पीओआई मार्कर अब भी लाल रंग के हैं, क्योंकि आपने onPoiClick() तरीके में स्टाइलिंग नहीं जोड़ी है.

b9916bca3c367e3.png

7. टास्क: ओवरले जोड़ना

Google मैप को अपनी पसंद के मुताबिक बनाने का एक तरीका यह है कि उस पर ड्रॉइंग बनाई जाए. अगर आपको किसी खास तरह की जगह को हाइलाइट करना है, तो यह तकनीक आपके काम आ सकती है. जैसे, मछली पकड़ने की लोकप्रिय जगहें.

  • शेप: मैप में पॉलीलाइन, पॉलीगॉन, और सर्कल जोड़े जा सकते हैं.
  • GroundOverlay objects: ग्राउंड ओवरले, मैप पर फ़िक्स की गई इमेज होती है. मार्कर के उलट, ग्राउंड ओवरले को स्क्रीन के बजाय पृथ्वी की सतह के हिसाब से ओरिएंट किया जाता है. मैप को घुमाने, झुकाने या ज़ूम करने से इमेज का ओरिएंटेशन बदल जाता है. ग्राउंड ओवरले तब काम आते हैं, जब आपको मैप पर किसी एक जगह पर कोई इमेज सेट करनी हो.

चरण: ग्राउंड ओवरले जोड़ना

इस टास्क में, आपको अपने घर की जगह पर Android के आकार का ग्राउंड ओवरले जोड़ना है.

  1. इस Android इमेज को डाउनलोड करें और इसे अपने res/drawable फ़ोल्डर में सेव करें. (पक्का करें कि फ़ाइल का नाम android.png हो.)

61fabd56a0841b44.png

  1. onMapReady() में, कैमरे को घर की पोज़िशन पर ले जाने के लिए कॉल करने के बाद, GroundOverlayOptions ऑब्जेक्ट बनाएं.
  2. ऑब्जेक्ट को androidOverlay नाम के वैरिएबल को असाइन करें.
val androidOverlay = GroundOverlayOptions()
  1. डाउनलोड किए गए इमेज रिसॉर्स से BitmapDescriptor ऑब्जेक्ट बनाने के लिए, BitmapDescriptorFactory.fromResource() तरीके का इस्तेमाल करें.
  2. नतीजे के तौर पर मिले BitmapDescriptor ऑब्जेक्ट को GroundOverlayOptions ऑब्जेक्ट के image() तरीके में पास करें.
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
  1. ज़रूरत के मुताबिक ओवरले की चौड़ाई के लिए, मीटर में float overlaySize बनाएं. इस उदाहरण के लिए, 100f की चौड़ाई सही है.

GroundOverlayOptions ऑब्जेक्ट के लिए position प्रॉपर्टी सेट करें. इसके लिए, position() तरीके को कॉल करें. साथ ही, homeLatLng ऑब्जेक्ट और overlaySize पास करें.

val overlaySize = 100f
val androidOverlay = GroundOverlayOptions()
   .image(BitmapDescriptorFactory.fromResource(R.drawable.android))
   .position(homeLatLng, overlaySize)
  1. GoogleMap ऑब्जेक्ट पर addGroundOverlay() को कॉल करें और अपना GroundOverlayOptions ऑब्जेक्ट पास करें.
map.addGroundOverlay(androidOverlay)
  1. ऐप्लिकेशन चलाएं.
  2. Android इमेज को ओवरले के तौर पर देखने के लिए, zoomLevel की वैल्यू को 18f पर सेट करें.

b1b25b0acd6a9807.png

8. टास्क: जगह की जानकारी ट्रैक करने की सुविधा चालू करना

उपयोगकर्ता अक्सर Google Maps का इस्तेमाल, अपनी मौजूदा जगह की जानकारी देखने के लिए करते हैं. अपने मैप पर डिवाइस की जगह की जानकारी दिखाने के लिए, जगह की जानकारी का डेटा लेयर का इस्तेमाल किया जा सकता है.

जगह की जानकारी के डेटा लेयर से, मैप में मेरी जगह आइकॉन जुड़ जाता है.

f317f84dcb3ac3a1.png

जब उपयोगकर्ता इस बटन पर टैप करता है, तो मैप डिवाइस की जगह की जानकारी पर फ़ोकस करता है. अगर डिवाइस एक जगह पर है, तो जगह की जानकारी नीले बिंदु के तौर पर दिखती है. अगर डिवाइस चल रहा है, तो जगह की जानकारी नीले शेवरॉन के तौर पर दिखती है.

इस टास्क में, आपको जगह की जानकारी के डेटा लेयर को चालू करना है.

चरण: जगह की जानकारी की अनुमतियों का अनुरोध करना

Google Maps में जगह की जानकारी को ट्रैक करने की सुविधा चालू करने के लिए, कोड की सिर्फ़ एक लाइन की ज़रूरत होती है. हालांकि, आपको यह पक्का करना होगा कि उपयोगकर्ता ने स्थान की अनुमतियां दी हों. इसके लिए, रनटाइम-अनुमति मॉडल का इस्तेमाल करें.

इस चरण में, जगह की जानकारी ऐक्सेस करने की अनुमतियों का अनुरोध किया जाता है और जगह की जानकारी ट्रैक करने की सुविधा चालू की जाती है.

  1. AndroidManifest.xml फ़ाइल में, पुष्टि करें कि FINE_LOCATION अनुमति पहले से मौजूद है. Google Maps टेंप्लेट चुनने पर, Android Studio ने यह अनुमति जोड़ी है.
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  1. MapsActivity में, REQUEST_LOCATION_PERMISSION क्लास वैरिएबल बनाएं.
private val REQUEST_LOCATION_PERMISSION = 1
  1. अनुमतियां दी गई हैं या नहीं, यह देखने के लिए MapsActivity में isPermissionGranted() नाम का एक तरीका बनाएं. इस तरीके में, यह देखें कि उपयोगकर्ता ने अनुमति दी है या नहीं.
private fun isPermissionGranted() : Boolean {
  return ContextCompat.checkSelfPermission(
       this,
      Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
}
  1. अपने ऐप्लिकेशन में जगह की जानकारी ट्रैक करने की सुविधा चालू करने के लिए, MapsActivity में एक ऐसा तरीका बनाएं जिसे enableMyLocation() कहा जाता है. इसमें कोई तर्क नहीं होता और यह कुछ भी नहीं दिखाता. इसमें जाकर, ACCESS_FINE_LOCATION की अनुमति देखें. अगर अनुमति दी गई है, तो जगह की जानकारी वाली लेयर चालू करें. अगर ऐसा नहीं है, तो अनुमति का अनुरोध करें.
private fun enableMyLocation() {
   if (isPermissionGranted()) {
       map.isMyLocationEnabled = true 
   }
   else {
       ActivityCompat.requestPermissions(
           this,
           arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION),
           REQUEST_LOCATION_PERMISSION
       )
   }
}
  1. जगह की जानकारी वाली लेयर को चालू करने के लिए, onMapReady() कॉलबैक से enableMyLocation() को कॉल करें.
override fun onMapReady(googleMap: GoogleMap) {
   ...
   enableMyLocation()
}
  1. onRequestPermissionsResult() तरीके को बदलें. देखें कि requestCode, REQUEST_LOCATION_PERMISSION के बराबर है या नहीं. अगर ऐसा है, तो इसका मतलब है कि अनुमति दे दी गई है. अगर अनुमति दी गई है, तो यह भी देखें कि grantResults ऐरे के पहले स्लॉट में PackageManager.PERMISSION_GRANTED मौजूद है या नहीं. अगर ऐसा है, तो enableMyLocation() को कॉल करें.
override fun onRequestPermissionsResult(
   requestCode: Int,
   permissions: Array<String>,
   grantResults: IntArray) {
   if (requestCode == REQUEST_LOCATION_PERMISSION) {
       if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
           enableMyLocation()
       }
   }
}
  1. अपना ऐप्लिकेशन चलाएं. आपको एक डायलॉग दिखेगा, जिसमें डिवाइस की जगह की जानकारी ऐक्सेस करने का अनुरोध किया गया होगा. आगे बढ़ें और अनुमति दें.

da7e23e00ec762c1.png

अब मैप पर, डिवाइस की मौजूदा जगह की जानकारी नीले बिंदु से दिखती है. ध्यान दें कि यहां जगह की जानकारी का बटन मौजूद है. अगर मैप को अपनी जगह से दूर ले जाकर इस बटन पर क्लिक किया जाता है, तो मैप को डिवाइस की जगह पर वापस ले जाया जाता है.

5b12eda7f467bc2f.png

9. सॉल्यूशन कोड

पूरे किए गए कोडलैब का कोड डाउनलोड करें.

$  git clone https://github.com/googlecodelabs/android-kotlin-geo-maps

इसके अलावा, रिपॉज़िटरी को zip फ़ाइल के तौर पर डाउनलोड किया जा सकता है. इसके बाद, इसे अनज़िप करके Android Studio में खोला जा सकता है.

10. खास जानकारी

बधाई हो! आपने Android Kotlin ऐप्लिकेशन में Google मैप जोड़ा हो और उसे स्टाइल किया हो.

11. ज़्यादा जानें

Android डेवलपर का दस्तावेज़:

रेफ़रंस के लिए दस्तावेज़:

12. अगला कोडलैब

इस कोर्स में मौजूद अन्य कोडलैब के लिंक के लिए, Advanced Android in Kotlin कोडलैब का लैंडिंग पेज देखें.