Skip to content

Commit

Permalink
feat: Try to catch invalid map api keys in the demo
Browse files Browse the repository at this point in the history
feat: Export the demo activities so they can be run directly
chore: Update gradle version, Google maps to 19.0.0
  • Loading branch information
dkhawk committed Oct 8, 2024
1 parent dd85f6f commit e9e20bd
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 37 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/

buildscript {
ext.kotlin_version = '1.9.24'
ext.kotlin_version = '2.0.0'
repositories {
google()
mavenCentral()
Expand All @@ -24,7 +24,7 @@ buildscript {
}
}
dependencies {
classpath 'com.android.tools.build:gradle:8.4.0'
classpath 'com.android.tools.build:gradle:8.7.0'
classpath 'com.mxalbert.gradle:jacoco-android:0.2.1'
classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
Expand Down
4 changes: 2 additions & 2 deletions demo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ dependencies {
// [START_EXCLUDE silent]
implementation project(':library')

implementation 'androidx.appcompat:appcompat:1.7.0-beta01'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.6"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1'
Expand Down
85 changes: 60 additions & 25 deletions demo/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8" standalone="no"?><!--
Copyright 2024 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -14,7 +13,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

Expand Down Expand Up @@ -58,35 +56,72 @@
android:value="${MAPS_API_KEY}" />

<activity
android:exported="true"
android:name=".MainActivity"
android:label="@string/app_name">
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity android:name=".PolyDecodeDemoActivity" />
<activity android:name=".PolySimplifyDemoActivity" />
<activity android:name=".IconGeneratorDemoActivity" />
<activity android:name=".DistanceDemoActivity" />
<activity android:name=".ClusteringDemoActivity" />
<activity android:name=".BigClusteringDemoActivity" />
<activity android:name=".VisibleClusteringDemoActivity" />
<activity android:name=".CustomMarkerClusteringDemoActivity" />
<activity android:name=".CustomAdvancedMarkerClusteringDemoActivity" />
<activity android:name=".ZoomClusteringDemoActivity" />
<activity android:name=".ClusteringViewModelDemoActivity"/>
<activity android:name=".TileProviderAndProjectionDemo" />
<activity android:name=".HeatmapsDemoActivity" />
<activity android:name=".HeatmapsPlacesDemoActivity" />
<activity android:name=".GeoJsonDemoActivity" />
<activity android:name=".KmlDemoActivity" />
<activity android:name=".MultiLayerDemoActivity" />
<activity android:name=".AnimationUtilDemoActivity" />
<activity android:name=".StreetViewDemoActivity" />
<activity
android:name=".PolyDecodeDemoActivity"
android:exported="true" />
<activity
android:name=".PolySimplifyDemoActivity"
android:exported="true" />
<activity
android:name=".IconGeneratorDemoActivity"
android:exported="true" />
<activity
android:name=".DistanceDemoActivity"
android:exported="true" />
<activity
android:name=".ClusteringDemoActivity"
android:exported="true" />
<activity
android:name=".BigClusteringDemoActivity"
android:exported="true" />
<activity
android:name=".VisibleClusteringDemoActivity"
android:exported="true" />
<activity
android:name=".CustomMarkerClusteringDemoActivity"
android:exported="true" />
<activity
android:name=".CustomAdvancedMarkerClusteringDemoActivity"
android:exported="true" />
<activity
android:name=".ZoomClusteringDemoActivity"
android:exported="true" />
<activity
android:name=".ClusteringViewModelDemoActivity"
android:exported="true" />
<activity
android:name=".TileProviderAndProjectionDemo"
android:exported="true" />
<activity
android:name=".HeatmapsDemoActivity"
android:exported="true" />
<activity
android:name=".HeatmapsPlacesDemoActivity"
android:exported="true" />
<activity
android:name=".GeoJsonDemoActivity"
android:exported="true" />
<activity
android:name=".KmlDemoActivity"
android:exported="true" />
<activity
android:name=".MultiLayerDemoActivity"
android:exported="true" />
<activity
android:name=".AnimationUtilDemoActivity"
android:exported="true" />
<activity
android:name=".StreetViewDemoActivity"
android:exported="true" />

</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.google.maps.android.utils.demo

import android.content.Context
import android.content.pm.PackageManager
import java.util.regex.Pattern

/**
* Checks if the provided context has a valid Google Maps API key in its metadata.
*
*
* This method retrieves the API key from the application's metadata and returns whether or
* not it has a valid format.
*
* @param context The context to check for the API key.
* @return `true` if the context has a valid API key, `false` otherwise.
*/
fun hasMapsApiKey(context: Context): Boolean {
val mapsApiKey = getMapsApiKey(context)

return mapsApiKey != null && keyHasValidFormat(mapsApiKey)
}

/**
* Checks if the provided API key has a valid format.
*
*
* The valid format is defined by the regular expression "^AIza[0-9A-Za-z\\-_]{35}$".
*
* @param apiKey The API key to validate.
* @return `true` if the API key has a valid format, `false` otherwise.
*/
private fun keyHasValidFormat(apiKey: String): Boolean {
val regex = "^AIza[0-9A-Za-z\\-_]{35}$"
val pattern = Pattern.compile(regex)
val matcher = pattern.matcher(apiKey)
return matcher.matches()
}

/**
* Retrieves the Google Maps API key from the application metadata.
*
* @param context The context to retrieve the API key from.
* @return The API key if found, `null` otherwise.
*/
private fun getMapsApiKey(context: Context): String? {
try {
val bundle = context.packageManager
.getApplicationInfo(context.packageName, PackageManager.GET_META_DATA)
.metaData
return bundle.getString("com.google.android.geo.API_KEY")
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
return null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@

package com.google.maps.android.utils.demo;

import static com.google.maps.android.utils.demo.ApiKeyValidatorKt.hasMapsApiKey;

import android.os.Bundle;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
Expand All @@ -36,6 +39,12 @@ protected int getLayoutId() {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (!hasMapsApiKey(this)) {
Toast.makeText(this, R.string.bad_maps_api_key, Toast.LENGTH_LONG).show();
finish();
}

mIsRestore = savedInstanceState != null;
setContentView(getLayoutId());
setUpMap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

public class ClusteringViewModel extends ViewModel {

private NonHierarchicalViewBasedAlgorithm<MyItem> mAlgorithm = new NonHierarchicalViewBasedAlgorithm<>(0, 0);
private final NonHierarchicalViewBasedAlgorithm<MyItem> mAlgorithm = new NonHierarchicalViewBasedAlgorithm<>(0, 0);

NonHierarchicalViewBasedAlgorithm<MyItem> getAlgorithm() {
return mAlgorithm;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.google.maps.android.utils.demo;

import static com.google.maps.android.utils.demo.ApiKeyValidatorKt.hasMapsApiKey;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
Expand All @@ -32,12 +34,14 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

if (BuildConfig.MAPS_API_KEY.isEmpty()) {
Toast.makeText(this, "Add your own API key in local.properties as MAPS_API_KEY=YOUR_API_KEY", Toast.LENGTH_LONG).show();
if (!hasMapsApiKey(this)) {
Toast.makeText(this, R.string.bad_maps_api_key, Toast.LENGTH_LONG).show();
finish();
}

setContentView(R.layout.main);

mListView = findViewById(R.id.list);

addDemo("Clustering", ClusteringDemoActivity.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.google.maps.android.utils.demo
import android.app.Activity
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.StreetViewUtils
import kotlinx.coroutines.DelicateCoroutinesApi
Expand All @@ -33,6 +34,11 @@ class StreetViewDemoActivity : Activity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.street_view_demo)

if (!hasMapsApiKey(this)) {
Toast.makeText(this, R.string.bad_maps_api_key, Toast.LENGTH_LONG).show()
finish()
}

GlobalScope.launch(Dispatchers.Main) {
val response1 =
StreetViewUtils.fetchStreetViewData(LatLng(48.1425918, 11.5386121), BuildConfig.MAPS_API_KEY)
Expand All @@ -43,4 +49,3 @@ class StreetViewDemoActivity : Activity() {
}
}
}

1 change: 1 addition & 0 deletions demo/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@
<string name="button_radius">Radius</string>
<string name="button_gradient">Gradient</string>
<string name="button_opacity">Opacity</string>
<string name="bad_maps_api_key">Invalid or missing Google Maps API key</string>
</resources>
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
networkTimeout=10000
validateDistributionUrl=true
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
4 changes: 2 additions & 2 deletions library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ android {

dependencies {
// We are adding api() for the Maps SDK for Android, so it propagates to the app-level modules.
api 'com.google.android.gms:play-services-maps:18.2.0'
api 'com.google.android.gms:play-services-maps:19.0.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.core:core-ktx:1.13.1'
lintPublish project(':lint-checks')
testImplementation 'junit:junit:4.13.2'
Expand Down

0 comments on commit e9e20bd

Please sign in to comment.