2014-01-08 38 views
1

任何人都可以幫助我與我的應用程序代碼。我嘗試製作一個應用程序,可以通過藍牙向arduino發送數據(數字或字母)。這是怎麼我的JAVA代碼的樣子:應用程序意外停止:致命異常

package com.example.btprojektas; 

import android.app.Activity; 
import android.bluetooth.BluetoothAdapter; 
import android.bluetooth.BluetoothDevice; 
import android.bluetooth.BluetoothSocket; 

import android.content.Intent; 

import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 

import android.widget.Button; 
import android.widget.Toast; 

import java.io.IOException; 
import java.io.OutputStream; 
import java.util.Set; 
import java.util.UUID; 

public class MainActivity extends Activity{ 

private static final String TAG = "btprojektas"; 

Button btnON, btnOFF; 

BluetoothAdapter bluetoothAdapter = null; 
BluetoothDevice device = null; 
OutputStream outputStream = null; 
BluetoothSocket socket = null; 



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

    bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 

    btnON = (Button) findViewById(R.id.btnON); 
    btnOFF = (Button) findViewById(R.id.btnOFF); 

    if(!bluetoothAdapter.isEnabled()){ 
     Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
     startActivityForResult(enableBluetooth, 0); 
    } 

    loadPairedDevice(); 
    connectBT(); 

    btnON.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      sendData("0"); 
      Toast.makeText(getBaseContext(), "Turn on LED", Toast.LENGTH_SHORT).show(); 
     } 
    }); 

    btnOFF.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      sendData("1"); 
      Toast.makeText(getBaseContext(), "Turn off LED", Toast.LENGTH_SHORT).show(); 
     } 
    }); 
} 

private void connectBT() { 
    if (device != null) { 
     UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard SerialPortService ID 
     try { 
      socket = device.createRfcommSocketToServiceRecord(uuid); 
      socket.connect(); 
      outputStream = socket.getOutputStream(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 


private void disconnect() { 
    try { 
     if (outputStream != null) outputStream.close(); 
     if (socket != null) socket.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private void loadPairedDevice() { 
    Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices(); 

    if (pairedDevices.size() > 0) { 
     Log.d(TAG, "Device found"); 

     for (BluetoothDevice device : pairedDevices) 
      if (device.getName().equals("HC-06")) { 
       this.device = device; 
       break; 
      } 
    } 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    disconnect(); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    loadPairedDevice(); 
    connectBT(); 
} 

private void sendData(String message) { 
    byte[] buffer = message.getBytes(); 
    Log.d(TAG,"Send data:"+ message); 
    try{ 
     outputStream.write (buffer); 
    } catch (IOException e) {} 

} 

}

在XML我有兩個按鈕。當程序啓動時,我按下其中一個按鈕,出現「應用程序...意外停止」,並顯示致命故障代碼:

01-08 15:55:15.439 15354-15354/com.example.btprojektas E/AndroidRuntime﹕ FATAL EXCEPTION: main 
java.lang.NullPointerException 
     at com.example.btprojektas.MainActivity.sendData(MainActivity.java:122) 
     at com.example.btprojektas.MainActivity.access$000(MainActivity.java:22) 
     at com.example.btprojektas.MainActivity$1.onClick(MainActivity.java:55) 
     at android.view.View.performClick(View.java:2485) 
     at android.view.View$PerformClick.run(View.java:9080) 
     at android.os.Handler.handleCallback(Handler.java:587) 
     at android.os.Handler.dispatchMessage(Handler.java:92) 
     at android.os.Looper.loop(Looper.java:130) 
     at android.app.ActivityThread.main(ActivityThread.java:3687) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:507) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625) 
     at dalvik.system.NativeStart.main(Native Method) 

P.S.對於這個問題抱歉,我知道這很常見,但我在編程方面尤其是JAVA。

+0

哪條線是122? – chrylis

+1

當您嘗試訪問它們時'outputStream'或'message'爲null。通過將所有的套接字調用包裝在'try {} catch(IOException)中',你可能會忽略一些重要的錯誤。您應該至少在e.printStackTrace()調用中放置一個斷點。更好的做法是在這裏實際做一些有用的事情,即通知用戶連接失敗 – CodingIntrigue

+0

檢查'device'是否不是'null'。 –

回答

0

它是socket或outputStream。在ConnectBT中,您不檢查套接字是否爲空。假設套接字有效,您可以直接調用socket.connect()。這同樣適用於outputStream。您在確定它不爲空之前使用它。

你也叫

startActivityForResult(enableBluetooth, 0); 

,但你不檢查的結果是藍牙是否得到允許。這使您的設備也可疑。

調用

loadPairedDevice(); 
connectBT(); 

使得啓用藍牙時才感。啓用藍牙可能需要幾秒鐘,但您可以立即給他們打電話。

0

幾個祕訣:

  • 你打電話loadPairedDevice()和connectBT()兩次:在的onCreate()和的onResume() - 做一次
  • 使用的OutputStream,檢查之前如果它不是空(被別人當作決定)
  • 在送出數據(

    ),捕獲並打印例外:

    try { 
        if (outputStream != null) { 
         outputStream.write(buffer); 
        } 
        else { 
         Log.d("TAG", "sendData() - outputStream is null!"); 
        } 
    } 
    catch (IOException e) { 
        e.printStackTrace(); 
    } 
    
  • 在loadPairedDevice

    () ,如果您沒有找到設備「HC-06」,您的可變設備將爲空...

  • 啓用藍牙需要幾秒鐘,因此註冊並偵聽ACTION_STATE_CHANGED廣播意圖。它將包含額外的EXTRA_STATE字段;尋找STATE_ON,然後打電話給你的loadPairedDevices()和connectBT()有:

    • 創建接收器(您的MainActivity類別中):

      private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 
          public void onReceive(Context context, Intent intent) { 
           final String action = intent.getAction(); 
      
           //this is the action you are observing 
           if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { 
            final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); 
            switch(state) { 
             //and the state we were looking for 
             //which means that bluetooth has switched on 
             //so now you can call your functions 
             //and set the flag to true, which then use in your 
             //onClick listeners 
             case BluetoothAdapter.STATE_ON: 
              loadPairedDevice(); 
              connectBT(); 
              isBluetoothOn = true; 
              break; 
            } 
           } 
          } 
      } 
      
    • 中的onCreate(

      ),創造的IntentFilter並註冊接收器與它

      IntentFilter btFilter = new IntentFilter(); 
      btFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 
      
      registerReceiver(mReceiver, btFilter); 
      
    • 記得的onPause()來註銷接收器:

      unregisterReceiver(mReceiver); 
      
  • 禁用按鈕,並在上面監聽器啓用它們,當你知道BT被打開;或者,在聽衆後保持標誌,並在點擊監聽器使用它,例如:

    boolean isBluetoothOn = false; 
    

然後當你STATE_ON

isBluetooth = true; 

而在你點擊按鈕聽衆:

//for btnON 
public void onClick(View v) { 
    if (isBluetoothOn) { 
     sendData("0"); 
     Toast.makeText(getBaseContext(), "Turn on LED", Toast.LENGTH_SHORT).show(); 
    } 
} 

對btnOFF做同樣的處理。

+0

感謝您的幫助,我檢查了outputStream是否爲空,並且我發現它實際上是現在我沒有那個「Applications」。意外停止「按鈕時出現故障。運行應用程序時,我仍然有「致命異常」,但我會嘗試應用其可能起作用的其他提示。 – user3173452

+0

你能幫我解釋第五點嗎?它應該看起來如何? – user3173452

+0

已在答案中添加。 – Melquiades