package com.mendhak.gpslogger;
import android.os.Bundle;
import android.os.Handler;
import android.support.wearable.activity.WearableActivity;
import android.support.wearable.view.BoxInsetLayout;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainWearActivity extends WearableActivity implements
DataApi.DataListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, View.OnClickListener {
private GoogleApiClient googleClient;
private ImageView img;
private boolean sessionStarted;
private BoxInsetLayout mContainerView;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_wear);
// setAmbientEnabled();
// Build a new GoogleApiClient for the Wearable API
googleClient = new GoogleApiClient.Builder(this)
.addApiIfAvailable(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mContainerView = (BoxInsetLayout) findViewById(R.id.container);
img = (ImageView)findViewById(R.id.btnStartStop);
img.setOnClickListener(this);
}
// Connect to the data layer when the Activity starts
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
Log.v("GPSLOGGER", "Connecting to listener client");
googleClient.connect();
}
@Override
protected void onPause() {
super.onPause();
Wearable.DataApi.removeListener(googleClient, this);
googleClient.disconnect();
}
// Disconnect from the data layer when the Activity stops
@Override
protected void onStop() {
if (null != googleClient && googleClient.isConnected()) {
googleClient.disconnect();
}
super.onStop();
}
// @Override
// public void onEnterAmbient(Bundle ambientDetails) {
// super.onEnterAmbient(ambientDetails);
// updateDisplay();
// }
//
// @Override
// public void onUpdateAmbient() {
// super.onUpdateAmbient();
// updateDisplay();
// }
//
// @Override
// public void onExitAmbient() {
// updateDisplay();
// super.onExitAmbient();
// }
//
// private void updateDisplay() {
// if (isAmbient()) {
// mContainerView.setBackgroundColor(getResources().getColor(android.R.color.black));
// mTextView.setTextColor(getResources().getColor(android.R.color.white));
// mClockView.setVisibility(View.VISIBLE);
//
// mClockView.setText(AMBIENT_DATE_FORMAT.format(new Date()));
// } else {
// mContainerView.setBackground(null);
// mTextView.setTextColor(getResources().getColor(android.R.color.black));
// mClockView.setVisibility(View.GONE);
// }
// }
// Send a message when the data layer connection is successful.
@Override
public void onConnected(Bundle connectionHint) {
Log.v("GPSLOGGER", "OnConnected");
Wearable.DataApi.addListener(googleClient, this);
//Requires a new thread to avoid blocking the UI
new SendToDataLayerThread("/get_status", "").start();
}
// Placeholders for required connection callbacks
@Override
public void onConnectionSuspended(int cause) { }
@Override
public void onConnectionFailed(ConnectionResult connectionResult) { }
@Override
public void onDataChanged(DataEventBuffer dataEventBuffer) {
for (DataEvent event : dataEventBuffer) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
// DataItem changed
DataItem item = event.getDataItem();
if (item.getUri().getPath().compareTo("/latest_gps") == 0) {
final DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
handler.post(new UpdateUI(dataMap));
}
}
}
}
@Override
public void onClick(View view) {
if(view.getId()==R.id.btnStartStop){
new SendToDataLayerThread("/start_stop", "").start();
if(!sessionStarted){
sessionStarted = true;
//clear the text while waiting for new location update
imageViewAnimatedChange("STARTED");
new UpdateUI(null).run();
}
else {
sessionStarted = false;
//Stop but keep text on screen
imageViewAnimatedChange("STOPPED");
}
}
}
private void imageViewAnimatedChange( String buttonState ) {
final ImageView v = (ImageView)findViewById(R.id.btnStartStop);
final int new_image = (buttonState.equals("STOPPED")) ? android.R.drawable.ic_media_play: android.R.drawable.ic_menu_close_clear_cancel;
final Animation anim_out = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
final Animation anim_in = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
anim_out.setAnimationListener(new Animation.AnimationListener()
{
@Override public void onAnimationStart(Animation animation) {}
@Override public void onAnimationRepeat(Animation animation) {}
@Override public void onAnimationEnd(Animation animation)
{
v.setImageResource(new_image);
anim_in.setAnimationListener(new Animation.AnimationListener() {
@Override public void onAnimationStart(Animation animation) {}
@Override public void onAnimationRepeat(Animation animation) {}
@Override public void onAnimationEnd(Animation animation) {}
});
v.startAnimation(anim_in);
}
});
v.startAnimation(anim_out);
}
private void textViewAnimatedChange(final TextView v, final String new_text) {
final Animation anim_out = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
anim_out.setDuration(500);
final Animation anim_in = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
anim_in.setDuration(20);
anim_out.setAnimationListener(new Animation.AnimationListener()
{
@Override public void onAnimationStart(Animation animation) {}
@Override public void onAnimationRepeat(Animation animation) {}
@Override public void onAnimationEnd(Animation animation)
{
v.setText(new_text);
anim_in.setAnimationListener(new Animation.AnimationListener() {
@Override public void onAnimationStart(Animation animation) {}
@Override public void onAnimationRepeat(Animation animation) {}
@Override public void onAnimationEnd(Animation animation) {}
});
v.startAnimation(anim_in);
}
});
v.startAnimation(anim_out);
}
private class UpdateUI implements Runnable {
private DataMap dataMap;
public UpdateUI(DataMap dataMap){
this.dataMap = dataMap;
}
@Override
public void run() {
TextView txtLatitude = (TextView) findViewById(R.id.txtLatitude);
TextView txtLongitude = (TextView)findViewById(R.id.txtLongitude);
TextView txtFixTime = (TextView)findViewById(R.id.txtFixTime);
if(dataMap == null){
txtLatitude.setText("");
txtLongitude.setText("");
txtFixTime.setText("");
return;
}
if(dataMap.containsKey("latitude")){
textViewAnimatedChange(txtLatitude, dataMap.getString("latitude"));
}
if(dataMap.containsKey("longitude")){
textViewAnimatedChange(txtLongitude, dataMap.getString("longitude"));
}
if(dataMap.containsKey("fixtime")){
String dateString = new SimpleDateFormat("HH:mm:ss").format(new Date(dataMap.getLong("fixtime")));
textViewAnimatedChange(txtFixTime, "(@" + dateString + ")");
}
sessionStarted = dataMap.getBoolean("session", false);
img.setImageResource(android.R.drawable.ic_media_play);
if(sessionStarted){
img.setImageResource(android.R.drawable.ic_menu_close_clear_cancel);
}
}
}
private class SendToDataLayerThread extends Thread {
String path;
String message;
// Constructor to send a message to the data layer
SendToDataLayerThread(String path, String msg) {
this.path = path;
this.message = msg;
}
public void run() {
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleClient).await();
for (Node node : nodes.getNodes()) {
MessageApi.SendMessageResult result = Wearable.MessageApi.sendMessage(googleClient, node.getId(), path, message.getBytes()).await();
if (result.getStatus().isSuccess()) {
Log.v("GPSLOGGER", "Request: {" + path+ "} sent to: " + node.getDisplayName());
}
else {
// Log an error
Log.v("myTag", "ERROR: failed to send Message");
}
}
}
}
}