Чтобы разработать приложение для Android, использующее передачу данных через Bluetooth (BT), можно логически начать со страницы Bluetooth разработчика Android, где подробно описаны все необходимые шаги: обнаружение устройства, сопряжение, сокеты клиент / сервер, каналы RFCOMM, и т.п.
Но прежде чем переходить к программированию сокетов и потоков только для выполнения базовой операции BT, давайте рассмотрим более простую альтернативу, основанную на одной из самых важных функций Android: возможность для одного приложения отправлять пользователя другому, что в данном случае , будет приложение BT устройства по умолчанию. При этом сама ОС Android сделает всю работу на низком уровне за нас.
Перво-наперво, немного защитного программирования:
|
01
02
03
04
05
06
07
08
09
10
|
import android.bluetooth.BluetoothAdapter;//...// inside method// Check if bluetooth is supportedBluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();if (btAdapter == null) { // Device does not support Bluetooth // Inform user that we're done. } |
Выше приведена первая проверка, которую нам нужно выполнить. Сделав это, давайте посмотрим, как он может запустить BT из нашего собственного приложения.
В предыдущем посте о программировании SMS мы говорили о неявных намерениях , которые в основном позволяют нам указать действие, которое мы хотели бы, чтобы система выполняла для нас. Android отобразит все действия, которые могут выполнить требуемое действие, в списке выбора . Вот пример:
|
1
2
3
4
5
6
7
|
// bring up Android chooserIntent intent = new Intent();intent.setAction(Intent.ACTION_SEND);intent.setType("text/plain");intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file_to_transfer) );//...startActivity(intent); |
В приведенном выше фрагменте кода мы сообщаем системе Android, что намереваемся отправить текстовый файл. Затем система отображает все установленные приложения, способные выполнить это действие:
Мы видим, что приложение BT входит в число этих обработчиков. Конечно, мы можем позволить пользователю выбрать это приложение из списка и покончить с ним. Но если мы чувствуем, что должны быть немного более удобными для пользователя, нам нужно пойти дальше и запустить приложение самостоятельно, а не просто отображать его в окружении других ненужных опций … Но как?
Один из способов сделать это — использовать PackageManager для Android следующим образом:
|
1
2
3
4
5
6
7
|
//list of apps that can handle our intentPackageManager pm = getPackageManager();List appsList = pm.queryIntentActivities( intent, 0);if(appsList.size() > 0 { // proceed} |
Приведенный выше метод PackageManager возвращает список всех ранее обнаруженных нами действий, которые могут обрабатывать наше намерение передачи файла, в виде списка объектов ResolveInfo, которые инкапсулируют необходимую нам информацию:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
//select bluetoothString packageName = null;String className = null;boolean found = false;for(ResolveInfo info: appsList){ packageName = info.activityInfo.packageName; if( packageName.equals("com.android.bluetooth")){ className = info.activityInfo.name; found = true; break;// found }}if(! found){ Toast.makeText(this, R.string.blu_notfound_inlist, Toast.LENGTH_SHORT).show(); // exit} |
Теперь у нас есть необходимая информация для запуска BT:
|
1
2
3
|
//set our intent to launch Bluetoothintent.setClassName(packageName, className);startActivity(intent); |
Мы использовали пакет и соответствующий ему класс, полученный ранее. Поскольку мы любопытная группа, мы можем задаться вопросом, как называется класс для пакета «com.android.bluetooth». Вот что мы получили бы, если бы распечатали: com.broadcom.bt.app.opp.OppLauncherActivity OPP означает Object Push Profile и является компонентом Android, позволяющим обмениваться файлами по беспроводной сети.
Все в порядке, но для того, чтобы весь приведенный выше код был полезен, BT не просто должен поддерживаться устройством, но и включаться пользователем. Поэтому первое, что мы хотим сделать, это попросить пользователя включить BT на время, которое мы считаем необходимым (здесь, 300 секунд):
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
|
import android.bluetooth.BluetoothAdapter;//...// duration that the device is discoverableprivate static final int DISCOVER_DURATION = 300;// our request code (must be greater than zero)private static final int REQUEST_BLU = 1;//...public void enableBlu(){// enable device discovery - this will automatically enable BluetoothIntent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);discoveryIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISCOVER_DURATION );startActivityForResult(discoveryIntent, REQUEST_BLU);} |
Как только мы укажем, что хотим получить результат от нашей деятельности с помощью startActivityForResult , пользователю предоставляется следующий включающий диалог:
Теперь, когда действие заканчивается, оно возвращает код запроса, который мы отправили (REQUEST_BLU), вместе с данными и кодом результата нашей основной деятельности через метод обратного вызова onActivityResult . Мы знаем, какой код запроса мы должны проверить, но как насчет кода результата ? Просто: если пользователь отвечает «Нет» на вышеуказанный запрос на разрешение (или если возникает ошибка), код результата будет RESULT_CANCELED. С другой стороны, если пользователь принимает, в документации BT указывается, что код результата будет равен продолжительности обнаружения устройства (т. Е. DISCOVER_DURATION, т. Е. 300).
Таким образом, способ обработки диалогового окна BT выше будет:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
// When startActivityForResult completes...protected void onActivityResult (int requestCode, int resultCode, Intent data) { if (resultCode == DISCOVER_DURATION && requestCode == REQUEST_BLU) { // processing code goes here } else{ // cancelled or error Toast.makeText(this, R.string.blu_cancelled, Toast.LENGTH_SHORT).show(); }}Putting all our processing flow in order, here’s what we are basically doing: |
Мы уже закончили? Почти. И последнее, но не менее важное: нам нужно запросить разрешения BT в манифесте Android:
|
1
2
|
<uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> |
Мы готовы развернуть сейчас. Чтобы проверить все это, нам нужно использовать как минимум два устройства Android, одно из которых является отправителем файла (где установлено наше приложение), а другое — любым принимающим устройством, поддерживающим BT. Вот скриншоты. Для отправителя:
И соответствующее приемное устройство:

Обратите внимание, что как только получатель примет соединение. полученный файл ( kmemo.dat ) сохраняется в папке BT на SD-карте. Вся передача данных нижнего уровня была обработана ОС Android.



