package net.steppschuh.sensordatalogger; import com.google.android.gms.wearable.Node; import com.google.android.gms.wearable.Wearable; import com.google.firebase.analytics.FirebaseAnalytics; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.Color; import android.hardware.Sensor; import android.os.Build; import android.os.Bundle; import android.os.Message; import android.support.v4.content.ContextCompat; import android.support.wearable.activity.WearableActivity; import android.support.wearable.view.BoxInsetLayout; import android.util.Log; import android.view.View; import android.widget.TextView; import net.steppschuh.datalogger.data.request.DataRequest; import net.steppschuh.datalogger.data.request.SensorDataRequest; import net.steppschuh.datalogger.messaging.handler.MessageHandler; import net.steppschuh.datalogger.messaging.handler.SinglePathMessageHandler; import net.steppschuh.datalogger.sensor.DeviceSensors; import net.steppschuh.datalogger.status.ActivityStatus; import net.steppschuh.datalogger.status.Status; import net.steppschuh.datalogger.status.StatusUpdateEmitter; import net.steppschuh.datalogger.status.StatusUpdateHandler; import net.steppschuh.datalogger.status.StatusUpdateReceiver; import java.util.ArrayList; import java.util.List; public class WearActivity extends WearableActivity implements StatusUpdateEmitter { private static final String TAG = WearActivity.class.getSimpleName(); private WearApp app; private List<MessageHandler> messageHandlers; private ActivityStatus status = new ActivityStatus(); private StatusUpdateHandler statusUpdateHandler; private BoxInsetLayout mContainerView; private TextView mainTextView; private TextView preTextView; private TextView postTextView; private TextView logTextView; private String lastConnectedDeviceName; private int lastRequestedSensorCount = -1; private int lastAvailableSensorCount = -1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // get reference to global application app = (WearApp) getApplicationContext(); // initialize with context activity if needed if (!app.getStatus().isInitialized() || app.getContextActivity() == null) { app.initialize(this); } setupUi(); setupMessageHandlers(); setupStatusUpdates(); setupAnalytics(); status.setInitialized(true); status.updated(statusUpdateHandler); } private void setupUi() { setContentView(R.layout.main_activity_wear); setAmbientEnabled(); mContainerView = (BoxInsetLayout) findViewById(R.id.container); mainTextView = (TextView) findViewById(R.id.mainText); preTextView = (TextView) findViewById(R.id.preText); postTextView = (TextView) findViewById(R.id.postText); logTextView = (TextView) findViewById(R.id.logText); mContainerView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { updateStatusTexts(); } }); updateDisplay(); } private void setupMessageHandlers() { messageHandlers = new ArrayList<>(); messageHandlers.add(getSensorDataRequestHandler()); } private void setupStatusUpdates() { statusUpdateHandler = new StatusUpdateHandler(); statusUpdateHandler.registerStatusUpdateReceiver(new StatusUpdateReceiver() { @Override public void onStatusUpdated(Status status) { app.getStatus().setActivityStatus((ActivityStatus) status); app.getStatus().updated(app.getStatusUpdateHandler()); } }); } private void setupAnalytics() { Bundle bundle = new Bundle(); try { PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0); bundle.putString("version_code", String.valueOf(packageInfo.versionCode)); bundle.putString("version_name", String.valueOf(packageInfo.versionName)); } catch (PackageManager.NameNotFoundException e) { Log.w(TAG, "Unable to get package info"); } app.getAnalytics().logEvent(FirebaseAnalytics.Event.APP_OPEN, bundle); } @Override protected void onStart() { super.onStart(); // register message handlers for (MessageHandler messageHandler : messageHandlers) { app.registerMessageHandler(messageHandler); } Wearable.MessageApi.addListener(app.getGoogleApiMessenger().getGoogleApiClient(), app); // update status status.setInForeground(true); status.updated(statusUpdateHandler); // update reachabilities of nearby nodes app.getReachabilityChecker().checkReachabilities(null); } @Override protected void onStop() { // let other devices know that the app won't be reachable anymore app.getGoogleApiMessenger().sendMessageToNearbyNodes(MessageHandler.PATH_CLOSING, Build.MODEL); // unregister message handlers for (MessageHandler messageHandler : messageHandlers) { app.unregisterMessageHandler(messageHandler); } Wearable.MessageApi.removeListener(app.getGoogleApiMessenger().getGoogleApiClient(), app); // update status status.setInForeground(false); status.updated(statusUpdateHandler); super.onStop(); } @Override public void onEnterAmbient(Bundle ambientDetails) { super.onEnterAmbient(ambientDetails); updateDisplay(); status.setAmbientMode(true); status.updated(statusUpdateHandler); } @Override public void onUpdateAmbient() { super.onUpdateAmbient(); updateDisplay(); } @Override public void onExitAmbient() { updateDisplay(); status.setAmbientMode(false); status.updated(statusUpdateHandler); super.onExitAmbient(); } private void updateDisplay() { if (isAmbient()) { mContainerView.setBackgroundColor(Color.BLACK); preTextView.setVisibility(View.GONE); postTextView.setVisibility(View.GONE); logTextView.setVisibility(View.GONE); } else { mContainerView.setBackgroundColor(ContextCompat.getColor(this, R.color.colorPrimary)); preTextView.setVisibility(View.VISIBLE); postTextView.setVisibility(View.VISIBLE); logTextView.setVisibility(View.VISIBLE); } updateStatusTexts(); } private void updateStatusTexts() { String connectedDeviceName = getConnectedDeviceName(); int availableSensorsCount = getAvailableSensorsCount(); int registeredSensorsCount = getRegisteredSensorsCount(); String preText; String mainText; String postText; String logText = String.valueOf(app.getStatus().getLastUpdateTimestamp()); if (isSendingRequestResponses()) { preText = getString(R.string.status_connected_pre); preText = preText.replace("[REGISTERED_SENSORS]", String.valueOf(registeredSensorsCount)); preText = preText.replace("[AVAILABLE_SENSORS]", String.valueOf(availableSensorsCount)); mainText = getString(R.string.status_connected_main); postText = getString(R.string.status_connected_post); postText = postText.replace("[DEVICENAME]", connectedDeviceName); } else { preText = getString(R.string.status_disconnected_pre); preText = preText.replace("[AVAILABLE_SENSORS]", String.valueOf(availableSensorsCount)); mainText = getString(R.string.status_disconnected_main); postText = getString(R.string.status_disconnected_post); } preTextView.setText(preText); mainTextView.setText(mainText); postTextView.setText(postText); logTextView.setText(logText); } private boolean isSendingRequestResponses() { if (!app.getGoogleApiMessenger().getGoogleApiClient().isConnected()) { return false; } if (app.getReachabilityChecker().getReachableNodeIds().size() < 1) { return false; } if (app.getSensorDataManager().getSensorEventListeners().entrySet().size() < 1) { return false; } return true; } private int getAvailableSensorsCount() { if (lastAvailableSensorCount < 0) { List<Sensor> availableSensors = app.getSensorDataManager().getSensorManager().getSensorList(Sensor.TYPE_ALL); lastAvailableSensorCount = new DeviceSensors(availableSensors, false).getSensors().size(); } return lastAvailableSensorCount; } private int getRegisteredSensorsCount() { if (lastRequestedSensorCount < 0) { lastRequestedSensorCount = app.getSensorDataManager().getSensorEventListeners().entrySet().size(); } return lastRequestedSensorCount; } private String getConnectedDeviceName() { if (lastConnectedDeviceName == null) { List<Node> lastConnectedNodes = app.getGoogleApiMessenger().getLastConnectedNearbyNodes(); if (lastConnectedNodes != null && lastConnectedNodes.size() > 0) { lastConnectedDeviceName = app.getGoogleApiMessenger().getNodeName(lastConnectedNodes.get(0).getId()); } } return lastConnectedDeviceName; } private MessageHandler getSensorDataRequestHandler() { return new SinglePathMessageHandler(MessageHandler.PATH_SENSOR_DATA_REQUEST) { @Override public void handleMessage(Message message) { // parse message String sourceNodeId = getSourceNodeIdFromMessage(message); String dataRequestJson = getDataFromMessageAsString(message); Log.v(TAG, "Received a data request from " + sourceNodeId + ": " + dataRequestJson); // update status from sensor data request SensorDataRequest sensorDataRequest = SensorDataRequest.fromJson(dataRequestJson); if (sensorDataRequest != null) { if (sensorDataRequest.getEndTimestamp() == DataRequest.TIMESTAMP_NOT_SET) { lastRequestedSensorCount = sensorDataRequest.getSensorTypes().size(); } else { lastRequestedSensorCount = 0; } lastConnectedDeviceName = app.getGoogleApiMessenger().getNodeName(sensorDataRequest.getSourceNodeId()); } updateStatusTexts(); logTextView.setText(String.valueOf(System.currentTimeMillis())); } }; } @Override public Status getStatus() { return status; } @Override public StatusUpdateHandler getStatusUpdateHandler() { return statusUpdateHandler; } }