我想尝试基本的蓝牙聊天应用程序。这是我的代码。我有听,列表视图和发送按钮。 听:搜索蓝牙设备 列表视图:显示设备列表 发送:发送消息
如果我按下听音按钮。没有问题,但如果我按列表视图或发送按钮,我会发生致命错误并关闭我的应用程序。
package com.example.duygu.btsendmessage;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
Button listen, btsend, listdevice;
ListView listview;
TextView textview, messageview;
EditText entermessage;
BluetoothAdapter myBluetoothAdapter;
BluetoothDevice[] btArray;
Intent enableIntent;
SendReceive sendReceive;
ArrayList<String> stringArrayList = new ArrayList<String>();
ArrayAdapter<String> arrayAdapter;
static final int STATE_LISTENING = 1;
static final int STATE_CONNECTING = 2;
static final int STATE_CONNECTED = 3;
static final int STATE_CONNECTION_FAILED = 4;
static final int STATE_MESSAGE_RECEIVER = 5;
int REQUEST_ENABLE_BLUETOOTH = 1;
private static final String APP_NAME = "BTCom";
private static final UUID MYUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
findviewbyidset();
if (!myBluetoothAdapter.isEnabled()) {
enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BLUETOOTH);
}
implementListeners();
}
private void findviewbyidset() {
listen = (Button) findViewById(R.id.listen);
btsend = (Button) findViewById(R.id.btsend);
listdevice = (Button) findViewById(R.id.listdevice);
listview = (ListView) findViewById(R.id.listview);
textview = (TextView) findViewById(R.id.textview);
messageview = (TextView) findViewById(R.id.messageview);
entermessage = (EditText) findViewById(R.id.entermessage);
}
private void implementListeners() {
listdevice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Set<BluetoothDevice> bt = myBluetoothAdapter.getBondedDevices();
String[] strings = new String[bt.size()];
//btArray=new BluetoothDevice[bt.size()];
int index = 0;
if (bt.size() > 0) {
for (BluetoothDevice device : bt) {
strings[index] = device.getName();
index++;
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, strings);
listview.setAdapter(arrayAdapter);
}
}
});
listen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ServerClass serverClass=new ServerClass();
serverClass.start();
}
});
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
ClientClass clientClass= new ClientClass(btArray[i]);
clientClass.start();
textview.setText("Connecting");
}
});
btsend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String string= String.valueOf(entermessage.getText());
sendReceive.write(string.getBytes());
}
});
}
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case STATE_LISTENING:
textview.setText("Listening");
break;
case STATE_CONNECTING:
textview.setText("Connecting");
break;
case STATE_CONNECTED:
textview.setText("Connected");
break;
case STATE_CONNECTION_FAILED:
textview.setText("Connection Failed");
break;
case STATE_MESSAGE_RECEIVER:
byte[] readBuff= (byte[]) msg.obj;
String tempMsg=new String(readBuff,0,msg.arg1);
messageview.setText(tempMsg);
break;
}
return true;
}
});
private class ServerClass extends Thread {
private BluetoothServerSocket serverSocket;
public ServerClass() {
try {
serverSocket = myBluetoothAdapter.listenUsingRfcommWithServiceRecord(APP_NAME, MYUUID);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
BluetoothSocket socket=null;
while(socket==null){
try{
Message message=Message.obtain();
message.what=STATE_CONNECTING;
handler.sendMessage(message);
socket=serverSocket.accept();
}
catch(IOException e){
e.printStackTrace();
Message message=Message.obtain();
message.what=STATE_CONNECTING;
handler.sendMessage(message);
}
if(socket!=null){
Message message=Message.obtain();
message.what=STATE_CONNECTED;
handler.sendMessage(message);
sendReceive=new SendReceive(socket);
sendReceive.start();
break;
}
}
}
}
private class ClientClass extends Thread{
private BluetoothDevice device;
private BluetoothSocket socket;
public ClientClass (BluetoothDevice device1){
device=device1;
try{
socket=device.createRfcommSocketToServiceRecord(MYUUID);
} catch(IOException e){
e.printStackTrace();
}
}
public void run(){
try{
socket.connect();
Message message=Message.obtain();
message.what=STATE_CONNECTED;
handler.sendMessage(message);
sendReceive=new SendReceive(socket);
sendReceive.start();
}
catch(IOException e){
e.printStackTrace();
Message message=Message.obtain();
message.what=STATE_CONNECTION_FAILED;
handler.sendMessage(message);
}
}
}
private class SendReceive extends Thread{
private BluetoothSocket bluetoothSocket;
private InputStream inputStream;
private OutputStream outputStream;
public SendReceive (BluetoothSocket socket){
bluetoothSocket=socket;
InputStream tempIn =null;
OutputStream tempOut=null;
try {
tempIn=bluetoothSocket.getInputStream();
tempOut=bluetoothSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
byte[] buffer=new byte[1024];
int bytes;
while(true){
try {
bytes=inputStream.read(buffer);
handler.obtainMessage(STATE_MESSAGE_RECEIVER,bytes,-1,buffer).sendToTarget();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void write(byte[] bytes){
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我的Fattal Erorrs:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.duygu.btsendmessage, PID: 7917
java.lang.NullPointerException: Attempt to read from null array
at com.example.duygu.btsendmessage.MainActivity$3.onItemClick(MainActivity.java:125)
at android.widget.AdapterView.performItemClick(AdapterView.java:310)
at android.widget.AbsListView.performItemClick(AbsListView.java:1188)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3100)
at android.widget.AbsListView$3.run(AbsListView.java:4091)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5525)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
修改1
我更改了这部分代码并修复了列表视图按钮,但发送按钮有一些错误。
private void implementListeners() {
listdevice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Set<BluetoothDevice> bt = myBluetoothAdapter.getBondedDevices();
String[] strings = new String[bt.size()];
btArray=new BluetoothDevice[bt.size()];
int index = 0;
if (bt.size() > 0) {
for (BluetoothDevice device : bt) {
btArray[index] = device;
strings[index] = device.getName();
index++;
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, strings);
listview.setAdapter(arrayAdapter);
}
}
});
致命错误
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.duygu.btsendmessage, PID: 16656
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.duygu.btsendmessage.MainActivity$SendReceive.write(byte[])' on a null object reference
at com.example.duygu.btsendmessage.MainActivity$4.onClick(MainActivity.java:135)
at android.view.View.performClick(View.java:5201)
at android.view.View$PerformClick.run(View.java:21215)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5525)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
修改2
我更改了所有搜索代码。
package com.example.duygu.btsendmessage;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
Button listen, btsend, listdevice;
ListView listview;
TextView textview, messageview;
EditText entermessage;
BluetoothAdapter myBluetoothAdapter;
BluetoothDevice[] btArray;
Intent enableIntent;
SendReceive sendReceive;
static final int STATE_LISTENING = 1;
static final int STATE_CONNECTING = 2;
static final int STATE_CONNECTED = 3;
static final int STATE_CONNECTION_FAILED = 4;
static final int STATE_MESSAGE_RECEIVER = 5;
int REQUEST_ENABLE_BLUETOOTH = 1;
private static final String APP_NAME = "BTCom";
private static final UUID MYUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
ArrayList<String> stringArrayList = new ArrayList<String>();
ArrayAdapter<String> arrayAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(myReceiver,intentFilter);
findviewbyidset();
int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1;
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
implementListeners();
}
private void findviewbyidset() {
listen = (Button) findViewById(R.id.listen);
btsend = (Button) findViewById(R.id.btsend);
listdevice = (Button) findViewById(R.id.listdevice);
listview = (ListView) findViewById(R.id.listview);
textview = (TextView) findViewById(R.id.textview);
messageview = (TextView) findViewById(R.id.messageview);
entermessage = (EditText) findViewById(R.id.entermessage);
}
private void implementListeners() {
listdevice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myBluetoothAdapter.startDiscovery();
if (!myBluetoothAdapter.isEnabled()) {
enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BLUETOOTH);
}
/* Set<BluetoothDevice> bt = myBluetoothAdapter.getBondedDevices();
String[] strings = new String[bt.size()];
btArray=new BluetoothDevice[bt.size()];
int index = 0;
if (bt.size() > 0) {
for (BluetoothDevice device : bt) {
btArray[index] = device;
strings[index] = device.getName();
index++;
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, strings);
listview.setAdapter(arrayAdapter);
}*/
}
});
listen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ServerClass serverClass=new ServerClass();
serverClass.start();
}
});
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
ClientClass clientClass= new ClientClass(device);
clientClass.start();
textview.setText("Connecting");
}
});
btsend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String string= String.valueOf(entermessage.getText());
sendReceive.write(string.getBytes());
}
});
}
Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case STATE_LISTENING:
textview.setText("Listening");
break;
case STATE_CONNECTING:
textview.setText("Connecting");
break;
case STATE_CONNECTED:
textview.setText("Connected");
break;
case STATE_CONNECTION_FAILED:
textview.setText("Failed");
break;
case STATE_MESSAGE_RECEIVER:
byte[] readBuff= (byte[]) msg.obj;
String tempMsg=new String(readBuff,0,msg.arg1);
messageview.setText(tempMsg);
break;
}
return true;
}
});
private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
stringArrayList.add(device.getName() + "\n" + device.getAddress());
Log.i("BT", device.getName() + "\n" + device.getAddress());
listview.setAdapter(new ArrayAdapter<String>(context,
android.R.layout.simple_list_item_1, stringArrayList));
}
}
};
private class ServerClass extends Thread {
private BluetoothServerSocket serverSocket;
public ServerClass() {
try {
serverSocket = myBluetoothAdapter.listenUsingRfcommWithServiceRecord(APP_NAME, MYUUID);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
BluetoothSocket socket=null;
while(socket==null){
try{
Message message=Message.obtain();
message.what=STATE_CONNECTING;
handler.sendMessage(message);
socket=serverSocket.accept();
}
catch(IOException e){
e.printStackTrace();
Message message=Message.obtain();
message.what=STATE_CONNECTING;
handler.sendMessage(message);
}
if(socket!=null){
Message message=Message.obtain();
message.what=STATE_CONNECTED;
handler.sendMessage(message);
sendReceive=new SendReceive(socket);
sendReceive.start();
break;
}
}
}
}
private class ClientClass extends Thread{
private BluetoothDevice device;
private BluetoothSocket socket;
public ClientClass (BluetoothDevice device1){
device=device1;
try{
socket=device.createRfcommSocketToServiceRecord(MYUUID);
} catch(IOException e){
e.printStackTrace();
}
}
public void run(){
try{
socket.connect();
Message message=Message.obtain();
message.what=STATE_CONNECTED;
handler.sendMessage(message);
sendReceive=new SendReceive(socket);
sendReceive.start();
}
catch(IOException e){
e.printStackTrace();
Message message=Message.obtain();
message.what=STATE_CONNECTION_FAILED;
handler.sendMessage(message);
}
}
}
private class SendReceive extends Thread{
private BluetoothSocket bluetoothSocket;
private InputStream inputStream;
private OutputStream outputStream;
public SendReceive (BluetoothSocket socket){
bluetoothSocket=socket;
InputStream tempIn =null;
OutputStream tempOut=null;
try {
tempIn=bluetoothSocket.getInputStream();
tempOut=bluetoothSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
public void run(){
byte[] buffer=new byte[1024];
int bytes;
while(true){
try {
bytes=inputStream.read(buffer);
handler.obtainMessage(STATE_MESSAGE_RECEIVER,bytes,-1,buffer).sendToTarget();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void write(byte[] bytes){
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
如何更改此代码:
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
ClientClass clientClass= new ClientClass(**????**);
clientClass.start();
textview.setText("Connecting");
}
});
答案 0 :(得分:0)
您正在使用implementListeners()函数向ArrayAdapter构造函数发送一个空的String数组。
将setOnClickListerner更改为
private void implementListeners() {
listdevice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Set<BluetoothDevice> bt = myBluetoothAdapter.getBondedDevices();
String[] strings = new String[bt.size()];
btArray=new BluetoothDevice[bt.size()];
int index = 0;
if (bt.size() > 0) {
for (BluetoothDevice device : bt) {
btArray[index] = device;
strings[index] = bt.getName();
index++;
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, strings);
listview.setAdapter(arrayAdapter);
}
}
});
回答编辑2
声明BluetoothDevice的ArrayList
ArrayList<BluetoothDevice> list = new ArrayList<>();
添加此list.add(设备);在
private final BroadcastReceiver myReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
list.add(device); // this line here
stringArrayList.add(device.getName() + "\n" + device.getAddress());
Log.i("BT", device.getName() + "\n" + device.getAddress());
listview.setAdapter(new ArrayAdapter<String>(context,
android.R.layout.simple_list_item_1, stringArrayList));
}
}
};
最后将listview.setOnItemClickListener更改为
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
ClientClass clientClass= new ClientClass(list.get(i));
clientClass.start();
textview.setText("Connecting");
}
});