Java tutorial
package com.appdynamics.demo.gasp.activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.location.Location; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.Button; import com.appdynamics.demo.gasp.R; import com.appdynamics.demo.gasp.adapter.GaspDatabase; import com.appdynamics.demo.gasp.gcm.GCMIntentService; import com.appdynamics.demo.gasp.gcm.GaspRegistrationClient; import com.appdynamics.demo.gasp.location.GaspPlaces; import com.appdynamics.demo.gasp.location.GaspSearch; import com.appdynamics.demo.gasp.model.Place; import com.appdynamics.demo.gasp.model.PlaceDetails; import com.appdynamics.demo.gasp.model.Places; import com.appdynamics.demo.gasp.model.Query; import com.appdynamics.demo.gasp.model.Restaurant; import com.appdynamics.demo.gasp.model.SearchResult; import com.appdynamics.demo.gasp.service.RestaurantSyncService; import com.appdynamics.demo.gasp.service.ReviewSyncService; import com.appdynamics.demo.gasp.service.UserSyncService; import com.appdynamics.demo.gasp.twitter.TwitterAuthentication; import com.appdynamics.demo.gasp.utils.LocationServices; import com.appdynamics.demo.gasp.utils.Network; import com.appdynamics.demo.gasp.utils.PlayServices; import com.appdynamics.demo.gasp.utils.Preferences; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import java.util.HashMap; import com.appdynamics.eumagent.runtime.Instrumentation; /** * Copyright (c) 2013 Mark Prichard * <p/> * 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 * <p/> * http://www.apache.org/licenses/LICENSE-2.0 * <p/> * 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. */ public class LocationsActivity extends FragmentActivity { private static final String TAG = LocationsActivity.class.getName(); // Google Maps and Location private GoogleMap mMap; private float mZoom = 16; private Location mLocation; // Incremental search results from Google Places API private SearchResult mSearchResult = new SearchResult(); // Next page token for Google Places API queries private String mPageToken = ""; // Bundle serialization keys private static final String PAGE_TOKEN = "PAGE_TOKEN"; private static final String SEARCH_RESULT = "SEARCH_RESULT"; private static final String ZOOM_LEVEL = "ZOOM_LEVEL"; // Gasp proxy objects private final GaspSearch mGaspSearch = new GaspSearch() { @Override public void onSuccess(Places places) { mSearchResult.add(places); showLocations(mSearchResult); checkToken(places); } @Override public void onFailure(String status) { Log.e(TAG, "Google Places API search failed: status = " + status); } }; private final GaspPlaces mGaspPlaces = new GaspPlaces() { @Override public void onSuccess(PlaceDetails placeDetails) { launchPlacesDetailActivity(placeDetails); } @Override public void onFailure(String status) { Log.e(TAG, "Google Places API search failed: status = " + status); } }; private final GaspDatabase mGaspDatabase = new GaspDatabase(this); // Map GoogleMap Markers to Place Ids private final HashMap<String, String> mPlacesMap = new HashMap<String, String>(); // Map Place Ids to Reference strings private final HashMap<String, String> mReferencesMap = new HashMap<String, String>(); // On initial load, we need to wait for Gasp data sync before drawing location markers private static boolean waitForSync = true; public static final String SYNC_COMPLETED = "gasp-sync"; // Proxy to handle Gasp GCM registration services private final GaspRegistrationClient mGaspRegistrationClient = new GaspRegistrationClient(); /** * Start Gasp data synchronization services * Handle initial REST sync and GCM updates */ private void startDataSyncServices() { Intent reviewsIntent = new Intent(this, ReviewSyncService.class); reviewsIntent.putExtra(GCMIntentService.PARAM_IN_MSG, "reviews"); startService(reviewsIntent); Intent restaurantsIntent = new Intent(this, RestaurantSyncService.class); restaurantsIntent.putExtra(GCMIntentService.PARAM_IN_MSG, "restaurants"); startService(restaurantsIntent); Intent usersIntent = new Intent(this, UserSyncService.class); usersIntent.putExtra(GCMIntentService.PARAM_IN_MSG, "users"); startService(usersIntent); } /** * Button Listener for "More Locations" button */ private void addButtonListener() { Button placesButton = (Button) findViewById(R.id.places_button); placesButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getLocations(); } }); } /** * Click listener for Google Maps markers */ private void setMarkerClickListener() { mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { Log.d(TAG, "Place Id: " + mPlacesMap.get(marker.getId())); Log.d(TAG, "Reference: " + mReferencesMap.get(mPlacesMap.get(marker.getId()))); mGaspPlaces.placeDetails(new Query(mReferencesMap.get(mPlacesMap.get(marker.getId())))); return false; } }); } /** * Set Camera for Google Maps API */ private void setCamera() { try { LatLng myLocation = new LatLng(mLocation.getLatitude(), mLocation.getLongitude()); CameraPosition cameraPosition = new CameraPosition.Builder().target(myLocation).zoom(mZoom).bearing(0) .tilt(0).build(); mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); } catch (Exception e) { e.printStackTrace(); } } /** * Do Google Places API search (centred on current location, radius from shared preferences) */ private void getLocations() { try { Preferences preferences = new Preferences(this); Query query = new Query(mLocation.getLatitude(), mLocation.getLongitude(), Preferences.getGaspSearchRadius(), mPageToken); mGaspSearch.nearbySearch(query); } catch (Exception e) { e.printStackTrace(); } } /** * Display location via Google Maps API * @param searchResult Gasp! Locations to display */ private void showLocations(SearchResult searchResult) { Restaurant restaurant; float markerColour; try { for (Place place : searchResult.getPlaces()) { LatLng pos = new LatLng(place.getGeometry().getLocation().getLat().doubleValue(), place.getGeometry().getLocation().getLng().doubleValue()); restaurant = mGaspDatabase.getRestaurantByPlacesId(place.getId()); if (restaurant != null) markerColour = BitmapDescriptorFactory.HUE_GREEN; else markerColour = BitmapDescriptorFactory.HUE_RED; Marker marker = mMap.addMarker(new MarkerOptions().position(pos).title(place.getName()) .icon(BitmapDescriptorFactory.defaultMarker(markerColour))); Log.d(TAG, place.getName() + " " + pos.toString()); mPlacesMap.put(marker.getId(), place.getId()); mReferencesMap.put(place.getId(), place.getReference()); } } catch (Exception e) { e.printStackTrace(); } } /** * Check Google Places API search result for page_token * Indicates more results available: enable "More Locations" button * See @link{https://developers.google.com/places/documentation/search} for details * @param places Google Places API return (converted from JSON) */ private void checkToken(Places places) { try { if (places.getNext_page_token() == null) { mPageToken = ""; setPlacesButton(false); } else { mPageToken = places.getNext_page_token(); Log.d(TAG, "Next page token: " + mPageToken); setPlacesButton(true); } } catch (Exception e) { e.printStackTrace(); } } /** * Launch child activity to display details for selected Gasp! location * @param placeDetails Details for Gasp! location */ private void launchPlacesDetailActivity(PlaceDetails placeDetails) { try { Intent intent = new Intent(); intent.setClass(LocationsActivity.this, PlacesDetailActivity.class); intent.putExtra(PlacesDetailActivity.PLACES_DETAIL_SERIALIZED, placeDetails.getResult()); intent.putExtra(PlacesDetailActivity.PLACES_DETAIL_REFERENCE, mReferencesMap.get(placeDetails.getResult().getId())); startActivityForResult(intent, 0); } catch (Exception e) { e.printStackTrace(); } } /** * Enable/disable "More Locations" button * @param enableButton enable or disable button */ private void setPlacesButton(boolean enableButton) { Button placesButton = (Button) findViewById(R.id.places_button); placesButton.setText("More Locations"); if (enableButton) { placesButton.setEnabled(true); } else { placesButton.setEnabled(false); } } /** * BroadcastReceiver for notification that Gasp! data sync completed */ private final BroadcastReceiver mMessageReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "Restaurant sync completed"); getLocations(); } }; /** * Load Google Maps view/fragment, set location and button/click listeners */ private void prepareMapView() { setContentView(R.layout.gasp_locations_layout); mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); mMap.setMyLocationEnabled(true); setCamera(); addButtonListener(); setMarkerClickListener(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Instrumentation.start("EUM-AAB-AUB", getApplicationContext(), "http://ec2-54-214-82-33.us-west-2.compute.amazonaws.com", true); mGaspRegistrationClient.registerGCM(this); TwitterAuthentication.requestTwitterOAuthToken(this); LocationServices.enableLocationChecking(this); mLocation = LocationServices.getLocation(this); // Activity first created if (savedInstanceState == null) { // We need Play Services and Network connectivity if (PlayServices.checkPlayServices(this) && Network.checkNetworking(this)) { // Register listener for notification that restaurant data has been synced LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter(SYNC_COMPLETED)); // Start data sync services and draw map startDataSyncServices(); prepareMapView(); } else { Log.e(TAG, "Cannot launch LocationsActivity"); finish(); } } // Subsequent onCreate() events else { // Restore incremental search results, page_token and zoom level mSearchResult = (SearchResult) savedInstanceState.getSerializable(SEARCH_RESULT); mPageToken = savedInstanceState.getString(PAGE_TOKEN); mZoom = savedInstanceState.getFloat(ZOOM_LEVEL); // Display locations and enable/disable "More Locations" button prepareMapView(); showLocations(mSearchResult); if (!mPageToken.isEmpty()) { setPlacesButton(true); } } } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.options_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { /* // (Re-)register with Gasp GCM Server case R.id.options_register: mGaspRegistrationClient.doRegisterGasp(this); return true; // Unregister with Gasp GCM Server case R.id.options_unregister: mGaspRegistrationClient.doUnregisterGasp(this); return true; case R.id.options_exit: finish(); return true; */ case R.id.gasp_settings: Intent intent = new Intent(); intent.setClass(LocationsActivity.this, SetPreferencesActivity.class); startActivityForResult(intent, 0); return true; case R.id.gasp_menu_twitter: intent = new Intent(); intent.setClass(LocationsActivity.this, TwitterStreamActivity.class); startActivityForResult(intent, 0); return true; case R.id.gasp_data: intent = new Intent(); intent.setClass(LocationsActivity.this, GaspDataActivity.class); startActivityForResult(intent, 0); return true; /* case R.id.gasp_reviews_data: intent = new Intent(); intent.setClass(LocationsActivity.this, ReviewListActivity.class); startActivityForResult(intent, 0); return true; case R.id.gasp_restaurants_data: intent = new Intent(); intent.setClass(LocationsActivity.this, RestaurantListActivity.class); startActivityForResult(intent, 0); return true; case R.id.gasp_users_data: intent = new Intent(); intent.setClass(LocationsActivity.this, UserListActivity.class); startActivityForResult(intent, 0); return true; */ case R.id.gasp_login_with_amazon: intent = new Intent(); intent.setClass(LocationsActivity.this, AmazonSignInActivity.class); startActivityForResult(intent, 0); return true; case R.id.gasp_login_with_google: intent = new Intent(); intent.setClass(LocationsActivity.this, GoogleSignInActivity.class); startActivityForResult(intent, 0); return true; default: return super.onOptionsItemSelected(item); } } @Override protected void onDestroy() { mGaspRegistrationClient.doUnregisterGasp(this); LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver); super.onDestroy(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // Save incremental search results, page_token and zoom level outState.putSerializable(SEARCH_RESULT, mSearchResult); outState.putString(PAGE_TOKEN, mPageToken); outState.putFloat(ZOOM_LEVEL, mMap.getCameraPosition().zoom); } }