What I'm trying to do:
User says "find my keys" Google glass takes a picture and stores a string of what you said in a socket to be sent on a port. A second socket is created to send the picture, so the receiver has the voice string and picture in order for further processing.
The problem:
After the picture is taken, I have some Toast.makeText messages along with the socket creation, which is being ignored for some reason.
All of the socket creation is happening under onActivityResult
The voice detection happens on onCreate
Code is as follows:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.FileObserver;
import android.provider.MediaStore;
import android.speech.RecognizerIntent;
import android.util.Log;
import android.widget.Toast;
import com.google.android.glass.content.Intents;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
public class CameraActivity extends Activity {
private CameraSurfaceView cameraView;
private static final int TAKE_PICTURE_REQUEST = 1;
//Take the picture only if the string take_picture from voice control allows for it.
private void takePicture() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, TAKE_PICTURE_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode != RESULT_CANCELED)
{
if (requestCode == TAKE_PICTURE_REQUEST && resultCode == RESULT_OK) {
String thumbnailPath = data.getStringExtra(Intents.EXTRA_THUMBNAIL_FILE_PATH);
String picturePath = data.getStringExtra(Intents.EXTRA_PICTURE_FILE_PATH);
processPictureWhenReady(picturePath);
Toast.makeText(getApplicationContext(), "Proceeding to Socket creation.", Toast.LENGTH_LONG).show();
//Create the java socket and send the file to the android device
//Need to send out the voice command to the Android phone and the picture
//for now, send the voice data
try {
Toast.makeText(getApplicationContext(), "Socket created on port 40404", Toast.LENGTH_LONG).show();
try {
//Define the socket:
//Firewall problem.
Socket skt = new Socket(InetAddress.getLocalHost(), 40404);
//Send the voice data
OutputStream outstream = skt.getOutputStream();
PrintWriter out = new PrintWriter(outstream);
Toast.makeText(getApplicationContext(), "Sending data to Android Device", Toast.LENGTH_LONG).show();
out.print(voiceglobal);
//The commented out code below will eventually send the picture that you take with the device over a socket
//to a recieving device.You can ignore this for now.
//long length = pictureToSend.length();
//Create a new socket for sending the picture.
/*
Socket pic_socket = new Socket(InetAddress.getLocalHost(), 50505);
byte bytes[];
ObjectInputStream ois = new ObjectInputStream(pic_socket.getInputStream());
FileOutputStream fos = null;
try {
bytes = (byte[])ois.readObject();
fos = new FileOutputStream(pictureToSend);
fos.write(bytes);
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} finally {
if(fos!= null)
{
fos.close();
}
}
*/
//////////////////////////////////////////////
//////////////////
} catch (UnknownHostException e) {
//Handle this.
System.err.print(e);
}
} catch (IOException v) {
// handle this.
System.err.print(v);
}
}
//Define the socket:
//Make sure this works and then write the code for
/////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
} //if resultCode != RESULT_CANCELED
super.onActivityResult(requestCode, resultCode, data);
}
//Define global path to picture file.
//Test the path by using the recieving connection.
File pictureToSend;
private void processPictureWhenReady(final String picturePath) {
final File pictureFile = new File(picturePath);
////////////////////////////////////////////////////////
//////
pictureToSend = pictureFile; //Global for sending the picture.
////////////////////////////////////////////////////////
/////
if (pictureFile.exists()) {
// The picture is ready; process it.
} else {
// The file does not exist yet. Before starting the file observer, you
// can update your UI to let the user know that the application is
// waiting for the picture (for example, by displaying the thumbnail
// image and a progress indicator).
final File parentDirectory = pictureFile.getParentFile();
FileObserver observer = new FileObserver(parentDirectory.getPath(),
FileObserver.CLOSE_WRITE | FileObserver.MOVED_TO) {
// Protect against additional pending events after CLOSE_WRITE
// or MOVED_TO is handled.
private boolean isFileWritten;
@Override
public void onEvent(int event, String path) {
if (!isFileWritten) {
// For safety, make sure that the file that was created in
// the directory is actually the one that we're expecting.
File affectedFile = new File(parentDirectory, path);
isFileWritten = affectedFile.equals(pictureFile);
if (isFileWritten) {
stopWatching();
// Now that the file is ready, recursively call
// processPictureWhenReady again (on the UI thread).
runOnUiThread(new Runnable() {
@Override
public void run() {
processPictureWhenReady(picturePath);
}
});
}
}
}
};
observer.startWatching();
}
}
public byte[] imgbyte;
public String voiceglobal;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Initiate CameraView
cameraView = new CameraSurfaceView(this); //Calls CameraSurfaceView
// Set the view
this.setContentView(cameraView);
//VOICE DETECTION HAPPENS HERE.
ArrayList<String> voiceRes = getIntent().getExtras().getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
String Voicedata = voiceRes.toString();
Log.d("Voicedata was ", Voicedata);
voiceglobal = Voicedata;
// "Dynamic" voice detection ...
if((Voicedata.equals("[take a picture]")) || (Voicedata.equals("[find my cup]")) || (Voicedata.equals("[find my keys]")))
{
//Then take the picture.
takePicture();
} // if voicedata equals
else if(!Voicedata.equals("take a picture"))
{
//Make a toast that says it's wrong.
Toast.makeText(getApplicationContext(), "Try again", Toast.LENGTH_LONG).show();
}
}
@Override
protected void onResume() {
super.onResume();
// Do not hold the camera during onResume
if (cameraView != null) {
cameraView.releaseCamera();
}
}
@Override
protected void onPause() {
super.onPause();
// Do not hold the camera during onPause
if (cameraView != null) {
cameraView.releaseCamera();
}
}
}
Thanks very much in advance. I will post the whole project once it is working for users to play with.
Check, if you have Internet permission in your manifest
<uses-permission android:name="android.permission.INTERNET" />
Move all networking code off the main UI thread. Otherwise, you'll be getting android.os.NetworkOnMainThreadException
in the logs. More info here.