Проблема с подключением Bluetooth в Android Studio ⇐ Android
-
Гость
Проблема с подключением Bluetooth в Android Studio
Чтобы рассказать предысторию, я создаю приложение для Android в студии Android, используя Java. Это приложение служит цифровым радиоуправляемым контроллером для радиоуправляемого самолета. Моя цель — иметь возможность подключаться к самолету через Bluetooth и управлять самолетом с моего телефона Android. Я долгое время работал со студией Android и Java, но никогда раньше не работал с соединениями/разрешениями Bluetooth. Я запускаю приложение и работаю, но у меня работает Bluetooth с перебоями. У меня уже создана кнопка с надписью Bluetooth, но сейчас она ничего не делает. Я пытался сделать так, чтобы при нажатии кнопки Bluetooth появлялось меню с Bluetooth, доступными для подключения, однако при этом приложение просто вылетало. Ниже приведен мой код MainActivity.Java и мой AndroidManifest.xml
пакет com.example.rcair; импортировать android.Manifest; импортировать android.bluetooth.BluetoothAdapter; импортировать android.bluetooth.BluetoothDevice; импортировать android.bluetooth.BluetoothSocket; импортировать android.content.BroadcastReceiver; импортировать android.content.Context; импортировать android.content.Intent; импортировать android.content.IntentFilter; импортировать android.content.pm.PackageManager; импортировать android.os.BatteryManager; импортировать android.os.Bundle; импортировать android.view.MotionEvent; импортировать android.view.View; импортировать android.widget.Button; импортировать android.widget.ImageView; импортировать androidx.annotation.NonNull; импортировать androidx.appcompat.app.AppCompatActivity; импортировать androidx.core.app.ActivityCompat; импортировать androidx.core.content.ContextCompat; импортировать java.io.IOException; публичный класс MainActivity расширяет AppCompatActivity { частная кнопка dragLeftButton; частная кнопка dragRightButton; частный ImageView BatteryIcon; частная кнопка BluetoothButton; частный int дроссель = 0; частный int bodyRoll = 0; частный int рыскание = 0; частный int шаг = 0; // Переменные Bluetooth частный Bluetooth-адаптер Bluetooth-адаптер; частный BluetoothSocket bluetoothSocket; частный BluetoothDevice bluetoothDevice; частный статический финал int REQUEST_ENABLE_BT = 1; частный статический финал int REQUEST_PERMISSION_BLUETOOTH = 2; @Override protected void onCreate (Bundle saveInstanceState) { super.onCreate(saveInstanceState); setContentView(R.layout.activity_main); // Инициализируем представления dragLeftButton = findViewById(R.id.dragLeft); dragRightButton = findViewById(R.id.dragRight); BatteryIcon = findViewById(R.id.batteryIcon); bluetoothButton = findViewById(R.id.bluetoothButton); // Инициализируем Bluetooth инициализироватьBluetooth(); // Устанавливаем onTouchListener для кнопки dragRightButton dragRightButton.setOnTouchListener(новый View.OnTouchListener() { @Override public boolean onTouch(View v, событие MotionEvent) { int action = event.getAction(); переключатель (действие) { случай MotionEvent.ACTION_DOWN: // Верхняя часть креста - Увеличить шаг if (event.getY() < (float) v.getHeight() / 2) { шаг += 10; // Увеличиваем высоту звука если (шаг > 100) шаг = 100; } // Нижняя часть креста - Уменьшить шаг еще { шаг -= 10; // Уменьшить высоту если (шаг < 0) шаг = 0; } // Левая часть креста - Направьте силу вправо (рыскание вправо) if (event.getX() < (float) v.getWidth() / 2) { рыскание -= 10; // Отклонение вправо если (рыскание < -100) отклонение = -100; } // Правая часть креста — отправьте мощность влево (рыскание влево) еще { рыскание += 10; // Отклонение влево если (рыскание > 100) рыскание = 100; } // Обновляем управление самолетом на основе новых значений updateAirplaneControl (дроссельная заслонка, крен кузова, рыскание, шаг); перерыв; случай MotionEvent.ACTION_UP: // Прекратим применение тангажа и рыскания, когда кнопка будет отпущена шаг = 0; рыскание = 0; updateAirplaneControl (дроссельная заслонка, крен кузова, рыскание, шаг); перерыв; } вернуть истину; } }); // Регистрирует BroadcastReceiver для отслеживания изменений уровня заряда батареи зарегистрироватьBatteryLevelReceiver(); // Устанавливаем onClickListener для кнопки Bluetooth bluetoothButton.setOnClickListener(новый View.OnClickListener() { @Override общественная недействительность onClick (Просмотр v) { // Здесь реализуем обнаружение, сопряжение и подключение устройств Bluetooth обнаружитьУстройстваBluetooth(); } }); } частная пустота initBluetooth () { bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); если (bluetoothAdapter == null) { // Устройство не поддерживает Bluetooth // Обработка этого случая возвращаться; } если (!bluetoothAdapter.isEnabled()) { // Bluetooth не включен, попросите пользователя включить его Намерение EnableBtIntent = новое намерение (BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); возвращаться; } } частная пустота DiscoverBluetoothDevices () { // Проверяем, поддерживается ли Bluetooth и предоставлено ли необходимое разрешение int PermissionCheck = ContextCompat.checkSelfPermission(this, Манифест.разрешение.BLUETOOTH); если (permissionCheck!= PackageManager.PERMISSION_GRANTED) { // Разрешение Bluetooth не предоставлено, запросите его ActivityCompat.requestPermissions(это, новая строка[]{Manifest.permission.BLUETOOTH}, REQUEST_PERMISSION_BLUETOOTH); возвращаться; } // Проверяем, доступен ли и включен ли Bluetooth if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) { System.out.println("Bluetooth недоступен или не включен."); возвращаться; } // Начать обнаружение устройства если (bluetoothAdapter.startDiscovery()) { // Регистрируем BroadcastReceiver для обнаружения Фильтр IntentFilter = новый IntentFilter(BluetoothDevice.ACTION_FOUND); RegisterReceiver (новый BroadcastReceiver () { @Override public void onReceive (контекст контекста, намерение намерения) { Строковое действие = намерение.getAction(); если (BluetoothDevice.ACTION_FOUND.equals(действие)) { Устройство BluetoothDevice = Intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // Обработка обнаруженного устройства System.out.println("Обнаружено устройство: " + device.getName() + " (" + device.getAddress() + ")"); } } }, фильтр); } еще { System.out.println("Не удалось начать обнаружение устройства Bluetooth."); } } @Override public void onRequestPermissionsResult(int requestCode, разрешения @NonNull String[], @NonNull int[]grantResults) { super.onRequestPermissionsResult(requestCode, разрешения, GrantResults); если (requestCode == REQUEST_PERMISSION_BLUETOOTH) { if (grantResults.length > 0 && GrantResults[0] == PackageManager.PERMISSION_GRANTED) { // Разрешение предоставлено, инициализируем Bluetooth инициализироватьBluetooth(); } еще { // Разрешение отклонено, обработать соответствующим образом (например, показать сообщение) } } } Private void updateAirplaneControl(int throttle, int bodyRoll, int yaw, int Pitch) { System.out.println("Дроссельная заслонка: " + дроссельная заслонка + "%"); System.out.println("Body Roll: " + bodyRoll + "%"); System.out.println("Отклонение: " + отклонение + "%"); System.out.println("Шаг: " + шаг + «%»); } частный недействительный регистрBatteryLevelReceiver () { Фильтр IntentFilter = новый IntentFilter(Intent.ACTION_BATTERY_CHANGED); BroadcastReceiver BatteryLevelReceiver = новый BroadcastReceiver() { @Override public void onReceive (контекст контекста, намерение намерения) { int level = Intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); int Scale = Intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); int BatteryLevel = (int) ((шкала уровня / (float)) * 100); updateBatteryIcon (уровень батареи); } }; RegisterReceiver (batteryLevelReceiver, фильтр); } частный недействительный updateBatteryIcon (int BatteryLevel) { если (уровень батареи >= 90) { BatteryIcon.setImageResource(R.drawable.ic_battery_full); } else if (batteryLevel >= 50) { BatteryIcon.setImageResource(R.drawable.ic_battery_50); } else if (batteryLevel >= 20) { BatteryIcon.setImageResource(R.drawable.ic_battery_20); } еще { BatteryIcon.setImageResource(R.drawable.ic_battery_dead); } } } а вот мой AndroidManifest.xml
Я поигрался с этим, я уже добавил разрешения в свой XML-файл и импортировал их в свой Java-файл. Но что бы я ни делал, я постоянно получаю сообщение «Вызов требует разрешения», которое может быть отклонено пользователем: код должен явно проверять, доступно ли разрешение (с помощью checkPermission), или явно обрабатывать потенциальное исключение SecurityException. и Call требуют разрешения, которое может быть отклонено пользователем: код должен явно проверять, доступно ли разрешение (с помощью checkPermission), или явно обрабатывать потенциальное исключение SecurityException. Как уже говорилось ранее, приложение работает как должно, но при нажатии кнопки Bluetooth приложение полностью аварийно завершает работу.
Чтобы рассказать предысторию, я создаю приложение для Android в студии Android, используя Java. Это приложение служит цифровым радиоуправляемым контроллером для радиоуправляемого самолета. Моя цель — иметь возможность подключаться к самолету через Bluetooth и управлять самолетом с моего телефона Android. Я долгое время работал со студией Android и Java, но никогда раньше не работал с соединениями/разрешениями Bluetooth. Я запускаю приложение и работаю, но у меня работает Bluetooth с перебоями. У меня уже создана кнопка с надписью Bluetooth, но сейчас она ничего не делает. Я пытался сделать так, чтобы при нажатии кнопки Bluetooth появлялось меню с Bluetooth, доступными для подключения, однако при этом приложение просто вылетало. Ниже приведен мой код MainActivity.Java и мой AndroidManifest.xml
пакет com.example.rcair; импортировать android.Manifest; импортировать android.bluetooth.BluetoothAdapter; импортировать android.bluetooth.BluetoothDevice; импортировать android.bluetooth.BluetoothSocket; импортировать android.content.BroadcastReceiver; импортировать android.content.Context; импортировать android.content.Intent; импортировать android.content.IntentFilter; импортировать android.content.pm.PackageManager; импортировать android.os.BatteryManager; импортировать android.os.Bundle; импортировать android.view.MotionEvent; импортировать android.view.View; импортировать android.widget.Button; импортировать android.widget.ImageView; импортировать androidx.annotation.NonNull; импортировать androidx.appcompat.app.AppCompatActivity; импортировать androidx.core.app.ActivityCompat; импортировать androidx.core.content.ContextCompat; импортировать java.io.IOException; публичный класс MainActivity расширяет AppCompatActivity { частная кнопка dragLeftButton; частная кнопка dragRightButton; частный ImageView BatteryIcon; частная кнопка BluetoothButton; частный int дроссель = 0; частный int bodyRoll = 0; частный int рыскание = 0; частный int шаг = 0; // Переменные Bluetooth частный Bluetooth-адаптер Bluetooth-адаптер; частный BluetoothSocket bluetoothSocket; частный BluetoothDevice bluetoothDevice; частный статический финал int REQUEST_ENABLE_BT = 1; частный статический финал int REQUEST_PERMISSION_BLUETOOTH = 2; @Override protected void onCreate (Bundle saveInstanceState) { super.onCreate(saveInstanceState); setContentView(R.layout.activity_main); // Инициализируем представления dragLeftButton = findViewById(R.id.dragLeft); dragRightButton = findViewById(R.id.dragRight); BatteryIcon = findViewById(R.id.batteryIcon); bluetoothButton = findViewById(R.id.bluetoothButton); // Инициализируем Bluetooth инициализироватьBluetooth(); // Устанавливаем onTouchListener для кнопки dragRightButton dragRightButton.setOnTouchListener(новый View.OnTouchListener() { @Override public boolean onTouch(View v, событие MotionEvent) { int action = event.getAction(); переключатель (действие) { случай MotionEvent.ACTION_DOWN: // Верхняя часть креста - Увеличить шаг if (event.getY() < (float) v.getHeight() / 2) { шаг += 10; // Увеличиваем высоту звука если (шаг > 100) шаг = 100; } // Нижняя часть креста - Уменьшить шаг еще { шаг -= 10; // Уменьшить высоту если (шаг < 0) шаг = 0; } // Левая часть креста - Направьте силу вправо (рыскание вправо) if (event.getX() < (float) v.getWidth() / 2) { рыскание -= 10; // Отклонение вправо если (рыскание < -100) отклонение = -100; } // Правая часть креста — отправьте мощность влево (рыскание влево) еще { рыскание += 10; // Отклонение влево если (рыскание > 100) рыскание = 100; } // Обновляем управление самолетом на основе новых значений updateAirplaneControl (дроссельная заслонка, крен кузова, рыскание, шаг); перерыв; случай MotionEvent.ACTION_UP: // Прекратим применение тангажа и рыскания, когда кнопка будет отпущена шаг = 0; рыскание = 0; updateAirplaneControl (дроссельная заслонка, крен кузова, рыскание, шаг); перерыв; } вернуть истину; } }); // Регистрирует BroadcastReceiver для отслеживания изменений уровня заряда батареи зарегистрироватьBatteryLevelReceiver(); // Устанавливаем onClickListener для кнопки Bluetooth bluetoothButton.setOnClickListener(новый View.OnClickListener() { @Override общественная недействительность onClick (Просмотр v) { // Здесь реализуем обнаружение, сопряжение и подключение устройств Bluetooth обнаружитьУстройстваBluetooth(); } }); } частная пустота initBluetooth () { bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); если (bluetoothAdapter == null) { // Устройство не поддерживает Bluetooth // Обработка этого случая возвращаться; } если (!bluetoothAdapter.isEnabled()) { // Bluetooth не включен, попросите пользователя включить его Намерение EnableBtIntent = новое намерение (BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); возвращаться; } } частная пустота DiscoverBluetoothDevices () { // Проверяем, поддерживается ли Bluetooth и предоставлено ли необходимое разрешение int PermissionCheck = ContextCompat.checkSelfPermission(this, Манифест.разрешение.BLUETOOTH); если (permissionCheck!= PackageManager.PERMISSION_GRANTED) { // Разрешение Bluetooth не предоставлено, запросите его ActivityCompat.requestPermissions(это, новая строка[]{Manifest.permission.BLUETOOTH}, REQUEST_PERMISSION_BLUETOOTH); возвращаться; } // Проверяем, доступен ли и включен ли Bluetooth if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) { System.out.println("Bluetooth недоступен или не включен."); возвращаться; } // Начать обнаружение устройства если (bluetoothAdapter.startDiscovery()) { // Регистрируем BroadcastReceiver для обнаружения Фильтр IntentFilter = новый IntentFilter(BluetoothDevice.ACTION_FOUND); RegisterReceiver (новый BroadcastReceiver () { @Override public void onReceive (контекст контекста, намерение намерения) { Строковое действие = намерение.getAction(); если (BluetoothDevice.ACTION_FOUND.equals(действие)) { Устройство BluetoothDevice = Intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // Обработка обнаруженного устройства System.out.println("Обнаружено устройство: " + device.getName() + " (" + device.getAddress() + ")"); } } }, фильтр); } еще { System.out.println("Не удалось начать обнаружение устройства Bluetooth."); } } @Override public void onRequestPermissionsResult(int requestCode, разрешения @NonNull String[], @NonNull int[]grantResults) { super.onRequestPermissionsResult(requestCode, разрешения, GrantResults); если (requestCode == REQUEST_PERMISSION_BLUETOOTH) { if (grantResults.length > 0 && GrantResults[0] == PackageManager.PERMISSION_GRANTED) { // Разрешение предоставлено, инициализируем Bluetooth инициализироватьBluetooth(); } еще { // Разрешение отклонено, обработать соответствующим образом (например, показать сообщение) } } } Private void updateAirplaneControl(int throttle, int bodyRoll, int yaw, int Pitch) { System.out.println("Дроссельная заслонка: " + дроссельная заслонка + "%"); System.out.println("Body Roll: " + bodyRoll + "%"); System.out.println("Отклонение: " + отклонение + "%"); System.out.println("Шаг: " + шаг + «%»); } частный недействительный регистрBatteryLevelReceiver () { Фильтр IntentFilter = новый IntentFilter(Intent.ACTION_BATTERY_CHANGED); BroadcastReceiver BatteryLevelReceiver = новый BroadcastReceiver() { @Override public void onReceive (контекст контекста, намерение намерения) { int level = Intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); int Scale = Intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); int BatteryLevel = (int) ((шкала уровня / (float)) * 100); updateBatteryIcon (уровень батареи); } }; RegisterReceiver (batteryLevelReceiver, фильтр); } частный недействительный updateBatteryIcon (int BatteryLevel) { если (уровень батареи >= 90) { BatteryIcon.setImageResource(R.drawable.ic_battery_full); } else if (batteryLevel >= 50) { BatteryIcon.setImageResource(R.drawable.ic_battery_50); } else if (batteryLevel >= 20) { BatteryIcon.setImageResource(R.drawable.ic_battery_20); } еще { BatteryIcon.setImageResource(R.drawable.ic_battery_dead); } } } а вот мой AndroidManifest.xml
Я поигрался с этим, я уже добавил разрешения в свой XML-файл и импортировал их в свой Java-файл. Но что бы я ни делал, я постоянно получаю сообщение «Вызов требует разрешения», которое может быть отклонено пользователем: код должен явно проверять, доступно ли разрешение (с помощью checkPermission), или явно обрабатывать потенциальное исключение SecurityException. и Call требуют разрешения, которое может быть отклонено пользователем: код должен явно проверять, доступно ли разрешение (с помощью checkPermission), или явно обрабатывать потенциальное исключение SecurityException. Как уже говорилось ранее, приложение работает как должно, но при нажатии кнопки Bluetooth приложение полностью аварийно завершает работу.
Мобильная версия