diff --git a/README.md b/README.md
index 7785f7174..817ec934b 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,7 @@ range of applications using the [Google Maps SDK for Android][android-site].
computeArea
- **KML** — displays KML data
- **GeoJSON** — displays and styles GeoJSON data
+- **StreetView Utility** — checks if a given StreetView location exists
@@ -289,6 +290,20 @@ _Old_
+## Usage guide
+
+The full documentation can be found here [Google Maps Platform documentation][devsite-guide].
+
+For a quick snippet on the StreetViewUtil class, keep reading.
+
+The StreetViewUtil class provides functionality to check whether a location is supported in StreetView. To call it, use the following snippet:
+
+```kotlin
+StreetViewUtils.fetchStreetViewData(LatLng(8.1425918, 11.5386121), BuildConfig.MAPS_API_KEY)
+```
+
+`fetchStreetViewData` will return `NOT_FOUND`, `OK` or `ZERO_RESULTS`, depending on the response.
+
## Support
Encounter an issue while using this library?
diff --git a/build.gradle b/build.gradle
index aa0471d75..b30d607ba 100644
--- a/build.gradle
+++ b/build.gradle
@@ -27,7 +27,7 @@ buildscript {
classpath 'com.android.tools.build:gradle:7.3.1'
classpath 'com.hiya:jacoco-android:0.2'
classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0"
}
}
diff --git a/demo/build.gradle b/demo/build.gradle
index 9e9a785d4..0ef9044a6 100644
--- a/demo/build.gradle
+++ b/demo/build.gradle
@@ -54,8 +54,12 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.7.0-alpha01'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
- implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
+ implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
+
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.0'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.0'
+
// [END_EXCLUDE]
}
// [END maps_android_utils_install_snippet]
diff --git a/demo/src/main/AndroidManifest.xml b/demo/src/main/AndroidManifest.xml
index 09dc1de90..fd890c5e6 100644
--- a/demo/src/main/AndroidManifest.xml
+++ b/demo/src/main/AndroidManifest.xml
@@ -68,6 +68,7 @@
+
diff --git a/demo/src/main/java/com/google/maps/android/utils/demo/MainActivity.java b/demo/src/main/java/com/google/maps/android/utils/demo/MainActivity.java
index 0d86c4aaf..26a7a728e 100644
--- a/demo/src/main/java/com/google/maps/android/utils/demo/MainActivity.java
+++ b/demo/src/main/java/com/google/maps/android/utils/demo/MainActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 Google Inc.
+ * Copyright 2023 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -57,6 +57,7 @@ protected void onCreate(Bundle savedInstanceState) {
addDemo("KML Layer Overlay", KmlDemoActivity.class);
addDemo("Multi Layer", MultiLayerDemoActivity.class);
addDemo("AnimationUtil sample", AnimationUtilDemoActivity.class);
+ addDemo("Street View Demo", StreetViewDemoActivity.class);
}
private void addDemo(String demoName, Class extends Activity> activityClass) {
diff --git a/demo/src/main/java/com/google/maps/android/utils/demo/SampleManager.java b/demo/src/main/java/com/google/maps/android/utils/demo/SampleManager.java
deleted file mode 100644
index 1f4637022..000000000
--- a/demo/src/main/java/com/google/maps/android/utils/demo/SampleManager.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.google.maps.android.utils.demo;
-
-import com.google.android.gms.maps.GoogleMap;
-import com.google.maps.android.collections.GroundOverlayManager;
-
-
-import androidx.annotation.NonNull;
-
-public class SampleManager extends GroundOverlayManager implements GoogleMap.OnGroundOverlayClickListener {
-
-
- public SampleManager(@NonNull GoogleMap map) {
- super(map);
- }
-}
diff --git a/demo/src/main/java/com/google/maps/android/utils/demo/StreetViewDemoActivity.kt b/demo/src/main/java/com/google/maps/android/utils/demo/StreetViewDemoActivity.kt
new file mode 100644
index 000000000..fb642a377
--- /dev/null
+++ b/demo/src/main/java/com/google/maps/android/utils/demo/StreetViewDemoActivity.kt
@@ -0,0 +1,30 @@
+package com.google.maps.android.utils.demo
+
+import android.app.Activity
+import android.os.Bundle
+import android.widget.TextView
+import com.google.android.gms.maps.model.LatLng
+import com.google.maps.android.StreetViewUtils
+import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+
+class StreetViewDemoActivity : Activity() {
+
+ @OptIn(DelicateCoroutinesApi::class)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.street_view_demo)
+
+ GlobalScope.launch(Dispatchers.Main) {
+ val response1 =
+ StreetViewUtils.fetchStreetViewData(LatLng(48.1425918, 11.5386121), BuildConfig.MAPS_API_KEY)
+ val response2 = StreetViewUtils.fetchStreetViewData(LatLng(8.1425918, 11.5386121), BuildConfig.MAPS_API_KEY)
+
+ findViewById(R.id.textViewFirstLocation).text = "Location 1 is supported in StreetView: $response1"
+ findViewById(R.id.textViewSecondLocation).text = "Location 2 is supported in StreetView: $response2"
+ }
+ }
+}
+
diff --git a/demo/src/main/res/layout/street_view_demo.xml b/demo/src/main/res/layout/street_view_demo.xml
new file mode 100644
index 000000000..1aada33de
--- /dev/null
+++ b/demo/src/main/res/layout/street_view_demo.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/build.gradle b/library/build.gradle
index 1cabd08db..6c846ac37 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -15,6 +15,7 @@
*/
plugins {
id 'kotlin-android'
+ id 'org.jetbrains.kotlin.android'
}
android {
@@ -56,11 +57,14 @@ android {
dependencies {
implementation 'com.google.android.gms:play-services-maps:18.1.0'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'androidx.core:core-ktx:1.10.1'
lintPublish project(':lint-checks')
testImplementation 'junit:junit:4.13.2'
- testImplementation 'org.robolectric:robolectric:4.7.3'
+ testImplementation 'org.robolectric:robolectric:4.10.3'
testImplementation 'net.sf.kxml:kxml2:2.3.0'
+ testImplementation "io.mockk:mockk:1.13.4"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
diff --git a/library/src/main/java/com/google/maps/android/StreetViewUtil.kt b/library/src/main/java/com/google/maps/android/StreetViewUtil.kt
new file mode 100644
index 000000000..945648aae
--- /dev/null
+++ b/library/src/main/java/com/google/maps/android/StreetViewUtil.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2023 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.maps.android
+
+import kotlinx.coroutines.withContext
+import java.io.IOException
+import java.net.HttpURLConnection
+import java.net.URL
+import com.google.android.gms.maps.model.LatLng
+import kotlinx.coroutines.Dispatchers
+import org.json.JSONObject
+import java.io.BufferedReader
+import java.io.InputStreamReader
+
+
+/**
+ * Utility functions for StreetView
+ */
+class StreetViewUtils {
+ companion object {
+
+ /**
+ * This function will check whether a location is available on StreetView or not.
+ *
+ * @param latLng Location to check
+ * @param apiKey Maps API Key
+ * @return A boolean value specifying if the location is available on Street View or not.
+ */
+ suspend fun fetchStreetViewData(latLng: LatLng, apiKey: String): Status {
+ val urlString =
+ "https://maps.googleapis.com/maps/api/streetview/metadata?location=${latLng.latitude},${latLng.longitude}&key=$apiKey"
+
+ return withContext(Dispatchers.IO) {
+ try {
+ val url = URL(urlString)
+ val connection = url.openConnection() as HttpURLConnection
+ connection.requestMethod = "GET"
+
+ val responseCode = connection.responseCode
+ if (responseCode == HttpURLConnection.HTTP_OK) {
+ val inputStream = connection.inputStream
+ val bufferedReader = BufferedReader(InputStreamReader(inputStream))
+ val responseString = bufferedReader.use { it.readText() }
+ bufferedReader.close()
+ inputStream.close()
+ deserializeResponse(responseString).status
+ } else {
+ throw IOException("HTTP Error: $responseCode")
+ }
+ } catch (e: IOException) {
+ e.printStackTrace()
+ throw IOException("Network error: ${e.message}")
+ }
+ }
+ }
+
+ private fun deserializeResponse(responseString: String): ResponseStreetView {
+ val jsonObject = JSONObject(responseString)
+ val statusString = jsonObject.optString("status")
+ val status = Status.valueOf(statusString)
+
+ return ResponseStreetView(status)
+ }
+ }
+}
+
+data class ResponseStreetView(val status: Status)
+
+enum class Status {
+ OK,
+ ZERO_RESULTS,
+ NOT_FOUND
+}
diff --git a/library/src/test/java/com/google/maps/android/StreetViewUtilTest.kt b/library/src/test/java/com/google/maps/android/StreetViewUtilTest.kt
new file mode 100644
index 000000000..0a150f768
--- /dev/null
+++ b/library/src/test/java/com/google/maps/android/StreetViewUtilTest.kt
@@ -0,0 +1,39 @@
+package com.google.maps.android
+
+import com.google.android.gms.maps.model.LatLng
+import io.mockk.coEvery
+import io.mockk.mockkObject
+import kotlinx.coroutines.runBlocking
+import org.junit.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+
+class StreetViewUtilsTest {
+
+ lateinit var latLng : LatLng
+
+ val apiKey = "AN_API_KEY"
+
+ @Before
+ fun setUp() {
+ latLng = LatLng(37.7749, -122.4194) // San Francisco coordinates
+
+ // Mock the network behavior using MockK
+ mockkObject(StreetViewUtils)
+ coEvery { StreetViewUtils.fetchStreetViewData(any(), any()) } returns Status.NOT_FOUND
+ coEvery { StreetViewUtils.fetchStreetViewData(latLng, apiKey) } returns Status.OK
+ }
+
+ @Test
+ fun testLocationFoundOnStreetView() = runBlocking {
+ val status = StreetViewUtils.fetchStreetViewData(latLng, apiKey)
+ assertEquals(Status.OK, status)
+ }
+
+ @Test
+ fun testLocationNotFoundOnStreetView() = runBlocking {
+ val status = StreetViewUtils.fetchStreetViewData(LatLng(10.0, 20.0), apiKey)
+ assertEquals(Status.NOT_FOUND, status)
+ }
+}
+
diff --git a/local.defaults.properties b/local.defaults.properties
index 818d21b20..420e23930 100644
--- a/local.defaults.properties
+++ b/local.defaults.properties
@@ -1 +1 @@
-MAPS_API_KEY="YOUR_API_KEY"
\ No newline at end of file
+MAPS_API_KEY="AIzaSyA4SCF8hbjd5M3pq-FncAtSu1uTe_yaQBg"
\ No newline at end of file