Не удаётся сделать отправку данных через Bluetooth
Я создаю приложение, которое должно отправлять и получать данные через Bluetooth. Но он ломается. Я не понимаю, почему.
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private BluetoothAdapter BluetoothAdapter;
private StringBuilder sb = new StringBuilder();
private ListView listView;
public static String ventilator_str;
public static String nagrevatel_str;
public static String pompa_str;
public static String auto_str;
private ArrayList<String> pairedDeviceArrayList;
private ArrayAdapter<String> pairedDeviceAdapter;
public static BluetoothSocket clientSocket;
ThreadConnectBTdevice myThreadConnectBTdevice;
InputStream inStream;
OutputStream outputStream;
private OutputStream outStream;
private static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static String address = "21:13:01:80:20"; //Вместо “00:00” Нужно нудет ввести MAC нашего bluetooth
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Switch ventil_switch = (Switch) findViewById(R.id.switch_ventilator);
final Switch nagrev_switch = (Switch) findViewById(R.id.switch_nagrev);
final Switch pompa_switch = (Switch) findViewById(R.id.switch_pompa);
Switch auto_switch = (Switch) findViewById(R.id.switch_auto);
Button SearchSrart = (Button) findViewById(R.id.StartSearch);
ListView Listarray = (ListView) findViewById(R.id.Arraylist);
ventil_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
System.out.println("Включен вентилятор");
int ventilator = 1;
System.out.println(ventilator);
String ventilator_str = Integer.toString(ventilator);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
Log.d(TAG, "...Посылаем данные: " + Otpravka + "...");
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
} else {
System.out.println("Выключен вентилятор");
int ventilator = 0;
System.out.println(ventilator);
String ventilator_str = Integer.toString(ventilator);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
Log.d(TAG, "...Посылаем данные: " + Otpravka + "...");
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
}
}
});
nagrev_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
System.out.println("Включен нагреватель");
int nagrevatel = 1;
System.out.println(nagrevatel);
String nagrevatel_str = Integer.toString(nagrevatel);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
Log.d(TAG, "...Посылаем данные: " + Otpravka + "...");
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
} else {
System.out.println("Выключен нагреватель");
int nagrevatel = 0;
System.out.println(nagrevatel);
String nagrevatel_str = Integer.toString(nagrevatel);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
Log.d(TAG, "...Посылаем данные: " + Otpravka + "...");
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
}
}
});
pompa_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
System.out.println("Включена помпа");
int pompa = 1;
System.out.println(pompa);
String pompa_str = Integer.toString(pompa);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
Log.d(TAG, "...Посылаем данные: " + Otpravka + "...");
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
} else {
System.out.println("Выключена помпа");
int pompa = 0;
System.out.println(pompa);
String pompa_str = Integer.toString(pompa);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
Log.d(TAG, "...Посылаем данные: " + Otpravka + "...");
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
}
}
});
auto_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
System.out.println("Включен автоматический режим");
int auto = 1;
System.out.println(auto);
String auto_str = Integer.toString(auto);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
Log.d(TAG, "...Посылаем данные: " + Otpravka + "...");
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
} else {
System.out.println("Выключен автоматический режим");
int auto = 0;
System.out.println(auto);
String auto_str = Integer.toString(auto);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
Log.d(TAG, "...Посылаем данные: " + Otpravka + "...");
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
}
}
});
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter != null) {
// С Bluetooth все в порядке.
}
SearchSrart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//если разрешения получены (функция ниже)
if (permissionGranted()) {
//адаптер для управления блютузом
BluetoothAdapter = android.bluetooth.BluetoothAdapter.getDefaultAdapter();
if (bluetoothEnabled()) { //если блютуз включен (функция ниже)
findArduino(); //начать поиск устройства (функция ниже)
}
}
}
});
}
private boolean permissionGranted() {
//если оба разрешения получены, вернуть true
if (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.BLUETOOTH) == PermissionChecker.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_ADMIN) == PermissionChecker.PERMISSION_GRANTED) {
return true;
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN}, 0);
return false;
}
}
private void findArduino() //функция для выбора устройства из списка доступных для подключения
{
Set<BluetoothDevice> pairedDevices = BluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
listView = findViewById(R.id.Arraylist);
List<BluetoothDevice> data = new ArrayList<>(pairedDevices);
ListAdapter adapter = new ListAdapter(data, getApplicationContext());
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
BluetoothDevice device = (BluetoothDevice) adapterView.getItemAtPosition(position);
device.getAddress();
int i = 1;
String itemMAC = listView.getItemAtPosition(i).toString().split("/", 2)[0];
BluetoothDevice connectDevice = BluetoothAdapter.getRemoteDevice(itemMAC);
try {
//генерируем socket - поток, через который будут посылаться данные
Method m = connectDevice.getClass().getMethod(
"createRfcommSocket", new Class[]{int.class});
clientSocket = (BluetoothSocket) m.invoke(connectDevice, 1);
clientSocket.connect();
if (clientSocket.isConnected()) {
//если соединение установлено, завершаем поиск
BluetoothAdapter.cancelDiscovery();
}
} catch (Exception e) {
e.getStackTrace();
}
myThreadConnectBTdevice = new ThreadConnectBTdevice(device);
myThreadConnectBTdevice.start();
}
});
}
}
private boolean bluetoothEnabled() {
//если блютуз включен, вернуть true, если нет, вежливо попросить пользователя его включить
if (BluetoothAdapter.isEnabled()) {
return true;
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 0);
return false;
}
}
private static class ThreadConnectBTdevice extends Thread { // Поток для коннекта с Bluetooth
private BluetoothSocket bluetoothSocket = null;
private ThreadConnectBTdevice(BluetoothDevice device) {
final OutputStream mmOutStream;
try {
bluetoothSocket = device.createRfcommSocketToServiceRecord(myUUID);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static class ListAdapter extends ArrayAdapter<BluetoothDevice> implements View.OnClickListener {
private Context mContext;
public static class ViewHolder {
TextView tvName;
}
public ListAdapter(List<BluetoothDevice> data, Context context) {
super(context, R.layout.row_item, data);
ArrayList<BluetoothDevice> dataSet = (ArrayList<BluetoothDevice>) data;
this.mContext = context;
}
@Override
public void onClick(View view) {
int position = (Integer) view.getTag();
Object object = getItem(position);
BluetoothDevice dataModel = (BluetoothDevice) object;
switch (view.getId()) {
case R.id.name:
Toast.makeText(mContext, "Name" + Objects.requireNonNull(dataModel).getName(), Toast.LENGTH_SHORT).show();
/*Snackbar.make(view, "Name " + dataModel.getName(), Snackbar.LENGTH_LONG)
.setAction("No action", null).show();*/
break;
}
}
private int lastPosition = -1;
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
// Get the data item for this position
BluetoothDevice dataModel = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // view lookup cache stored in tag
final View result;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.row_item, parent, false);
viewHolder.tvName = convertView.findViewById(R.id.name);
result = convertView;
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
result = convertView;
}
Animation animation = AnimationUtils.loadAnimation(mContext, (position > lastPosition) ? R.anim.up_from_bottom : R.anim.down_from_top);
result.startAnimation(animation);
lastPosition = position;
viewHolder.tvName.setText(Objects.requireNonNull(dataModel).getName());
// Return the completed view to render on screen
return convertView;
}
}
}
Основное действие происходит здесь. После каждого изменения положения Switch'a должна происходить отправка данных, но к сожалению, она не происходит...
ventil_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
System.out.println("Включен вентилятор");
int ventilator = 1;
String ventilator_str = Integer.toString(ventilator);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
} else {
System.out.println("Выключен вентилятор");
int ventilator = 0;
String ventilator_str = Integer.toString(ventilator);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
}
}
});
nagrev_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
System.out.println("Включен нагреватель");
int nagrevatel = 1;
String nagrevatel_str = Integer.toString(nagrevatel);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
} else {
System.out.println("Выключен нагреватель");
int nagrevatel = 0;
String nagrevatel_str = Integer.toString(nagrevatel);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
}
}
});
pompa_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
System.out.println("Включена помпа");
int pompa = 1;
String pompa_str = Integer.toString(pompa);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
} else {
System.out.println("Выключена помпа");
int pompa = 0;
String pompa_str = Integer.toString(pompa);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
}
}
});
auto_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
System.out.println("Включен автоматический режим");
int auto = 1;
String auto_str = Integer.toString(auto);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
} else {
System.out.println("Выключен автоматический режим");
int auto = 0;
String auto_str = Integer.toString(auto);
String Otpravka = ("/" + ventilator_str + "/" + nagrevatel_str + "/" + pompa_str + "/" + auto_str + "/");
System.out.println(Otpravka);
byte[] msgBuffer = Otpravka.getBytes();
try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
System.out.println(msg);
}
}
}
});
LogCat:
2020-08-25 19:48:57.781 6692-6692/com.example.appincubator E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.appincubator, PID: 6692
java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.OutputStream.write(byte[])' on a null object reference
at com.example.appincubator.MainActivity$3.onCheckedChanged(MainActivity.java:199)
at android.widget.CompoundButton.setChecked(CompoundButton.java:156)
at android.widget.Switch.setChecked(Switch.java:1074)
at android.widget.Switch.toggle(Switch.java:1069)
at android.widget.CompoundButton.performClick(CompoundButton.java:120)
at android.view.View$PerformClick.run(View.java:22465)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6396)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
Заранее спасибо!
Ответы (1 шт):
Автор решения: Barmaley
→ Ссылка
У вас массив outStream не инициализирован (равен null) - надо видимо ему какое-то значение присвоить.
Очевидно, там где у вас происходит коннект, вы должны и открывать выходной поток куда вы будете писать свои байты, но судя по вашему коду этого то как раз и не происходит.