Java android studio带有arduino,bt套接字关闭错误
我正在尝试制作一个可以控制伺服电机的应用程序,我正在使用蓝牙模块。首先,我使用了一些我在网上找到的代码来控制一个简单的LED: 它工作完美,我可以打开和关闭led的次数,我想。 接下来,我做了另一个按钮,使伺服转到180°并返回。这是可行的,但只有一次,我在网上找到了很多解决方案,但都无法解决这个问题,因为它只能工作一次。在我的logcat中,按下伺服按钮时会发生以下情况:Java android studio带有arduino,bt套接字关闭错误,java,android-studio,arduino,Java,Android Studio,Arduino,我正在尝试制作一个可以控制伺服电机的应用程序,我正在使用蓝牙模块。首先,我使用了一些我在网上找到的代码来控制一个简单的LED: 它工作完美,我可以打开和关闭led的次数,我想。 接下来,我做了另一个按钮,使伺服转到180°并返回。这是可行的,但只有一次,我在网上找到了很多解决方案,但都无法解决这个问题,因为它只能工作一次。在我的logcat中,按下伺服按钮时会发生以下情况: 2021-05-06 20:33:32.008 29340-29340/com.example.pes I/ViewRoo
2021-05-06 20:33:32.008 29340-29340/com.example.pes I/ViewRootImpl@79ab82a[MainActivity]: ViewPostIme pointer 0
2021-05-06 20:33:32.106 29340-29340/com.example.pes I/ViewRootImpl@79ab82a[MainActivity]: ViewPostIme pointer 1
2021-05-06 20:33:33.187 29340-31464/com.example.pes E/Arduino Message: Android Command: <herlaad>
2021-05-06 20:33:38.491 29340-31464/com.example.pes W/System.err: java.io.IOException: bt socket closed, read return: -1
2021-05-06 20:33:38.491 29340-31464/com.example.pes W/System.err: at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:750)
2021-05-06 20:33:38.491 29340-31464/com.example.pes W/System.err: at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:59)
2021-05-06 20:33:38.492 29340-31464/com.example.pes W/System.err: at com.example.pes.MainActivity$ConnectedThread.run(MainActivity.java:277)
2021-05-06 20:33:38.492 29340-31464/com.example.pes W/System.err: at com.example.pes.MainActivity$CreateConnectThread.run(MainActivity.java:231)
我不熟悉堆栈溢出,所以请告诉我我错过了一些重要信息
package com.example.pes;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.example.pes.R;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Timer;
import java.util.UUID;
import static android.content.ContentValues.TAG;
public class MainActivity extends AppCompatActivity {
private String deviceName = null;
private String deviceAddress;
public static Handler handler;
public static BluetoothSocket mmSocket;
public static ConnectedThread connectedThread;
public static CreateConnectThread createConnectThread;
private final static int CONNECTING_STATUS = 1; // used in bluetooth handler to identify message status
private final static int MESSAGE_READ = 2; // used in bluetooth handler to identify message update
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// UI Initialization
final Button buttonConnect = findViewById(R.id.buttonConnect);
final Toolbar toolbar = findViewById(R.id.toolbar);
final ProgressBar progressBar = findViewById(R.id.progressBar);
progressBar.setVisibility(View.GONE);
final TextView textViewInfo = findViewById(R.id.textViewInfo);
final Button buttonToggle = findViewById(R.id.buttonToggle);
buttonToggle.setEnabled(false);
final Button buttonHerlaad = findViewById(R.id.buttonHerlaad);
buttonHerlaad.setEnabled(false);
final ImageView imageView = findViewById(R.id.imageView);
imageView.setBackgroundColor(getResources().getColor(R.color.colorOff));
// If a bluetooth device has been selected from SelectDeviceActivity
deviceName = getIntent().getStringExtra("deviceName");
if (deviceName != null){
// Get the device address to make BT Connection
deviceAddress = getIntent().getStringExtra("deviceAddress");
// Show progree and connection status
toolbar.setSubtitle("Connecting to " + deviceName + "...");
progressBar.setVisibility(View.VISIBLE);
buttonConnect.setEnabled(false);
/*
This is the most important piece of code. When "deviceName" is found
the code will call a new thread to create a bluetooth connection to the
selected device (see the thread code below)
*/
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
createConnectThread = new CreateConnectThread(bluetoothAdapter,deviceAddress);
createConnectThread.start();
}
/*
Second most important piece of Code. GUI Handler
*/
handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg){
switch (msg.what){
case CONNECTING_STATUS:
switch(msg.arg1){
case 1:
toolbar.setSubtitle("Connected to " + deviceName);
progressBar.setVisibility(View.GONE);
buttonConnect.setEnabled(true);
buttonToggle.setEnabled(true);
buttonHerlaad.setEnabled(true);
break;
case -1:
toolbar.setSubtitle("Device fails to connect");
progressBar.setVisibility(View.GONE);
buttonConnect.setEnabled(true);
break;
}
break;
case MESSAGE_READ:
String arduinoMsg = msg.obj.toString(); // Read message from Arduino
switch (arduinoMsg.toLowerCase()){
case "led is turned on":
imageView.setBackgroundColor(getResources().getColor(R.color.colorOn));
textViewInfo.setText("Arduino Message : " + arduinoMsg);
break;
case "led is turned off":
imageView.setBackgroundColor(getResources().getColor(R.color.colorOff));
textViewInfo.setText("Arduino Message : " + arduinoMsg);
break;
case "systeem is herladen":
textViewInfo.setText("Arduino Message : " + arduinoMsg);
break;
}
break;
}
}
};
// Select Bluetooth Device
buttonConnect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Move to adapter list
Intent intent = new Intent(MainActivity.this, SelectDeviceActivity.class);
startActivity(intent);
}
});
// Button to ON/OFF LED on Arduino Board
buttonToggle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String cmdText = null;
String btnState = buttonToggle.getText().toString().toLowerCase();
switch (btnState){
case "turn on":
buttonToggle.setText("Turn Off");
// Command to turn on LED on Arduino. Must match with the command in Arduino code
cmdText = "<turn on>";
break;
case "turn off":
buttonToggle.setText("Turn On");
// Command to turn off LED on Arduino. Must match with the command in Arduino code
cmdText = "<turn off>";
break;
}
// Send command to Arduino board
connectedThread.write(cmdText);
}
});
buttonHerlaad.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String cmdText2 = null;
String btnState = buttonHerlaad.getText().toString().toLowerCase();
switch (btnState){
case "herlaad":
// Command to turn on LED on Arduino. Must match with the command in Arduino code
cmdText2 = "<herlaad>";
break;
}
// Send command to Arduino board
connectedThread.write(cmdText2);
}
});
}
/* ============================ Thread to Create Bluetooth Connection =================================== */
public static class CreateConnectThread extends Thread {
public CreateConnectThread(BluetoothAdapter bluetoothAdapter, String address) {
/*
Use a temporary object that is later assigned to mmSocket
because mmSocket is final.
*/
BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(address);
BluetoothSocket tmp = null;
UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
try {
/*
Get a BluetoothSocket to connect with the given BluetoothDevice.
Due to Android device varieties,the method below may not work fo different devices.
You should try using other methods i.e. :
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
*/
tmp = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid);
//tmp = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
Log.e(TAG, "Socket's create() method failed", e);
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it otherwise slows down the connection.
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.cancelDiscovery();
try {
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
mmSocket.connect();
Log.e("Status", "Device connected");
handler.obtainMessage(CONNECTING_STATUS, 1, -1).sendToTarget();
} catch (IOException connectException) {
// Unable to connect; close the socket and return.
try {
mmSocket.close();
Log.e("Status", "Cannot connect to device");
handler.obtainMessage(CONNECTING_STATUS, -1, -1).sendToTarget();
} catch (IOException closeException) {
Log.e(TAG, "Could not close the client socket", closeException);
}
return;
}
// The connection attempt succeeded. Perform work associated with
// the connection in a separate thread.
connectedThread = new ConnectedThread(mmSocket);
connectedThread.run();
}
// Closes the client socket and causes the thread to finish.
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close the client socket", e);
}
}
}
/* =============================== Thread for Data Transfer =========================================== */
public static class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes = 0; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
/*
Read from the InputStream from Arduino until termination character is reached.
Then send the whole String message to GUI Handler.
*/
buffer[bytes] = (byte) mmInStream.read();
String readMessage;
if (buffer[bytes] == '\n'){
readMessage = new String(buffer,0,bytes);
Log.e("Arduino Message",readMessage);
handler.obtainMessage(MESSAGE_READ,readMessage).sendToTarget();
bytes = 0;
} else {
bytes++;
}
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(String input) {
byte[] bytes = input.getBytes(); //converts entered String into bytes
try {
mmOutStream.write(bytes);
} catch (IOException e) {
Log.e("Send Error","Unable to send message",e);
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
/* ============================ Terminate Connection at BackPress ====================== */
@Override
public void onBackPressed() {
// Terminate Bluetooth Connection and close app
if (createConnectThread != null){
createConnectThread.cancel();
}
Intent a = new Intent(Intent.ACTION_MAIN);
a.addCategory(Intent.CATEGORY_HOME);
a.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(a);
}
}
package com.example.pes;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.os.Bundle;
import android.view.View;
import com.google.android.material.snackbar.Snackbar;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class SelectDeviceActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_device);
// Bluetooth Setup
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// Get List of Paired Bluetooth Device
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
List<Object> deviceList = new ArrayList<>();
if (pairedDevices.size() > 0) {
// There are paired devices. Get the name and address of each paired device.
for (BluetoothDevice device : pairedDevices) {
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
DeviceInfoModel deviceInfoModel = new DeviceInfoModel(deviceName,deviceHardwareAddress);
deviceList.add(deviceInfoModel);
}
// Display paired device using recyclerView
RecyclerView recyclerView = findViewById(R.id.recyclerViewDevice);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
DeviceListAdapter deviceListAdapter = new DeviceListAdapter(this,deviceList);
recyclerView.setAdapter(deviceListAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
} else {
View view = findViewById(R.id.recyclerViewDevice);
Snackbar snackbar = Snackbar.make(view, "Activate Bluetooth or pair a Bluetooth device", Snackbar.LENGTH_INDEFINITE);
snackbar.setAction("OK", new View.OnClickListener() {
@Override
public void onClick(View view) { }
});
snackbar.show();
}
}
}
package com.example.pes;
import android.content.Intent;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class DeviceListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<Object> deviceList;
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView textName, textAddress;
LinearLayout linearLayout;
public ViewHolder(View v) {
super(v);
textName = v.findViewById(R.id.textViewDeviceName);
textAddress = v.findViewById(R.id.textViewDeviceAddress);
linearLayout = v.findViewById(R.id.linearLayoutDeviceInfo);
}
}
public DeviceListAdapter(Context context, List<Object> deviceList) {
this.context = context;
this.deviceList = deviceList;
}
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.device_info_layout, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
ViewHolder itemHolder = (ViewHolder) holder;
final DeviceInfoModel deviceInfoModel = (DeviceInfoModel) deviceList.get(position);
itemHolder.textName.setText(deviceInfoModel.getDeviceName());
itemHolder.textAddress.setText(deviceInfoModel.getDeviceHardwareAddress());
// When a device is selected
itemHolder.linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(context,MainActivity.class);
// Send device details to the MainActivity
intent.putExtra("deviceName", deviceInfoModel.getDeviceName());
intent.putExtra("deviceAddress",deviceInfoModel.getDeviceHardwareAddress());
// Call MainActivity
context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
int dataCount = deviceList.size();
return dataCount;
}
}
package com.example.pes;
public class DeviceInfoModel {
private String deviceName, deviceHardwareAddress;
public DeviceInfoModel(){}
public DeviceInfoModel(String deviceName, String deviceHardwareAddress){
this.deviceName = deviceName;
this.deviceHardwareAddress = deviceHardwareAddress;
}
public String getDeviceName(){return deviceName;}
public String getDeviceHardwareAddress(){return deviceHardwareAddress;}
}