【问题标题】:Sending byte from Android to Arduino over Bluetooth causes application to crash通过蓝牙从 Android 向 Arduino 发送字节会导致应用程序崩溃
【发布时间】:2015-01-02 18:06:10
【问题描述】:

我叫 Nick,我是开发 Android 应用程序的新手。我正在尝试开发一个简单的应用程序来打开和关闭电动门锁。我目前的目标是创建一个只有 3 个按钮的应用程序:一个连接蓝牙模块 (HC-06) 的按钮、一个解锁门的按钮和一个锁门的按钮。这个应用程序应该通过蓝牙向 Arduino 发送 1 或 0,然后它将锁定或解锁门。请注意,在项目的这个阶段,电锁被一个 LED 取代。到目前为止,我已经设法创建了一个连接到蓝牙模块的按钮,如果您按下其他按钮之一(openDoor 和 closeDoor),应用程序将停止工作。

我的问题是:我应该对代码进行哪些更改才能使其正常工作,而不是让应用程序崩溃?

应用代码:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;




public class MainActivity extends Activity implements OnClickListener{

TextView myLabel;
BluetoothAdapter btAdapter;
BluetoothDevice mDevice;
Set<BluetoothDevice> devicesArray;
Button button;
OutputStream mmOutStream;
BluetoothDevice mmDevice;
BluetoothSocket mmSocket;
InputStream mmInputStream;
OutputStream mmOutputStream;
Thread workerThread;
byte one;
byte zero;
byte[] readBuffer;
int readBufferPosition;
volatile boolean stopWorker;

public void openDoor(View view)
{
    Toast.makeText(this, "Door is unlocked", Toast.LENGTH_SHORT).show();
    try
    {
    unlockDoor();
    }
    catch (IOException ex){}                
}

public void closeDoor (View view)
{
    Toast.makeText(this, "Door is locked", Toast.LENGTH_SHORT).show();
    try
    {
    lockDoor();
    }
    catch (IOException ex){}
}

public void onMyButtonClick(View view)
{
    try
    {
        findBT();
        openBT();
    }
    catch (IOException ex){}   
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    btAdapter = BluetoothAdapter.getDefaultAdapter();
    if (btAdapter == null) {
    // Device does not support Bluetooth
    }
    if (!btAdapter.isEnabled()) {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, 0);
        }
}


@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);
}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
}

void findBT()
{
    btAdapter = BluetoothAdapter.getDefaultAdapter();
    if(btAdapter == null)
    {
        Toast.makeText(this, "No Bluetooth adapter available", Toast.LENGTH_SHORT).show();
    }

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

    Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices();
    if(pairedDevices.size() > 0)
    {
        for(BluetoothDevice device : pairedDevices)
        {
            if(device.getName().equals("HC-06")) 
            {
                mmDevice = device;
                break;
            }
        }
    }
    Toast.makeText(this, "Bluetooth device found", Toast.LENGTH_SHORT).show();
}
void openBT() throws IOException
{
    UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard      SerialPortService ID
    mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);        
    mmSocket.connect();
    mmOutputStream = mmSocket.getOutputStream();
    mmInputStream = mmSocket.getInputStream();



    Toast.makeText(this, "Bluetooth connection established", Toast.LENGTH_SHORT).show();
}


 private void unlockDoor() throws IOException {
     one = 1;
     mmOutStream.write(one);
     mmOutStream.flush();
     mmOutStream.close(); 



 }
 private void lockDoor() throws IOException {
     zero = 0;
     mmOutStream.write(zero);
     mmOutStream.flush();
     mmOutStream.close();
 }
}

LogCat:

01-02 19:22:11.970: I/Process(1855): Sending signal. PID: 1855 SIG: 9
01-02 19:22:15.438: D/OpenGLRenderer(2964): Render dirty regions requested: true
01-02 19:22:15.445: D/Atlas(2964): Validating map...
01-02 19:22:15.512: I/Adreno-EGL(2964): <qeglDrvAPI_eglInitialize:410>: QUALCOMM Build: 10/24/14,      167c270, I68fa98814b
01-02 19:22:15.513: I/OpenGLRenderer(2964): Initialized EGL, version 1.4
01-02 19:22:15.526: D/OpenGLRenderer(2964): Enabling debug mode 0
01-02 19:22:17.176: W/BluetoothAdapter(2964): getBluetoothService() called with no   BluetoothManagerCallback
01-02 19:22:21.425: I/Choreographer(2964): Skipped 255 frames!  The application may be doing too  much work on its main thread.
01-02 19:22:21.550: V/RenderScript(2964): Application requested CPU execution
01-02 19:22:21.557: V/RenderScript(2964): 0xa1f36000 Launching thread(s), CPUs 4
01-02 19:22:24.554: D/AndroidRuntime(2964): Shutting down VM
01-02 19:22:24.555: E/AndroidRuntime(2964): FATAL EXCEPTION: main
01-02 19:22:24.555: E/AndroidRuntime(2964): Process: com.nickstaal.rnbtlock, PID: 2964
01-02 19:22:24.555: E/AndroidRuntime(2964): java.lang.IllegalStateException: Could not execute method of the activity
01-02 19:22:24.555: E/AndroidRuntime(2964):     at android.view.View$1.onClick(View.java:4007)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at android.view.View.performClick(View.java:4756)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at android.view.View$PerformClick.run(View.java:19749)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at android.os.Handler.handleCallback(Handler.java:739)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at android.os.Handler.dispatchMessage(Handler.java:95)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at android.os.Looper.loop(Looper.java:135)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at android.app.ActivityThread.main(ActivityThread.java:5221)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at java.lang.reflect.Method.invoke(Native Method)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at  java.lang.reflect.Method.invoke(Method.java:372)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
01-02 19:22:24.555: E/AndroidRuntime(2964): Caused by: java.lang.reflect.InvocationTargetException
01-02 19:22:24.555: E/AndroidRuntime(2964):     at java.lang.reflect.Method.invoke(Native Method)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at java.lang.reflect.Method.invoke(Method.java:372)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at android.view.View$1.onClick(View.java:4002)
01-02 19:22:24.555: E/AndroidRuntime(2964):     ... 10 more
01-02 19:22:24.555: E/AndroidRuntime(2964): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.OutputStream.write(int)' on a null object reference
01-02 19:22:24.555: E/AndroidRuntime(2964):     at  com.nickstaal.rnbtlock.MainActivity.unlockDoor(MainActivity.java:172)
01-02 19:22:24.555: E/AndroidRuntime(2964):     at com.nickstaal.rnbtlock.MainActivity.openDoor(MainActivity.java:57)
01-02 19:22:24.555: E/AndroidRuntime(2964):     ... 13 more

【问题讨论】:

  • 有故障转储/堆栈回溯?不要让我们尝试和猜测问题可能出在哪里。
  • 啊,是的,对不起。我马上添加。
  • 我已经添加了 LogCat 消息,希望你或其他人能帮助我解决这个问题。
  • 您的 OutputStream 尚未初始化,至少在该实例(运行)中未初始化。尝试添加一个检查,并适当地处理它(自动连接、错误对话框等)。
  • 感谢 Chris,但我缺乏创建代码来进行此类更改的技能。我的 MainActivity 中的大部分内容都是从互联网上收集的并稍作编辑。您能否告诉我在哪里可以找到有关初始化 OutputStream 的更多信息,或者“简单地”告诉我要添加什么?

标签: android bluetooth arduino


【解决方案1】:

经过大量研究后,我设法找到了可行的解决方案。我把 lockDoor() 和 unlockDoor() 的代码改成了这样:

public void unlockDoor() throws IOException {
     try {
            mmOutStream = mmSocket.getOutputStream();
        } catch (IOException e) {}

        String message = "1";

        byte[] msgBuffer = message.getBytes();

        try {
            mmOutStream.write(msgBuffer);
        } catch (IOException e) {}
    } 




 public void lockDoor() throws IOException {
     try {
            mmOutStream = mmSocket.getOutputStream();
        } catch (IOException e) {}

        String message = "0";

        byte[] msgBuffer = message.getBytes();

        try {
            mmOutStream.write(msgBuffer);
        } catch (IOException e) {}
    } 

无论如何,感谢您提供帮助,我相信稍后我会遇到其他问题。 :)

【讨论】:

  • 你能确认不刷新消息会阻止崩溃吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-29
相关资源
最近更新 更多