2015-02-11 46 views
-1

我構建了android應用語音識別命令,通過嵌入式藍牙控制設備,我使用示例代碼BluetoothChat發送語音識別結果。但我有這樣的錯誤。發送消息時出現空指針異常

enter FATAL EXCEPTION: main 
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=Intent { (has extras) }} to activity {com.embox.rumahpintar/com.embox.rumahpintar.MainActivity}: java.lang.NullPointerException 
     at android.app.ActivityThread.deliverResults(ActivityThread.java:3378) 
     at android.app.ActivityThread.handleSendResult(ActivityThread.java:3421) 
     at android.app.ActivityThread.access$1100(ActivityThread.java:148) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1311) 
     at android.os.Handler.dispatchMessage(Handler.java:99) 
     at android.os.Looper.loop(Looper.java:137) 
     at android.app.ActivityThread.main(ActivityThread.java:5162) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:525) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:756) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:572) 
     at miui.dexspy.DexspyInstaller.main(DexspyInstaller.java:171) 
     at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.NullPointerException 
     at com.embox.rumahpintar.MainActivity.sendMessage(MainActivity.java:102) 
     at com.embox.rumahpintar.MainActivity.onActivityResult(MainActivity.java:89) 
     at android.app.Activity.dispatchActivityResult(Activity.java:5324) 
     at android.app.ActivityThread.deliverResults(ActivityThread.java:3374) 
at android.app.ActivityThread.access$1100(ActivityThread.java:148) 

這是MainActivity類別:

公共類MainActivity延伸ActionBarActivity {

private static final String TAG = "voice"; 
private final int REQ_CODE_SPEECH_INPUT = 100; 
private TextView speakInput; 
ArrayList<String> result; 
Button tapSpeak; 

String perintah = "hidupkan lampu kamar"; 
BluetoothService mService = null; 



@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    if (savedInstanceState == null) { 
     FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
     BluetoothFragment fragment = new BluetoothFragment(); 
     transaction.replace(R.id.sample_content_fragment, fragment); 
     transaction.commit(); 
    } 
    Toast.makeText(this, "Smart Home @Created by Akmal Fadli", Toast.LENGTH_LONG).show(); 
    speakInput = (TextView) findViewById(R.id.speakInput); 
    tapSpeak = (Button) findViewById(R.id.tapSpeak); 
    tapSpeak.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Log.i(TAG, "Speak recognition open...."); 
      promptSpeechInput(); 
     } 
    }); 
} 

public 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) { 

       result = data 
         .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); 
       speakInput.setText(result.get(0)); 
       BluetoothFragment m = new BluetoothFragment(); 
       if (result.contains(perintah)) { 
        Toast.makeText(this, "Perintah terkirim . . .", Toast.LENGTH_LONG).show(); 
        sendMessage(perintah); 
       } 
       break; 
      } 

     } 

    } 

} 

private void sendMessage(String message) { 
    // Check that we're actually connected before trying anything 
    if (mService.getState() != BluetoothService.STATE_CONNECTED) { 
     Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show(); 
     return; 
    } 

    // Check that there's actually something to send 
    if (message.length() > 0) { 
     // Get the message bytes and tell the BluetoothChatService to write 
     byte[] send = message.getBytes(); 
     mService.write(send); 
    } 
} 

這是的SendMessage方法:

public void sendMessage(String message) { 
    // Check that we're actually connected before trying anything 
    if (mService.getState() != BluetoothService.STATE_CONNECTED) { 
     Toast.makeText(getActivity(), R.string.not_connected, Toast.LENGTH_SHORT).show(); 
     return; 
    } 

    // Check that there's actually something to send 
    if (message.length() > 0) { 
     // Get the message bytes and tell the BluetoothChatService to write 
     byte[] send = message.getBytes(); 
     mService.write(send); 
    } 
} 

請給我建議。 。 。

BluetoothService類別:

public class BluetoothService { 
// Debugging 
private static final String TAG = "BluetoothChatService"; 

// Name for the SDP record when creating server socket 
private static final String NAME_INSECURE = "BluetoothChatInsecure"; 

// Unique UUID for this application 
private static final UUID MY_UUID_SECURE = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 

//UUID uuid = device.getUuids()[0].getUuid(); 
//MY_UUID_SECURE = uuid; 


// Member fields 
private final BluetoothAdapter mAdapter; 
private final Handler mHandler; 
private AcceptThread mSecureAcceptThread; 
private AcceptThread mInsecureAcceptThread; 
private ConnectThread mConnectThread; 
private ConnectedThread mConnectedThread; 
private int mState; 

// Constants that indicate the current connection state 
public static final int STATE_NONE = 0;  // we're doing nothing 
public static final int STATE_LISTEN = 1;  // now listening for incoming connections 
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection 
public static final int STATE_CONNECTED = 3; // now connected to a remote device 

/** 
* Constructor. Prepares a new BluetoothChat session. 
* 
* @param context The UI Activity Context 
* @param handler A Handler to send messages back to the UI Activity 
*/ 
public BluetoothService(Context context, Handler handler) { 
    mAdapter = BluetoothAdapter.getDefaultAdapter(); 
    mState = STATE_NONE; 
    mHandler = handler; 
} 

/** 
* Set the current state of the chat connection 
* 
* @param state An integer defining the current connection state 
*/ 
private synchronized void setState(int state) { 
    Log.d(TAG, "setState() " + mState + " -> " + state); 
    mState = state; 

    // Give the new state to the Handler so the UI Activity can update 
    mHandler.obtainMessage(Constants.MESSAGE_STATE_CHANGE, state, -1).sendToTarget(); 
} 

/** 
* Return the current connection state. 
*/ 
public synchronized int getState() { 
    return mState; 
} 

/** 
* Start the chat service. Specifically start AcceptThread to begin a 
* session in listening (server) mode. Called by the Activity onResume() 
*/ 
public synchronized void start() { 
    Log.d(TAG, "start"); 

    // Cancel any thread attempting to make a connection 
    if (mConnectThread != null) { 
     mConnectThread.cancel(); 
     mConnectThread = null; 
    } 

    // Cancel any thread currently running a connection 
    if (mConnectedThread != null) { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 
    } 

    setState(STATE_LISTEN); 

    // Start the thread to listen on a BluetoothServerSocket 
    if (mSecureAcceptThread == null) { 
     mSecureAcceptThread = new AcceptThread(true); 
     mSecureAcceptThread.start(); 
    } 
    if (mInsecureAcceptThread == null) { 
     mInsecureAcceptThread = new AcceptThread(false); 
     mInsecureAcceptThread.start(); 
    } 
} 

/** 
* Start the ConnectThread to initiate a connection to a remote device. 
* 
* @param device The BluetoothDevice to connect 
* 
*/ 
public synchronized void connect(BluetoothDevice device) { 
    Log.d(TAG, "connect to: " + device); 
    mAdapter.cancelDiscovery(); 
    // Cancel any thread attempting to make a connection 
    if (mState == STATE_CONNECTING) { 
     if (mConnectThread != null) { 
      mConnectThread.cancel(); 
      mConnectThread = null; 
     } 
    } 

    // Cancel any thread currently running a connection 
    if (mConnectedThread != null) { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 
    } 

    // Start the thread to connect with the given device 
    mConnectThread = new ConnectThread(device); 
    mConnectThread.start(); 
    setState(STATE_CONNECTING); 
} 

/** 
* Start the ConnectedThread to begin managing a Bluetooth connection 
* 
* @param socket The BluetoothSocket on which the connection was made 
* @param device The BluetoothDevice that has been connected 
*/ 
public synchronized void connected(BluetoothSocket socket, BluetoothDevice 
     device) { 
    // Log.d(TAG, "connected, Socket Type:" + socketType); 

    // Cancel the thread that completed the connection 
    if (mConnectThread != null) { 
     mConnectThread.cancel(); 
     mConnectThread = null; 
    } 

    // Cancel any thread currently running a connection 
    if (mConnectedThread != null) { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 
    } 

    // Cancel the accept thread because we only want to connect to one device 
    if (mSecureAcceptThread != null) { 
     mSecureAcceptThread.cancel(); 
     mSecureAcceptThread = null; 
    } 
    if (mInsecureAcceptThread != null) { 
     mInsecureAcceptThread.cancel(); 
     mInsecureAcceptThread = null; 
    } 

    // Start the thread to manage the connection and perform transmissions 
    mConnectedThread = new ConnectedThread(socket); 
    mConnectedThread.start(); 
    String konek = "Device connected..."; 
    byte[] pesan = konek.getBytes(); 
    mConnectedThread.write(pesan); 

    // Send the name of the connected device back to the UI Activity 
    Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME); 
    Bundle bundle = new Bundle(); 
    bundle.putString(Constants.DEVICE_NAME, device.getName()); 
    msg.setData(bundle); 
    mHandler.sendMessage(msg); 

    setState(STATE_CONNECTED); 
} 

/** 
* Stop all threads 
*/ 
public synchronized void stop() { 
    Log.d(TAG, "stop"); 

    if (mConnectThread != null) { 
     mConnectThread.cancel(); 
     mConnectThread = null; 
    } 

    if (mConnectedThread != null) { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 
    } 

    if (mSecureAcceptThread != null) { 
     mSecureAcceptThread.cancel(); 
     mSecureAcceptThread = null; 
    } 

    if (mInsecureAcceptThread != null) { 
     mInsecureAcceptThread.cancel(); 
     mInsecureAcceptThread = null; 
    } 
    setState(STATE_NONE); 
} 

/** 
* Write to the ConnectedThread in an unsynchronized manner 
* 
* @param out The bytes to write 
* @see ConnectedThread#write(byte[]) (java.lang.String) 
*/ 
public void write(byte[] out) { 
    // Create temporary object 
    ConnectedThread r; 
    // Synchronize a copy of the ConnectedThread 
    synchronized (this) { 
     if (mState != STATE_CONNECTED) return; 
     r = mConnectedThread; 
    } 
    // Perform the write unsynchronized 
    r.write(out); 
} 

/** 
* Indicate that the connection attempt failed and notify the UI Activity. 
*/ 
private void connectionFailed() { 
    // Send a failure message back to the Activity 
    Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST); 
    Bundle bundle = new Bundle(); 
    bundle.putString(Constants.TOAST, "Unable to connect device"); 
    msg.setData(bundle); 
    mHandler.sendMessage(msg); 

    // Start the service over to restart listening mode 
    // BluetoothService.this.start(); 
} 

/** 
* Indicate that the connection was lost and notify the UI Activity. 
*/ 
private void connectionLost() { 
    // Send a failure message back to the Activity 
    Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST); 
    Bundle bundle = new Bundle(); 
    bundle.putString(Constants.TOAST, "Device connection was lost"); 
    msg.setData(bundle); 
    mHandler.sendMessage(msg); 

    // Start the service over to restart listening mode 
    //BluetoothService.this.start(); 
} 

/** 
* This thread runs while listening for incoming connections. It behaves 
* like a server-side client. It runs until a connection is accepted 
* (or until cancelled). 
*/ 
private class AcceptThread extends Thread { 
    // The local server socket 
    private final BluetoothServerSocket mmServerSocket; 
    private String mSocketType; 

    public AcceptThread(boolean secure) { 
     BluetoothServerSocket tmp = null; 
     mSocketType = secure ? "Secure" : "Insecure"; 

     // Create a new listening server socket 
     try { 

       tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(
         NAME_INSECURE, MY_UUID_SECURE); 

     } catch (IOException e) { 
      Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e); 
     } 
     mmServerSocket = tmp; 
    } 

    public void run() { 
     Log.d(TAG, "Socket Type: " + mSocketType + 
       "BEGIN mAcceptThread" + this); 
     setName("AcceptThread" + mSocketType); 

     BluetoothSocket socket = null; 

     // Listen to the server socket if we're not connected 
     while (mState != STATE_CONNECTED) { 
      try { 
       // This is a blocking call and will only return on a 
       // successful connection or an exception 
       socket = mmServerSocket.accept(); 
      } catch (IOException e) { 
       Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e); 
       break; 
      } 

      // If a connection was accepted 
      if (socket != null) { 
       synchronized (BluetoothService.this) { 
        switch (mState) { 
         case STATE_LISTEN: 
         case STATE_CONNECTING: 
          // Situation normal. Start the connected thread. 
          connected(socket, socket.getRemoteDevice()); 
          break; 
         case STATE_NONE: 
         case STATE_CONNECTED: 
          // Either not ready or already connected. Terminate new socket. 
          try { 
           socket.close(); 
          } catch (IOException e) { 
           Log.e(TAG, "Could not close unwanted socket", e); 
          } 
          break; 
        } 
       } 
      } 
     } 
     Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType); 

    } 

    public void cancel() { 
     Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this); 
     try { 
      mmServerSocket.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "Socket Type" + mSocketType + "close() of server failed", e); 
     } 
    } 
} 


/** 
* This thread runs while attempting to make an outgoing connection 
* with a device. It runs straight through; the connection either 
* succeeds or fails. 
*/ 
private class ConnectThread extends Thread { 
    private final BluetoothSocket mmSocket; 
    private final BluetoothDevice mmDevice; 


    public ConnectThread(BluetoothDevice device) { 
     mmDevice = device; 
     BluetoothSocket tmp = null; 
     // mSocketType = secure ? "Secure" : "Insecure"; 

     // Get a BluetoothSocket for a connection with the 
     // given BluetoothDevice 
     try { 
       tmp = device.createRfcommSocketToServiceRecord(
         MY_UUID_SECURE); 
     } catch (IOException e) { 
      Log.e(TAG, "Socket Type: " + "create() failed", e); 
     } 
     mmSocket = tmp; 
    } 

    public void run() { 



     // Always cancel discovery because it will slow down a connection 
     mAdapter.cancelDiscovery(); 

     // Make a connection to the BluetoothSocket 
     try { 
      // This is a blocking call and will only return on a 
      // successful connection or an exception 

       mmSocket.connect(); 

     } catch (IOException e) { 
      // Close the socket 
      try { 
       mmSocket.close(); 
      } catch (IOException e2) { 
       Log.e(TAG, "unable to close() " + 
         " socket during connection failure", e2); 
      } 
      connectionFailed(); 
      return; 
     } 

     // Reset the ConnectThread because we're done 
     synchronized (BluetoothService.this) { 
      mConnectThread = null; 
     } 

     // Start the connected thread 
     connected(mmSocket, mmDevice); 
    } 

    public void cancel() { 
     try { 
      mmSocket.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "close() of connect " + " socket failed", e); 
     } 
    } 
} 

/** 
* This thread runs during a connection with a remote device. 
* It handles all incoming and outgoing transmissions. 
*/ 
//public class dulunya private 
private class ConnectedThread extends Thread { 
    private final BluetoothSocket mmSocket; 
    private final InputStream mmInStream; 
    private final OutputStream mmOutStream; 

    public ConnectedThread(BluetoothSocket socket) { 
     // Log.d(TAG, "create ConnectedThread: " + socketType); 
     mmSocket = socket; 
     InputStream tmpIn = null; 
     OutputStream tmpOut = null; 

     // Get the BluetoothSocket input and output streams 
     try { 
      tmpIn = socket.getInputStream(); 
      tmpOut = socket.getOutputStream(); 
     } catch (IOException e) { 
      Log.e(TAG, "temp sockets not created", e); 
     } 

     mmInStream = tmpIn; 
     mmOutStream = tmpOut; 
    } 

    public void run() { 
     Log.i(TAG, "BEGIN mConnectedThread"); 
     byte[] buffer = new byte[1024]; 
     int bytes; 

     // Keep listening to the InputStream while connected 
     while (true) { 
      try { 
       // Read from the InputStream 
       bytes = mmInStream.read(buffer); 

       // Send the obtained bytes to the UI Activity 
       mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer) 
         .sendToTarget(); 
      } catch (IOException e) { 
       Log.e(TAG, "disconnected", e); 
       connectionLost(); 
       // Start the service over to restart listening mode 
       BluetoothService.this.start(); 
       break; 
      } 
     } 
    } 

    /** 
    * Write to the connected OutStream. 
    * 
    * @param buffer The bytes to write 
    */ 
    public void write(byte[] buffer) { 
     try { 
      mmOutStream.write(buffer); 

      // Share the sent message back to the UI Activity 
      mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer) 
        .sendToTarget(); 
     } catch (IOException e) { 
      Log.e(TAG, "Exception during write", e); 
     } 
    } 

    public void cancel() { 
     try { 
      mmSocket.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "close() of connect socket failed", e); 
     } 
    } 
} 

解決,我修改代碼轉換成一個活動(MainActivity.class),所以我移動BluetoothService到MainActivity。

回答

0

您從不初始化kirimPesan,因此它具有空值。所以你有NullPointerException(異常,告訴你什麼是空的)。

在發送消息之前,您需要使用構造函數初始化kirimPesan。

另外,你可以把方法sendMessage放在你自己的類MainActivity中,那麼你根本不需要kirimPesan對象。

+0

我已將sendMesssage移動到MainActivity類中,但我仍然遇到同樣的錯誤。 :( – 2015-02-12 04:57:53

+0

你是否刪除kirimPesan?現在你在什麼行中得到異常 – 2015-02-12 07:51:18

+0

是的,現在我的代碼只是sendMessage(perintah);沒有kirimPesan。 – 2015-02-12 10:18:52