应用程序意外停止:致命异常

时间:2014-01-08 14:08:57

标签: java android bluetooth fault

任何人都可以通过我的应用代码帮助我。我试图制作一个可以通过蓝牙将数据(数字或字母)发送到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的新手。

2 个答案:

答案 0 :(得分:0)

它是socket或outputStream。在ConnectBT中,您不检查套接字是否为空。假设socket有效,你直接调用socket.connect()。这同样适用于outputStream。在确定它不为空之前使用它。

你也打电话

startActivityForResult(enableBluetooth, 0);

但是你没有检查蓝牙是否启用的结果。这会让您的设备产生怀疑。

致电

loadPairedDevice();
connectBT();

仅在启用蓝牙时才有意义。启用蓝牙可能需要几秒钟,但您可以立即调用它们。

答案 1 :(得分:0)

一些提示:

  • 你正在调用loadPairedDevice()和connectBT()两次:在onCreate()和onResume()中 - 只执行一次
  • 在使用outputStream之前,检查它是否为空(由其他人建议)
  • sendData()中的
  • ,捕获并打印您的异常:

    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做同样的事。