1 /* 2 * Copyright (C) 2014 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.wearable.speedtracker; 18 19 import com.google.android.gms.maps.CameraUpdateFactory; 20 import com.google.android.gms.maps.GoogleMap; 21 import com.google.android.gms.maps.MapFragment; 22 import com.google.android.gms.maps.model.LatLng; 23 import com.google.android.gms.maps.model.LatLngBounds; 24 import com.google.android.gms.maps.model.PolylineOptions; 25 26 import android.app.Activity; 27 import android.app.DatePickerDialog; 28 import android.os.AsyncTask; 29 import android.os.Bundle; 30 import android.text.format.DateUtils; 31 import android.util.Log; 32 import android.view.View; 33 import android.widget.DatePicker; 34 import android.widget.TextView; 35 36 import com.example.android.wearable.speedtracker.common.LocationEntry; 37 38 import java.util.ArrayList; 39 import java.util.Calendar; 40 import java.util.List; 41 42 /** 43 * The main activity for the handset application. When a watch device reconnects to the handset 44 * app, the collected GPS data on the watch, if any, is synced up and user can see his/her track on 45 * a map. This data is then saved into an internal database and the corresponding data items are 46 * deleted. 47 */ 48 public class PhoneMainActivity extends Activity implements DatePickerDialog.OnDateSetListener { 49 50 private static final String TAG = "PhoneMainActivity"; 51 private static final int BOUNDING_BOX_PADDING_PX = 50; 52 private TextView mSelectedDateText; 53 private GoogleMap mMap; 54 55 @Override 56 protected void onCreate(Bundle savedInstanceState) { 57 super.onCreate(savedInstanceState); 58 setContentView(R.layout.main_activity); 59 mSelectedDateText = (TextView) findViewById(R.id.selected_date); 60 mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap(); 61 } 62 63 public void onClick(View view) { 64 Calendar calendar = Calendar.getInstance(); 65 calendar.setTimeInMillis(System.currentTimeMillis()); 66 new DatePickerDialog(PhoneMainActivity.this, PhoneMainActivity.this, 67 calendar.get(Calendar.YEAR), 68 calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)).show(); 69 } 70 71 @Override 72 public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { 73 // the following if-clause is to get around a bug that causes this callback to be called 74 // twice 75 if (view.isShown()) { 76 Calendar calendar = Calendar.getInstance(); 77 calendar.setTimeInMillis(System.currentTimeMillis()); 78 calendar.set(Calendar.YEAR, year); 79 calendar.set(Calendar.MONTH, monthOfYear); 80 calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth); 81 String date = DateUtils.formatDateTime(this, calendar.getTimeInMillis(), 82 DateUtils.FORMAT_SHOW_DATE); 83 mSelectedDateText.setText(getString(R.string.showing_for_date, date)); 84 showTrack(calendar); 85 } 86 } 87 88 /** 89 * An {@link android.os.AsyncTask} that is responsible for getting a list of {@link 90 * com.example.android.wearable.speedtracker.common.LocationEntry} objects for a given day and 91 * building a track from those points. In addition, it sets the smallest bounding box for the 92 * map that covers all the points on the track. 93 */ 94 private void showTrack(Calendar calendar) { 95 new AsyncTask<Calendar, Void, Void>() { 96 97 private List<LatLng> coordinates; 98 private LatLngBounds bounds; 99 100 @Override 101 protected Void doInBackground(Calendar... params) { 102 LocationDataManager dataManager = ((PhoneApplication) getApplicationContext()) 103 .getDataManager(); 104 List<LocationEntry> entries = dataManager.getPoints(params[0]); 105 if (entries != null && !entries.isEmpty()) { 106 coordinates = new ArrayList<LatLng>(); 107 LatLngBounds.Builder builder = new LatLngBounds.Builder(); 108 for (LocationEntry entry : entries) { 109 LatLng latLng = new LatLng(entry.latitude, entry.longitude); 110 builder.include(latLng); 111 coordinates.add(latLng); 112 } 113 bounds = builder.build(); 114 } 115 return null; 116 } 117 118 @Override 119 protected void onPostExecute(Void aVoid) { 120 mMap.clear(); 121 if (coordinates == null || coordinates.isEmpty()) { 122 if (Log.isLoggable(TAG, Log.DEBUG)) { 123 Log.d(TAG, "No Entries found for that date"); 124 } 125 } else { 126 mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 127 BOUNDING_BOX_PADDING_PX)); 128 mMap.addPolyline(new PolylineOptions().geodesic(true).addAll(coordinates)); 129 } 130 } 131 132 }.execute(calendar); 133 } 134 } 135