diff --git a/ApiDemos/app/src/main/AndroidManifest.xml b/ApiDemos/app/src/main/AndroidManifest.xml
index 35d0cde8..90d1b86f 100644
--- a/ApiDemos/app/src/main/AndroidManifest.xml
+++ b/ApiDemos/app/src/main/AndroidManifest.xml
@@ -20,7 +20,7 @@
@@ -45,7 +45,7 @@
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
- You can define the keys for the debug and release targets in src/debug/ and src/release/.
+ You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
+
diff --git a/ApiDemos/app/src/main/java/com/example/mapdemo/CameraClampingDemoActivity.java b/ApiDemos/app/src/main/java/com/example/mapdemo/CameraClampingDemoActivity.java
new file mode 100644
index 00000000..f62ccc1f
--- /dev/null
+++ b/ApiDemos/app/src/main/java/com/example/mapdemo/CameraClampingDemoActivity.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * 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.example.mapdemo;
+
+import com.google.android.gms.maps.CameraUpdateFactory;
+import com.google.android.gms.maps.GoogleMap;
+import com.google.android.gms.maps.GoogleMap.OnCameraIdleListener;
+import com.google.android.gms.maps.OnMapReadyCallback;
+import com.google.android.gms.maps.SupportMapFragment;
+import com.google.android.gms.maps.model.CameraPosition;
+import com.google.android.gms.maps.model.LatLng;
+import com.google.android.gms.maps.model.LatLngBounds;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/**
+ * This shows how to constrain the camera to specific boundaries and zoom levels.
+ */
+public class CameraClampingDemoActivity extends AppCompatActivity
+ implements OnMapReadyCallback, OnCameraIdleListener {
+
+ private static final String TAG = CameraClampingDemoActivity.class.getSimpleName();
+
+ private static final float ZOOM_DELTA = 2.0f;
+ private static final float DEFAULT_MIN_ZOOM = 2.0f;
+ private static final float DEFAULT_MAX_ZOOM = 22.0f;
+
+ private static final LatLngBounds ADELAIDE = new LatLngBounds(
+ new LatLng(-35.0, 138.58), new LatLng(-34.9, 138.61));
+ private static final CameraPosition ADELAIDE_CAMERA = new CameraPosition.Builder()
+ .target(new LatLng(-34.92873, 138.59995)).zoom(20.0f).bearing(0).tilt(0).build();
+
+ private static final LatLngBounds PACIFIC = new LatLngBounds(
+ new LatLng(-15.0, 165.0), new LatLng(15.0, -165.0));
+ private static final CameraPosition PACIFIC_CAMERA = new CameraPosition.Builder()
+ .target(new LatLng(0, -180)).zoom(4.0f).bearing(0).tilt(0).build();
+
+ private GoogleMap mMap;
+
+ /**
+ * Internal min zoom level that can be toggled via the demo.
+ */
+ private float mMinZoom;
+
+ /**
+ * Internal max zoom level that can be toggled via the demo.
+ */
+ private float mMaxZoom;
+
+ private TextView mCameraTextView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.camera_clamping_demo);
+
+ mMap = null;
+ resetMinMaxZoom();
+
+ mCameraTextView = (TextView) findViewById(R.id.camera_text);
+
+ SupportMapFragment mapFragment =
+ (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
+ mapFragment.getMapAsync(this);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ }
+
+ @Override
+ public void onMapReady(GoogleMap map) {
+ mMap = map;
+ map.setOnCameraIdleListener(this);
+ }
+
+ @Override
+ public void onCameraIdle() {
+ mCameraTextView.setText(mMap.getCameraPosition().toString());
+ }
+
+ /**
+ * Before the map is ready many calls will fail.
+ * This should be called on all entry points that call methods on the Google Maps API.
+ */
+ private boolean checkReady() {
+ if (mMap == null) {
+ Toast.makeText(this, R.string.map_not_ready, Toast.LENGTH_SHORT).show();
+ return false;
+ }
+ return true;
+ }
+
+ private void toast(String msg) {
+ Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
+ }
+
+ private void resetMinMaxZoom() {
+ mMinZoom = DEFAULT_MIN_ZOOM;
+ mMaxZoom = DEFAULT_MAX_ZOOM;
+ }
+
+ /**
+ * Click handler for clamping to Adelaide button.
+ * @param view
+ */
+ public void onClampToAdelaide(View view) {
+ if (!checkReady()) {
+ return;
+ }
+ mMap.setLatLngBoundsForCameraTarget(ADELAIDE);
+ mMap.animateCamera(CameraUpdateFactory.newCameraPosition(ADELAIDE_CAMERA));
+ }
+
+ /**
+ * Click handler for clamping to Pacific button.
+ * @param view
+ */
+ public void onClampToPacific(View view) {
+ if (!checkReady()) {
+ return;
+ }
+ mMap.setLatLngBoundsForCameraTarget(PACIFIC);
+ mMap.animateCamera(CameraUpdateFactory.newCameraPosition(PACIFIC_CAMERA));
+ }
+
+ public void onLatLngClampReset(View view) {
+ if (!checkReady()) {
+ return;
+ }
+ // Setting bounds to null removes any previously set bounds.
+ mMap.setLatLngBoundsForCameraTarget(null);
+ toast("LatLngBounds clamp reset.");
+ }
+
+ public void onSetMinZoomClamp(View view) {
+ if (!checkReady()) {
+ return;
+ }
+ mMinZoom += ZOOM_DELTA;
+ // Constrains the minimum zoom level.
+ mMap.setMinZoomPreference(mMinZoom);
+ toast("Min zoom preference set to: " + mMinZoom);
+ }
+
+ public void onSetMaxZoomClamp(View view) {
+ if (!checkReady()) {
+ return;
+ }
+ mMaxZoom -= ZOOM_DELTA;
+ // Constrains the maximum zoom level.
+ mMap.setMaxZoomPreference(mMaxZoom);
+ toast("Max zoom preference set to: " + mMaxZoom);
+ }
+
+ public void onMinMaxZoomClampReset(View view) {
+ if (!checkReady()) {
+ return;
+ }
+ resetMinMaxZoom();
+ mMap.resetMinMaxZoomPreference();
+ toast("Min/Max zoom preferences reset.");
+ }
+}
\ No newline at end of file
diff --git a/ApiDemos/app/src/main/res/layout/camera_clamping_demo.xml b/ApiDemos/app/src/main/res/layout/camera_clamping_demo.xml
new file mode 100644
index 00000000..f86e4241
--- /dev/null
+++ b/ApiDemos/app/src/main/res/layout/camera_clamping_demo.xml
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ApiDemos/app/src/main/res/values/strings.xml b/ApiDemos/app/src/main/res/values/strings.xml
index e826f18e..a0e39cd4 100755
--- a/ApiDemos/app/src/main/res/values/strings.xml
+++ b/ApiDemos/app/src/main/res/values/strings.xml
@@ -28,6 +28,16 @@
Demonstrates camera functions.CirclesDemonstrates how to add Circles to a map.
+
+ Camera Clamping
+ Demonstrates how to constrain the camera to specific boundaries and zoom levels.
+ Clamp to Adelaide
+ Clamp to Pacific
+ Reset LatLng Bounds
+ MinZoom++
+ MaxZoom--
+ Reset Zoom Bounds
+
ClearClickableCompass