【发布时间】: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 的更多信息,或者“简单地”告诉我要添加什么?