Java tutorial
/* * Copyright (C) 2012 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.campusclipper.android; import java.util.ArrayList; import java.util.List; import java.util.Random; import android.annotation.SuppressLint; import android.graphics.Color; import android.location.Location; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; import android.support.v4.app.Fragment; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.animation.BounceInterpolator; import android.view.animation.Interpolator; import android.widget.Button; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.RadioGroup; import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks; import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener; import com.google.android.gms.location.LocationClient; import com.google.android.gms.location.LocationListener; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.maps.CameraUpdate; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter; import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener; import com.google.android.gms.maps.GoogleMap.OnMyLocationButtonClickListener; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.LatLngBounds; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; /** * This demo shows how GMS Location can be used to check for changes to the users location. The * "My Location" button uses GMS Location to set the blue dot representing the users location. To * track changes to the users location on the map, we request updates from the * {@link LocationClient}. */ public class MyLocationActivity extends Fragment implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener, OnMyLocationButtonClickListener, OnMarkerClickListener // OnMarkerDragListener, //OnInfoWindowClickListener // OnSeekBarChangeListener { private GoogleMap mMap; private LocationClient mLocationClient; private TextView mMessageView; private View mRootView; private Bundle mBundle; private ViewGroup mContainer; private static final LatLng BRISBANE = new LatLng(-27.47093, 153.0235); private static final LatLng MELBOURNE = new LatLng(-37.81319, 144.96298); private static final LatLng SYDNEY = new LatLng(-33.87365, 151.20689); private static final LatLng ADELAIDE = new LatLng(-34.92873, 138.59995); private static final LatLng PERTH = new LatLng(-31.952854, 115.857342); /** Demonstrates customizing the info window and/or its contents. */ class CustomInfoWindowAdapter implements InfoWindowAdapter { private final RadioGroup mOptions; // These a both viewgroups containing an ImageView with id "badge" and two TextViews with id // "title" and "snippet". private final View mWindow; private final View mContents; CustomInfoWindowAdapter() { mWindow = getLayoutInflater(mBundle).inflate(R.layout.custom_info_window, mContainer);// mContents = getLayoutInflater(mBundle).inflate(R.layout.custom_info_contents, mContainer);// mOptions = (RadioGroup) mRootView.findViewById(R.id.custom_info_window_options); } @Override public View getInfoWindow(Marker marker) { if (mOptions == null) { Toast.makeText(getActivity(), "mOptions is null!!", Toast.LENGTH_LONG).show(); return mWindow; } if (mOptions.getCheckedRadioButtonId() != R.id.custom_info_window) { // This means that getInfoContents will be called. return null; } render(marker, mWindow); return mWindow; } @Override public View getInfoContents(Marker marker) { if (mOptions.getCheckedRadioButtonId() != R.id.custom_info_contents) { // This means that the default info contents will be used. return null; } render(marker, mContents); return mContents; } private void render(Marker marker, View view) { int badge; // Use the equals() method on a Marker to check for equals. Do not use ==. if (marker.equals(mBrisbane)) { badge = R.drawable.badge_qld; } else if (marker.equals(mAdelaide)) { badge = R.drawable.badge_sa; } else if (marker.equals(mSydney)) { badge = R.drawable.badge_nsw; } else if (marker.equals(mMelbourne)) { badge = R.drawable.badge_victoria; } else if (marker.equals(mPerth)) { badge = R.drawable.badge_wa; } else { // Passing 0 to setImageResource will clear the image view. badge = 0; } ((ImageView) view.findViewById(R.id.badge)).setImageResource(badge); String title = marker.getTitle(); TextView titleUi = ((TextView) view.findViewById(R.id.title)); if (title != null) { // Spannable string allows us to edit the formatting of the text. SpannableString titleText = new SpannableString(title); titleText.setSpan(new ForegroundColorSpan(Color.RED), 0, titleText.length(), 0); titleUi.setText(titleText); } else { titleUi.setText(""); } String snippet = marker.getSnippet(); TextView snippetUi = ((TextView) view.findViewById(R.id.snippet)); if (snippet != null && snippet.length() > 12) { SpannableString snippetText = new SpannableString(snippet); snippetText.setSpan(new ForegroundColorSpan(Color.MAGENTA), 0, 10, 0); snippetText.setSpan(new ForegroundColorSpan(Color.BLUE), 12, snippet.length(), 0); snippetUi.setText(snippetText); } else { snippetUi.setText(""); } } } private Marker mPerth; private Marker mSydney; private Marker mBrisbane; private Marker mAdelaide; private Marker mMelbourne; private final List<Marker> mMarkerRainbow = new ArrayList<Marker>(); private TextView mTopText; private SeekBar mRotationBar; private CheckBox mFlatBox; private final Random mRandom = new Random(); // These settings are the same as the settings for the map. They will in fact give you updates // at the maximal rates currently possible. private static final LocationRequest REQUEST = LocationRequest.create().setInterval(5000) // 5 seconds .setFastestInterval(16) // 16ms = 60fps .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); Toast.makeText(getActivity(), "onCreateView is called", Toast.LENGTH_SHORT).show(); mBundle = savedInstanceState; mContainer = container; mRootView = inflater.inflate(R.layout.activity_my_location, container, false); mTopText = (TextView) mRootView.findViewById(R.id.top_text); mTopText = (TextView) mRootView.findViewById(R.id.top_text); mRotationBar = (SeekBar) mRootView.findViewById(R.id.rotationSeekBar); mRotationBar.setMax(360); mFlatBox = (CheckBox) mRootView.findViewById(R.id.flat); mMessageView = (TextView) mRootView.findViewById(R.id.message_text); ((Button) (mRootView.findViewById(R.id.get_my_location_button))) .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showMyLocation(getView()); LatLng current = new LatLng(mLocationClient.getLastLocation().getLatitude(), mLocationClient.getLastLocation().getLongitude()); mMap.addMarker(new MarkerOptions().position(current).title("Marker")); } }); ((CheckBox) (mRootView.findViewById(R.id.flat))).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onToggleFlat(getView()); } }); if (mMessageView == null) Toast.makeText(getActivity(), "But message view is still null", Toast.LENGTH_LONG).show(); if (mRootView.getViewTreeObserver().isAlive()) { mRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @SuppressWarnings("deprecation") // We use the new method when supported @SuppressLint("NewApi") // We check which build version we are using. @Override public void onGlobalLayout() { LatLngBounds bounds = new LatLngBounds.Builder().include(PERTH).include(SYDNEY) .include(ADELAIDE).include(BRISBANE).include(MELBOURNE).build(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { mRootView.getViewTreeObserver().removeGlobalOnLayoutListener(this); } else { mRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50)); } }); } setUpMapIfNeeded(); // LatLng current = new LatLng(mLocationClient.getLastLocation().getLatitude(),mLocationClient.getLastLocation().getLongitude()); // mMap.addMarker(new MarkerOptions().position(current).title("Marker")); // CameraUpdate yourLocation = CameraUpdateFactory.newLatLngZoom(current, 13); // mMap.animateCamera(yourLocation); return mRootView; } @Override public void onResume() { Toast.makeText(getActivity(), "ML resume", Toast.LENGTH_SHORT).show(); super.onResume(); setUpMapIfNeeded(); setUpLocationClientIfNeeded(); mLocationClient.connect(); } @Override public void onPause() { Toast.makeText(getActivity(), "ML onPause", Toast.LENGTH_SHORT).show(); super.onPause(); if (mLocationClient != null) { mLocationClient.disconnect(); } } private void setUpMapIfNeeded() { Toast.makeText(getActivity(), "SetupMapIfNeeded", Toast.LENGTH_SHORT).show(); // Do a null check to confirm that we have not already instantiated the map. if (mMap == null) { // Try to obtain the map from the SupportMapFragment. mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap(); // Check if we were successful in obtaining the map. if (mMap != null) { mMap.setMyLocationEnabled(true); mMap.setOnMyLocationButtonClickListener(this); setUpMap(); } } } private void setUpLocationClientIfNeeded() { if (mLocationClient == null) { mLocationClient = new LocationClient(getActivity(), this, // ConnectionCallbacks this); // OnConnectionFailedListener } } /** * Button to get current Location. This demonstrates how to get the current Location as required * without needing to register a LocationListener. */ public void showMyLocation(View view) { if (mLocationClient != null && mLocationClient.isConnected()) { String msg = "Location = " + mLocationClient.getLastLocation(); Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show(); } } /** * Implementation of {@link LocationListener}. */ @Override public void onLocationChanged(Location location) { if (mMessageView == null) { Toast.makeText(getActivity(), "It's null, can't make text", Toast.LENGTH_LONG).show(); return; } mMessageView.setText("Location = " + location); } /** * Callback called when connected to GCore. Implementation of {@link ConnectionCallbacks}. */ @Override public void onConnected(Bundle connectionHint) { Toast.makeText(getActivity(), "ML onConnected", Toast.LENGTH_SHORT).show(); mLocationClient.requestLocationUpdates(REQUEST, this); // LocationListener LatLng current = new LatLng(mLocationClient.getLastLocation().getLatitude(), mLocationClient.getLastLocation().getLongitude()); mMap.addMarker(new MarkerOptions().position(current).title("Marker")); CameraUpdate yourLocation = CameraUpdateFactory.newLatLngZoom(current, 13); mMap.animateCamera(yourLocation); } /** * Callback called when disconnected from GCore. Implementation of {@link ConnectionCallbacks}. */ @Override public void onDisconnected() { // Do nothing Toast.makeText(getActivity(), "ML onDisconnected", Toast.LENGTH_SHORT).show(); } /** * Implementation of {@link OnConnectionFailedListener}. */ @Override public void onConnectionFailed(ConnectionResult result) { // Do nothing } //OnClickListener of the button @Override public boolean onMyLocationButtonClick() { Toast.makeText(getActivity(), "MyLocation button clicked", Toast.LENGTH_SHORT).show(); showMyLocation(getView()); //LatLng current = new LatLng(mLocationClient.getLastLocation().getLatitude(),mLocationClient.getLastLocation().getLongitude()); //mMap.addMarker(new MarkerOptions().position(current).title("Marker")); // Return false so that we don't consume the event and the default behavior still occurs // (the camera animates to the user's current position). return false; } @Override public void onDestroyView() { super.onDestroyView(); Fragment f = getFragmentManager().findFragmentById(R.id.map); if (f != null) getFragmentManager().beginTransaction().remove(f).commit(); } private void setUpMap() { // Hide the zoom controls as the button panel will cover it. mMap.getUiSettings().setZoomControlsEnabled(false); // Add lots of markers to the map. addMarkersToMap(); // Setting an info window adapter allows us to change the both the contents and look of the // info window. mMap.setInfoWindowAdapter(new CustomInfoWindowAdapter()); // Set listeners for marker events. See the bottom of this class for their behavior. mMap.setOnMarkerClickListener(this); //mMap.setOnInfoWindowClickListener(this); // Pan to see all markers in view. // Cannot zoom to bounds until the map has a size. // final View mRootView = getSupportFragmentManager().findFragmentById(R.id.map).getView(); if (mRootView.getViewTreeObserver().isAlive()) { mRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @SuppressWarnings("deprecation") // We use the new method when supported @SuppressLint("NewApi") // We check which build version we are using. @Override public void onGlobalLayout() { LatLngBounds bounds = new LatLngBounds.Builder().include(PERTH).include(SYDNEY) .include(ADELAIDE).include(BRISBANE).include(MELBOURNE).build(); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { mRootView.getViewTreeObserver().removeGlobalOnLayoutListener(this); } else { mRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50)); } }); } } private void addMarkersToMap() { // Uses a colored icon. mBrisbane = mMap .addMarker(new MarkerOptions().position(BRISBANE).title("Brisbane").snippet("Population: 2,074,200") .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))); // Uses a custom icon with the info window popping out of the center of the icon. mSydney = mMap .addMarker(new MarkerOptions().position(SYDNEY).title("Sydney").snippet("Population: 4,627,300") .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)).infoWindowAnchor(0.5f, 0.5f)); // Creates a draggable marker. Long press to drag. mMelbourne = mMap.addMarker(new MarkerOptions().position(MELBOURNE).title("Melbourne") .snippet("Population: 4,137,400").draggable(true)); // A few more markers for good measure. mPerth = mMap .addMarker(new MarkerOptions().position(PERTH).title("Perth").snippet("Population: 1,738,800")); mAdelaide = mMap.addMarker( new MarkerOptions().position(ADELAIDE).title("Adelaide").snippet("Population: 1,213,000")); // Creates a marker rainbow demonstrating how to create default marker icons of different // hues (colors). float rotation = mRotationBar.getProgress(); boolean flat = mFlatBox.isChecked(); int numMarkersInRainbow = 12; for (int i = 0; i < numMarkersInRainbow; i++) { mMarkerRainbow.add(mMap.addMarker(new MarkerOptions() .position(new LatLng(-30 + 10 * Math.sin(i * Math.PI / (numMarkersInRainbow - 1)), 135 - 10 * Math.cos(i * Math.PI / (numMarkersInRainbow - 1)))) .title("Marker " + i).icon(BitmapDescriptorFactory.defaultMarker(i * 360 / numMarkersInRainbow)) .flat(flat).rotation(rotation))); } } private boolean checkReady() { if (mMap == null) { Toast.makeText(getActivity(), R.string.map_not_ready, Toast.LENGTH_SHORT).show(); return false; } return true; } /** Called when the Clear button is clicked. */ public void onClearMap(View view) { if (!checkReady()) { return; } mMap.clear(); } /** Called when the Reset button is clicked. */ public void onResetMap(View view) { if (!checkReady()) { return; } // Clear the map because we don't want duplicates of the markers. mMap.clear(); addMarkersToMap(); } /** Called when the Reset button is clicked. */ public void onToggleFlat(View view) { if (!checkReady()) { return; } boolean flat = mFlatBox.isChecked(); for (Marker marker : mMarkerRainbow) { marker.setFlat(flat); } } // // Marker related listeners. // @Override public boolean onMarkerClick(final Marker marker) { if (marker.equals(mPerth)) { // This causes the marker at Perth to bounce into position when it is clicked. final Handler handler = new Handler(); final long start = SystemClock.uptimeMillis(); final long duration = 1500; final Interpolator interpolator = new BounceInterpolator(); handler.post(new Runnable() { @Override public void run() { long elapsed = SystemClock.uptimeMillis() - start; float t = Math.max(1 - interpolator.getInterpolation((float) elapsed / duration), 0); marker.setAnchor(0.5f, 1.0f + 2 * t); if (t > 0.0) { // Post again 16ms later. handler.postDelayed(this, 16); } } }); } else if (marker.equals(mAdelaide)) { // This causes the marker at Adelaide to change color and alpha. marker.setIcon(BitmapDescriptorFactory.defaultMarker(mRandom.nextFloat() * 360)); marker.setAlpha(mRandom.nextFloat()); } // We return false to indicate that we have not consumed the event and that we wish // for the default behavior to occur (which is for the camera to move such that the // marker is centered and for the marker's info window to open, if it has one). return false; } }