我是Android的新手。我的应用程序使用语音识别, TextToSpeech ,并通过蓝牙从Android手机(SAMSUNG Galaxy Note |操作系统:Android 4.1.2)发送数据到Arduino的。它可以一次只发送一次数据,然后发送数据(通过package com.itcdroid.smarthome;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Locale;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements
TextToSpeech.OnInitListener {
//Tag for logging
private static final String TAG = "ITCDroid";
private static final int REQUEST_ENABLE_BT = 1;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket mBluetoothSocket = null;
private OutputStream outStream = null;
//MAC address of remote Bluetooth device
private final String address = "98:D3:31:B4:34:EE";
// UUID that specifies a protocol for generic bluetooth serial communication
//Well known SPP UUID
private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private TextToSpeech tts;
private String ttsText;
private TextView txtSpeechInput;
private ImageButton btnSpeak;
private final int REQ_CODE_SPEECH_INPUT = 100;
// Available commands
private static final String[] commands = {"on", "off", "turn on the light", "turn off the light"};
boolean foundCommand;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
checkBtState();
tts = new TextToSpeech(this, this);
txtSpeechInput = (TextView) findViewById(R.id.txtSpeechInput);
btnSpeak = (ImageButton) findViewById(R.id.btnSpeak);
// hide the action bar
//getActionBar().hide();
//mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//checkBtState();
btnSpeak.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
promptSpeechInput();
}
});
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "...In onResume - Attempting client connect...");
//Set up a pointer to the remote node using it's address.
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// Two things are needed to make a connection:
// A MAC address, which we got above.
// A Service ID or UUID. in this case we are using the UUID for SPP
try {
mBluetoothSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
}
// Discovery is resource intensive. Make sure it isn't going on
// when you attempt to connect and pass your message.
mBluetoothAdapter.cancelDiscovery();
// Establish the connection. This will block until is connects.
Log.d(TAG, "...Connecting to Remote...");
try {
mBluetoothSocket.connect();
Log.d(TAG, "...Connection established and data link opened...");
} catch(IOException e) {
try {
mBluetoothSocket.close();
} catch (IOException e2) {
errorExit("Fatal Error", "In onResume() and unable to close socket during connection failture" + e2.getMessage() + ".");
}
}
//Create a data stream so we can talk to server.
Log.d(TAG, "...Creating Socket...");
try {
outStream = mBluetoothSocket.getOutputStream();
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and output stream creation failture: " + e.getMessage() + ".");
}
}
@Override
public void onPause(){
super.onPause();
Log.d(TAG, "...In onPause()...");
if (outStream != null) {
try {
outStream.flush();
} catch (IOException e) {
errorExit("Fatal Error", "In onPause() and failed to flush output stream: " + e.getMessage() + ".");
}
}
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mBluetoothSocket.close();
} catch (IOException e) { }
}
private void checkBtState() {
// TODO Auto-generated method stub
//Check for Bluetooth support and then check to make sure it is turned on
if (mBluetoothAdapter == null) {
errorExit("Fatal Error", "Bluetooth Not supported. Aborting.");
} else {
if (mBluetoothAdapter.isEnabled()) {
Log.d(TAG, "...Bluetooth is enabled...");
} else {
//Prompt user to turn on Bluetooth
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
}
/**
* Showing google speech input dialog
* */
private void promptSpeechInput() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
getString(R.string.speech_prompt));
try {
startActivityForResult(intent, REQ_CODE_SPEECH_INPUT);
} catch (ActivityNotFoundException a) {
Toast.makeText(getApplicationContext(),
getString(R.string.speech_not_supported),
Toast.LENGTH_SHORT).show();
}
}
/**
* Receiving speech input
* */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQ_CODE_SPEECH_INPUT: {
if (resultCode == RESULT_OK && null != data) {
ArrayList<String> result = data
.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
foundCommand = false;
for(String command : commands) {
if(result.contains(command)) {
foundCommand = true;
if(command == "on") {
txtSpeechInput.setText("You say -on-");
ttsText = "The light is turn on now.";
speakOut();
sentData("1");
}
else if(command == "off") {
txtSpeechInput.setText("You say -off-");
ttsText = "The light is turn off now.";
speakOut();
sentData("2");
}
else if(command == "turn on the light") {
txtSpeechInput.setText("You say -turn on the light-");
ttsText = "The light is turn on now.";
speakOut();
sentData("1");
}
else if(command == "turn off the light") {
txtSpeechInput.setText("You say -turn off the light-");
ttsText = "The light is turn off now.";
speakOut();
sentData("2");
}
}
}
if (!foundCommand) {
txtSpeechInput.setText("Unknown what you say");
ttsText = "I don't know what you want!";
speakOut();
}
//txtSpeechInput.setText(result.get(0));
}
break;
}
}
}
@Override
public void onDestroy() {
// Don't forget to shutdown!
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
@Override
public void onInit(int status) {
// TODO Auto-generated method stub
if (status == TextToSpeech.SUCCESS) {
int result = tts.setLanguage(Locale.US);
// tts.setPitch(5); // set pitch level
// tts.setSpeechRate(2); // set speech speed rate
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "Language is not supported");
} else {
//btnSpeak.setEnabled(true);
speakOut();
}
} else {
Log.e("TTS", "Initilization Failed");
}
}
//@SuppressWarnings("deprecation")
private void speakOut() {
String text = ttsText;
tts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
}
private void sentData(String message) {
// TODO Auto-generated method stub
byte[] msgBuffer = message.getBytes();
Log.d(TAG, "...Sending data: " + message + "...");
try {
outStream.write(msgBuffer);
outStream.close();
reConnectBT();
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write:" + e.getMessage();
msg = msg + ".\n\nCheck that the SPP UUID: " + MY_UUID.toString() + "exists on server.\n\n";
errorExit("sentData IOException", msg);
}
}
private void reConnectBT() {
// TODO Auto-generated method stub
Log.d(TAG, "...In reConnectBT - Attempting client connect...");
//Set up a pointer to the remote node using it's address.
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// Two things are needed to make a connection:
// A MAC address, which we got above.
// A Service ID or UUID. in this case we are using the UUID for SPP
try {
mBluetoothSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
}
// Discovery is resource intensive. Make sure it isn't going on
// when you attempt to connect and pass your message.
mBluetoothAdapter.cancelDiscovery();
// Establish the connection. This will block until is connects.
Log.d(TAG, "...Connecting to Remote...");
try {
mBluetoothSocket.connect();
Log.d(TAG, "...Connection established and data link opened...");
} catch(IOException e) {
try {
mBluetoothSocket.close();
} catch (IOException e2) {
errorExit("Fatal Error", "In onResume() and unable to close socket during connection failture" + e2.getMessage() + ".");
}
}
//Create a data stream so we can talk to server.
Log.d(TAG, "...Creating Socket...");
try {
outStream = mBluetoothSocket.getOutputStream();
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and output stream creation failture: " + e.getMessage() + ".");
}
}
private void errorExit(String title, String message) {
// TODO Auto-generated method stub
Toast msg= Toast.makeText(getBaseContext(),
title, Toast.LENGTH_SHORT);
msg.show();
finish();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
),因此应用程序requests
。以下是我的代码。
Android代码
json
答案 0 :(得分:0)
似乎你在连接和断开蓝牙设备方面做了很多工作,这可能会损害你的性能。您正在做的另一件事是直接在UI线程中管理所有繁重的蓝牙进程,这将使您的应用程序锁定,直到连接完成。
Here's指向我项目存储库的链接,我在其中进行简单的蓝牙连接,并将BluetoothConnection
类作为管理连接状态的包装器。随意使用源代码,但要小心,我总是积极地改变它。如果你选择使用你的代码,实现将是这样的:
InputStream mInputStream;
OutputStream mOutputStream;
BluetoothConnection mConnection = new BluetoothConnection("Connection Name", "98:D3:31:B4:34:EE");
mConnection.setOnConnectStatusChangedListener(this, new onConnectStatusChangedListener() {
@Override
public void onConnect() {
/*
* Connecting to bluetooth takes some time, it won't be ready immediately.
* Set some actions here that let your program know that the connection
* finished successfully. For example,
*/
mInputStream = mConnection.getInputStream();
mOutputStream = mConnection.getOutputStream();
//Use some method of your own to write data
sendDataToBluetoothDevice(mOutputStream);
}
@Override
public void onDisconnect() {
/*
* Same thing applies to disconnecting, set some actions to occur
* when the disconnect is confirmed.
*/
}
}
/*
* Internally, this launches an AsyncTask to handle connecting,
* which is why we need the onConnectStatusChangedListener
* callbacks.
*/
mConnection.connect();
//To disconnect:
mConnection.disconnect();
这可以通过处理后台进程中的所有繁重工作来简化您的工作。至于读写不止一次,只要你正确使用InputStream和OutputStream就应该是金色的。