Android语音识别并通过蓝牙将数据发送到Arduino。如何多次发送数据?

时间:2015-04-23 12:02:19

标签: java android bluetooth

我是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

1 个答案:

答案 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就应该是金色的。