Android Studio Google Glass:如何使用语音命令拍照
Android Studio Google Glass: How to take a picture with voice command
理想情况下,我尝试使用 voice_trigger.xml 中用户的语音输入并将其存储在 strings.xml 中,以便我可以比较相机 activity 中的字符串变量,例如如果匹配,请拍照并保存。
我不太确定如何实现它。听起来我有解决这个问题的正确想法吗?
以下:voice_trigger.xml、strings.xml、CameraActivity.java
voice_trigger.xml:
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information about voice trigger, check out: https://developers.google.com/glass/develop/gdk/starting-glassware -->
<trigger keyword="Visual tracker">
<!-- <input prompt="@string/glass_tracking_prompt" /> -->
<input interaction ="@string/take_picture"/>
<constraints network="true"
camera="true" />
</trigger>
strings.xml:
<resources>
<string name="app_name">GlassTracker</string>
<string name="title_activity_live_card_service">Tracking Prime LiveCard</string>
<string name="title_activity_live_card_renderer">Tracking Prime Activity</string>
<string name="action_stop">Close App</string>
<string name="action_tune_track">Tune Tracker</string>
<string name="action_start_track">Start Tracking</string>
<string name="action_stop_track">Stop Tracking</string>
<string name="hello_world">Hello visual tracker!</string>
<string name="glass_tracking_trigger">Visual tracker</string>
<string name="glass_tracking_prompt">Tap to tune</string>
<string name="take_picture">Take a picture</string>
</resources>
CameraActivity.java:
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 com.google.android.glass.content.Intents;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* Created by
*/
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
/*Take out ints */
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
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);
// TODO: Show the thumbnail to the user while the full picture is being
// processed.
}
super.onActivityResult(requestCode, resultCode, data);
}
private void processPictureWhenReady(final String picturePath) {
final File pictureFile = new File(picturePath);
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();
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initiate CameraView
cameraView = new CameraSurfaceView(this); //Calls CameraSurfaceView
// Set the view
this.setContentView(cameraView);
}
@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();
}
}
}
非常感谢!
在voice_triggers.xml文件中,将收听语音命令。当您对设备说出命令时,voiceRes 将填充您所说的内容,因为它是一个字符串类型的数组,理想情况下需要将其转换为字符串。然后根据用户说的做对比就简单了。另外,确保在比较前后包含方括号,否则 if 语句将不起作用。这是我很快发现的解决方案,我相信有很多方法可以做到。
在 onCreate()
方法中,在 this.setContentView(cameraView);
之后
ArrayList<String> voiceRes =getIntent().getExtras().getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
String Voicedata = voiceRes.toString();
if(Voicedata.equals("[take a picture]")
{
takepicture();
}
理想情况下,我尝试使用 voice_trigger.xml 中用户的语音输入并将其存储在 strings.xml 中,以便我可以比较相机 activity 中的字符串变量,例如如果匹配,请拍照并保存。
我不太确定如何实现它。听起来我有解决这个问题的正确想法吗?
以下:voice_trigger.xml、strings.xml、CameraActivity.java
voice_trigger.xml:
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information about voice trigger, check out: https://developers.google.com/glass/develop/gdk/starting-glassware -->
<trigger keyword="Visual tracker">
<!-- <input prompt="@string/glass_tracking_prompt" /> -->
<input interaction ="@string/take_picture"/>
<constraints network="true"
camera="true" />
</trigger>
strings.xml:
<resources>
<string name="app_name">GlassTracker</string>
<string name="title_activity_live_card_service">Tracking Prime LiveCard</string>
<string name="title_activity_live_card_renderer">Tracking Prime Activity</string>
<string name="action_stop">Close App</string>
<string name="action_tune_track">Tune Tracker</string>
<string name="action_start_track">Start Tracking</string>
<string name="action_stop_track">Stop Tracking</string>
<string name="hello_world">Hello visual tracker!</string>
<string name="glass_tracking_trigger">Visual tracker</string>
<string name="glass_tracking_prompt">Tap to tune</string>
<string name="take_picture">Take a picture</string>
</resources>
CameraActivity.java:
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 com.google.android.glass.content.Intents;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* Created by
*/
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
/*Take out ints */
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
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);
// TODO: Show the thumbnail to the user while the full picture is being
// processed.
}
super.onActivityResult(requestCode, resultCode, data);
}
private void processPictureWhenReady(final String picturePath) {
final File pictureFile = new File(picturePath);
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();
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initiate CameraView
cameraView = new CameraSurfaceView(this); //Calls CameraSurfaceView
// Set the view
this.setContentView(cameraView);
}
@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();
}
}
}
非常感谢!
在voice_triggers.xml文件中,将收听语音命令。当您对设备说出命令时,voiceRes 将填充您所说的内容,因为它是一个字符串类型的数组,理想情况下需要将其转换为字符串。然后根据用户说的做对比就简单了。另外,确保在比较前后包含方括号,否则 if 语句将不起作用。这是我很快发现的解决方案,我相信有很多方法可以做到。
在 onCreate()
方法中,在 this.setContentView(cameraView);
ArrayList<String> voiceRes =getIntent().getExtras().getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
String Voicedata = voiceRes.toString();
if(Voicedata.equals("[take a picture]")
{
takepicture();
}