/*
* Copyright (C) 2016 Glucosio Foundation
*
* This file is part of Glucosio.
*
* Glucosio is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* Glucosio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Glucosio. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.glucosio.android;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.support.wearable.activity.ConfirmationActivity;
import android.support.wearable.view.DelayedConfirmationView;
import android.support.wearable.view.WearableListView;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class MainActivity extends Activity implements
DelayedConfirmationView.DelayedConfirmationListener, WearableListView.ClickListener {
private static final int SPEECH_REQUEST_CODE = 0;
private static final long CONNECTION_TIME_OUT_MS = 10000;
private String spokenText;
private DelayedConfirmationView mDelayedView;
private String[] typeArray;
private FrameLayout listFrame;
private FrameLayout confirmFrame;
private TextView confirmTextView;
private String finalString;
private GoogleApiClient client;
private String nodeId;
public static boolean isNumeric(String str) {
try {
double d = Double.parseDouble(str);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
typeArray = getResources().getStringArray(R.array.dialog_add_measured_list);
initApi();
displaySpeechRecognizer();
// Get the list component from the layout of the activity
WearableListView listView =
(WearableListView) findViewById(R.id.reading_type_list);
mDelayedView =
(DelayedConfirmationView) findViewById(R.id.delayed_confirm);
mDelayedView.setListener(this);
listFrame = (FrameLayout) findViewById(R.id.list_frame);
confirmFrame = (FrameLayout) findViewById(R.id.confirm_frame);
confirmTextView = (TextView) findViewById(R.id.confirm_textview);
// Assign an adapter to the list
listView.setAdapter(new Adapter(this, typeArray));
// Set a click listener
listView.setClickListener(this);
}
/**
* Initializes the GoogleApiClient and gets the Node ID of the connected device.
*/
private void initApi() {
client = getGoogleApiClient(this);
retrieveDeviceNode();
}
/**
* Returns a GoogleApiClient that can access the Wear API.
*
* @param context
* @return A GoogleApiClient that can make calls to the Wear API
*/
private GoogleApiClient getGoogleApiClient(Context context) {
return new GoogleApiClient.Builder(context)
.addApi(Wearable.API)
.build();
}
/**
* Connects to the GoogleApiClient and retrieves the connected device's Node ID. If there are
* multiple connected devices, the first Node ID is returned.
*/
private void retrieveDeviceNode() {
new Thread(new Runnable() {
@Override
public void run() {
client.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
NodeApi.GetConnectedNodesResult result =
Wearable.NodeApi.getConnectedNodes(client).await();
List<Node> nodes = result.getNodes();
if (nodes.size() > 0) {
nodeId = nodes.get(0).getId();
}
client.disconnect();
}
}).start();
}
/**
* Sends a message to the connected mobile device, telling it to show a Toast.
*/
private void sendMessage() {
if (nodeId != null) {
new Thread(new Runnable() {
@Override
public void run() {
client.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
Wearable.MessageApi.sendMessage(client, nodeId, "/GLUCOSIO_READING_WEAR", finalString.getBytes());
Log.i(getPackageName(), "New reading sent to phone");
finish();
client.disconnect();
}
}).start();
// Show Success ConfirmationActivity
Intent intent = new Intent(this, ConfirmationActivity.class);
intent.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE,
ConfirmationActivity.SUCCESS_ANIMATION);
startActivity(intent);
} else {
Toast.makeText(MainActivity.this, getResources().getString(R.string.wear_error), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onTimerFinished(View view) {
sendMessage();
}
@Override
public void onTimerSelected(View view) {
finish();
}
// WearableListView click listener
@Override
public void onClick(WearableListView.ViewHolder v) {
Integer tag = (Integer) v.itemView.getTag();
// use this data to complete some action ...
String type = typeArray[tag];
// Show confirm dialog
listFrame.setVisibility(View.GONE);
confirmFrame.setVisibility(View.VISIBLE);
finalString = spokenText + ", " + type;
confirmTextView.setText(finalString);
// Two seconds to cancel the action
mDelayedView.setTotalTimeMs(2000);
// Start the timer
mDelayedView.start();
}
@Override
public void onTopEmptyRegionClick() {
}
// Create an intent that can start the Speech Recognizer activity
private void displaySpeechRecognizer() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
// Start the activity, the intent will be populated with the speech text
startActivityForResult(intent, SPEECH_REQUEST_CODE);
}
// This callback is invoked when the Speech Recognizer returns.
// This is where you process the intent and extract the speech text from the intent.
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == SPEECH_REQUEST_CODE && resultCode == RESULT_OK) {
List<String> results = data.getStringArrayListExtra(
RecognizerIntent.EXTRA_RESULTS);
spokenText = results.get(0);
if (!isNumeric(spokenText)) {
Toast.makeText(getApplicationContext(), getResources().getString(R.string.reading_invalid), Toast.LENGTH_SHORT).show();
finish();
}
} else {
finish();
}
super.onActivityResult(requestCode, resultCode, data);
}
}