2014-01-08 45 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