Дистанционное управление Android устройствами с помощью Bluetooth | 4Tablet-PC

Дистанционное управление Android устройствами с помощью Bluetooth | 4Tablet-PC Вертолеты

Основная активность, сопряжение arduino и android

Наследуем класс от AppCompatActivity и объявляем переменные:

public class MainActivity extends AppCompatActivity {
        private BluetoothAdapter bluetoothAdapter;
        private ListView listView;
        private ArrayList<String> pairedDeviceArrayList;
        private ArrayAdapter<String> pairedDeviceAdapter;
        public static BluetoothSocket clientSocket;
        private Button buttonStartControl;
}

Метод onCreate() опишу построчно:

@Override
protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState); //обязательная строчка
     //прикрепляем ранее созданную разметку
     setContentView(R.layout.activity_main); 
     //цепляем кнопку из разметки          
     Button buttonStartFind = (Button) findViewById(R.id.button_start_find); 
     //цепляем layout, в котором будут отображаться найденные устройства
     listView = (ListView) findViewById(R.id.list_device); 
      
     //устанавливаем действие на клик                                                                           
     buttonStartFind.setOnClickListener(new View.OnClickListener() { 
                                                                                                    
         @Override
         public void onClick(View v) {
             //если разрешения получены (функция ниже)
             if(permissionGranted()) { 
               //адаптер для управления блютузом
                bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
                if(bluetoothEnabled()) { //если блютуз включен (функция ниже)
                    findArduino(); //начать поиск устройства (функция ниже)
                  }
              }
         }
    });

     //цепляем кнопку для перехода к управлению
     buttonStartControl = (Button) findViewById(R.id.button_start_control); 
     buttonStartControl.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
                //объект для запуска новых активностей
                Intent intent = new Intent(); 
                //связываем с активностью управления
                intent.setClass(getApplicationContext(), ActivityControl.class);
                //закрыть эту активность, открыть экран управления
                startActivity(intent); 
         }
     });

 }

Нижеприведенные функции проверяют, получено ли разрешение на использование блютуза (без разрешение пользователя мы не сможем передавать данные) и включен ли блютуз:

Mobilego (бесплатно)

MobileGo - удаленное управление android
Программу MobileGo скачали более миллиона раз, почти 40 тысяч пользователей поставили ей оценки, средняя из которых 4,4 балла. Приложение позволяет синхронизировать работу смартфона и ПК с помощью кабеля, или с помощью беспроводного соединения. С его помощью станет возможно:

  • Управлять телефонной книжкой и звонками с помощью компьютера.
  • Переносить любые файлы с памяти смартфона и память настольного ПК.
  • Управлять сообщениями любых приложений, предполагающих переписку пользователей, а также СМС.
  • Конвертировать видео-файлы на ПК с возможностью просматривать их на мобильном устройстве.
  • Создавать резервное копирование данных при каждом соединении, восстановление резерва в один клик.
  • Очищать оперативную память смартфона.
  • Перенос приложений из системной памяти в память карты памяти, и обратно.
  • Управлять приложениями.
Смотрите про коптеры:  Робот пылесос алиса умный дом

Для того, чтоб все это осуществить, необходимо установить приложение MobileGo на компьютер и на мобильное устройство. Для синхронизации через wi-fi нужно отсканировать QR-код на экране монитора и запустить найденное приложение в смартфоне. Если использовать провод – программа запустится, и при каждом соединении будет создавать резервные копии, которые легко можно восстановить при необходимости.

MobileGo - удаленное управление android
Мобильная версия этого приложения также позволяет переносить и копировать файлы внутри смартфона, загружать программы, видеоролики, управлять памятью устройства.

Включение bluetooth из приложения

Современные Android смартфоны не могут похвастаться долгим временем работы, поэтому все нормальные люди отключают Bluetooth модуль. Если Вы припрограммровании для Android хотите дать своим пользователям возможность сделать телефон видимым для других телефонов, вызовите с помощью метода startActivityForResult(Intent, int)

интент ACTION_REQUEST_DISCOVERABLE. В результате пользователю будет показано системное окно с запросом на перевод телефона в режим bluetooth видимости. По умолчанию этот режим включается на 120 секунд. Это время можно изменить с передав интенту дополнительный параметр EXTRA_DISCOVERABLE_DURATION.

Intent discoverableIntent=new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);
startActivity(discoverableIntent);

В результате выполнения этого кода пользователю будет показан диалог с запросом. Если пользователь согласится, телефон будет переведен в режим видимости, и будет вызван callback метод onActivityResult() . В качестве результата методу будет передано число секунд, которое устройство будет видимым.

Если вы хотите получить уведомления, при изменении режима видимости Вашего устройства, зарегистрируйте BroadcastReceiver для интента ACTION_SCAN_MODE_CHANGED. Дополнительные поля EXTRA_SCAN_MODE и EXTRA_PREVIOUS_SCAN_MODE позволяют получить информацию о новом и старом состоянии соответственно.

Они могут принимать значения SCAN_MODE_CONNECTABLE_DISCOVERABLE, SCAN_MODE_CONNECTABLE или SCAN_MODE_NONE. Первое значение указывает на то, что устройство доступно для поиска. Второе – устройство не доступно для поиска, но способно принимать соединения. Третье – не доступно для поиска и не может принимать соединения.

Вам не нужно переводить свой телефон в режим видимости, если вы инициализируете соединение. Видимым должно быть устройство к которому вы хотите подключиться.

Дистанционное управление android устройствами с помощью bluetooth | 4tablet-pc

У вас есть Android планшет или смартфон с HDMI выходом, и вы знаете, что с его помощью можно смотреть фильмы на большом экране телевизора или монитора. Но это очень неудобно – скажете вы. То ли дело медиаплеер: расположился на диване, взял в руки дистанционку, и смотри все что хочешь в свое удовольствие.

Программы для планшетовОднако, если у вас в хозяйстве есть еще одно Android устройство, вам теперь не нужен медиаплеер. С помощью бесплатного приложения Tablet Remote вы можете превратить его в пульт управления любым Android планшетом или телефоном. Достаточно просто установить на оба устройства программу и настроить ее.

Программа Tablet Remote позволит вам управлять воспроизведением видео и музыки, регулировать яркость изображения и громкость звука, отправлять такие команды, как «Воспроизведение», «Пауза», «Перемотка» и переключать треки. Кроме того, вы можете подавать системные команды «Назад», «Меню», «Домой» и «Поиск» и даже вводить текст на другом устройстве с помощью экранной клавиатуры.
Мало того, вам даже не потребуются root права ни на одном из устройств.

Программы для планшетов

Для того, чтобы настроить программу, вам нужно запустить ее на обеих устройствах, включить на них Bluetooth и подключить их друг к другу. Для этого вы должны выбрать «Connection» -> «Scan Devices», и после того, как устройство будет обнаружено, нажать «Make Device Discoverable», чтобы оно появилось в списке. По умолчанию Bluetooth активируется на 120 секунд (2 минуты), поэтому не забудьте убрать это ограничение в разделе “Настройки” -> “Беспроводные сети” -> “Bluetooth” настроек вашего устройства.

Теперь нам нужно на устройстве, которым мы хотим управлять зайти в настройки программы, нажав кнопку «Setup» и включить обе опции: «Enable Tablet Remote» и «Change The Input method For Tablet Remote»

Программы для планшетов

Все, с настройками покончено. Теперь, когда ваши устройства подключены друг к другу, просто нажмите на устройстве, которое будет выступать в качестве пульта управления кнопку «Remote», и на нем откроется окно с имитацией пульта управления, которым вы и будете посылать команды на второе устройство.

Чтобы включить полноэкранный режим, включите опцию «Hide Status bar» в разделе настроек «Settings» приложения.
Приложение Tablet Remote прекрасно работает как на телефонах, так и на планшетах, и когда мы пробовали управлять HTC Desire Z, он принимал команды от другого смартфона, даже в режиме ожидания (когда его экран был погашен).

Скачать бесплатно программу Tablet Remote можно в Android Market:


Похожие материалы:

Управляем закачкой торрентов с помощью Android телефона или планшета

Программы для Андроид. Samsung Smart View портирован на все Android устройства! (Скачать)

Приложение Smart View App для Samsung Galaxy S II позволяет передавать видео с телевизора на экран смартфона.

Mobile Mouse Lite. Удобный пульт ДУ для компьютера из Android телефона или планшета

Motorola Corvair. Новый компактный планшет или просто умная дистанционка?

Клиент

Для инициализации соединения с удаленным устройствам (устройством, которое держит открытым серверный сокет) вам необходимо получить объект BluetoothDevice, содержащий информацию о нем. Этот объект используется для получения BluetoothSocket и инициализации соединения.

Опишем процедуру соединения:

  1. Получим BluetoothSocket вызвав метод  BluetoothDevice.createRfcommSocketToServiceRecord(UUID). Значение параметра UUID должно совпадать с значением, указанным при вызове listenUsingRfcommWithServiceRecord сервера.
  2. Инициализируем соединение, вызвав метод connect().  После вызова этого метода система будет выполнять SDP поиск на удаленном устройстве, чтобы сопоставить  UUID. В случае успеха при условии подтверждения запроса со стороны сервера будет открыт RFCOMM канал. Это блокирующий вызов. Если по каким-то причинам соединение сорвется или выйдет timeout (около 12 секунд), будет сгенерировано исключение.

Как и в случае с accept, метод connect() следует выполнять в отдельном потоке, в противном случае может произойти подвисание интерфейса.

Замечание. Прежде чем вызывать connect() убедитесь, что в данный момент не происходит сканирование с целью поиска доступных устройств. В случае одновременного выполнения этих операций соединение будет устанавливаться намного медленнее, и вы рискуете не уложиться в timeout.

Приведем пример клиентского приложения, инициализирующего соединение

privateclass ConnectThreadextends Thread{private final BluetoothSocket mmSocket;private final BluetoothDevice mmDevice;
 
public ConnectThread(BluetoothDevice device){// используем вспомогательную переменную, которую в дальнейшем// свяжем с mmSocket,
BluetoothSocket tmp=null;
mmDevice= device;
 
// получаем BluetoothSocket чтобы соединиться с BluetoothDevice
try{// MY_UUID это UUID, который используется и в сервере
tmp= device.createRfcommSocketToServiceRecord(MY_UUID);} catch(IOException e){}
mmSocket= tmp;}
 
public void run(){// Отменяем сканирование, поскольку оно тормозит соединение
mBluetoothAdapter.cancelDiscovery();
 
try{// Соединяемся с устройством через сокет.// Метод блокирует выполнение программы до// установки соединения или возникновения ошибки
mmSocket.connect();} catch(IOException connectException){// Невозможно соединиться. Закрываем сокет и выходим.
try{
mmSocket.close();} catch(IOException closeException){}return;}
 
// управлчем соединением (в отдельном потоке)
manageConnectedSocket(mmSocket);}
 
/** отмена ожидания сокета */public void cancel(){
try{
mmSocket.close();} catch(IOException e){}}}

Для остановки сканирования эфира вызывается метод cancelDiscovery(). Перед вызовом этого метода можно проверить идет ли сканирование с помощью isDiscovering().

После завершения работы с BluetoothSocket всегда вызывайте метод close(). Это поможет сэкономить ресурсы телефона.

Метод loop() и дополнительные функции


В постоянно повторяющемся методе loop() происходит считывание данных. Сначала рассмотрим основной алгоритм, а потом функции, задействованные в нем.


void loop() {
  //если хоть несчитанные байты
  if(BTSerial.available() > 0) {
     //считываем последний несчитанный байт
     char a = BTSerial.read();
     
    if (a == '@') {
      //если он равен @ (случайно выбранный мною символ)
      //обнуляем переменную val
      val = "";
      //указываем, что сейчас считаем скорость
      readSpeed = true;

    } else if (readSpeed) {
      //если пора считывать скорость и байт не равен решетке
      //добавляем байт к val
      if(a == '#') {
        //если байт равен решетке, данные о скорости кончились
        //выводим в монитор порта для отладки
        Serial.println(val);
        //указываем, что скорость больше не считываем
        readSpeed = false;
        //передаем полученную скорость в функцию езды 
        go(val.toInt());
        //обнуляем val
        val = "";
        //выходим из цикла, чтобы считать следующий байт
        return;
      }
      val =a;
    } else if (a == '*') {
      //начинаем считывать угол поворота
      readAngle = true; 
    } else if (readAngle) {
      //если решетка, то заканчиваем считывать угол
      //пока не решетка, добавляем значение к val
      if(a == '#') {
       Serial.println(val);
       Serial.println("-----");
        readAngle = false;
        //передаем значение в функцию поворота
        turn(val.toInt());
        val= "";
        return;
      }
      val =a;
    }
    //получаем время последнего приема данных
    lastTakeInformation = millis();
  } else {
     //если несчитанных байтов нет, и их не было больше 150 миллисекунд 
     //глушим двигатели
     if(millis() - lastTakeInformation > 150) {
     lastTakeInformation = 0;
     analogWrite(angleSpeed, 0);
     analogWrite(speedRight, 0);
     analogWrite(speedLeft, 0);
     }
     
  }
}

Получаем результат: с телефона отправляем байты в стиле “@скорость#угол#” (например, типичная команда “@200#60#”. Данный цикл повторяется каждый 100 миллисекунд, так как на андроиде мы установили именно этот промежуток отправки команд. Короче делать нет смысла, так как они начнут становится в очередь, а если сделать длиннее, то колеса начнут двигаться рывками.

Все задержки через команду delay(), которые вы увидите далее, подобраны не через физико-математические вычисления, а опытным путем. Благодаря всем выставленным задрежам, машинка едет плавно, и у всех команд есть время на отработку (токи успевают пробежаться).

В цикле используются две побочные функции, они принимают полученные данные и заставляют машинку ехать и крутится.

void go(int mySpeed) {
  //если скорость больше 0
  if(mySpeed > 0) {
  //едем вперед
  digitalWrite(dirRight, HIGH);
  analogWrite(speedRight, mySpeed);
  digitalWrite(dirLeft, HIGH);
  analogWrite(speedLeft, mySpeed);
  } else {
    //а если меньше 0, то назад
    digitalWrite(dirRight, LOW);
    analogWrite(speedRight, abs(mySpeed)   30);
    digitalWrite(dirLeft, LOW);
     analogWrite(speedLeft, abs(mySpeed)   30);
  }
  delay(10);
 
}

void turn(int angle) {
  //подаем ток на плюс определителя угла
  digitalWrite(pinAngleStop, HIGH);
  //даем задержку, чтобы ток успел установиться
  delay(5);
  
  //если угол 150 и больше, поворачиваем вправо 
  //если 30 и меньше, то влево 
  //промежуток от 31 до 149 оставляем для движения прямо
  if(angle > 149) {
        //если замкнут белый, но разомкнуты  черный и красный
        //значит достигнуто крайнее положение, дальше крутить нельзя
        //выходим из функции через return 
        if( digitalRead(pinWhite) == HIGH && digitalRead(pinBlack) == LOW && digitalRead(pinRed) == LOW) {
          return;
        }
        //если проверка на максимальный угол пройдена
        //крутим колеса
        digitalWrite(angleDirection, HIGH);
        analogWrite(angleSpeed, speedTurn);
  } else if (angle < 31) { 
        if(digitalRead(pinRed) == HIGH && digitalRead(pinBlack) == HIGH && digitalRead(pinWhite) == HIGH) {
          return;
        }
        digitalWrite(angleDirection, LOW);
        analogWrite(angleSpeed, speedTurn);
  }
  //убираем питание 
  digitalWrite(pinAngleStop, LOW);
  delay(5);
}

Поворачивать, когда андроид отправляет данные о том, что пользователь зажал угол 60, 90, 120, не стоит, иначе не сможете ехать прямо. Да, возможно сразу не стоило отправлять с андроида команду на поворот, если угол слишком мал, но это как-то коряво на мой взгляд.

Настройки bluetooth в режиме разработчика – пошаговая инструкция для смартфонов android

В этом режиме находится несколько функций, которые могут быть полезны.

  1. Показывать блютуз-устройства без названий. Эта функция говорит сама за себя. Если отключим названия устройств, то будем видеть только их MAC адреса.

    Дистанционное управление Android устройствами с помощью Bluetooth | 4Tablet-PC

  2. Версия блютуз AVRCP – управление различными устройствами (телевизор дом.кинотеатр и другие). Эта функция позволяет выбрать версию от 1.3 до 1.6.

    Дистанционное управление Android устройствами с помощью Bluetooth | 4Tablet-PC

  3. Запуск аудиокодека через блютуз. Позволяет выбрать определенный аудиокодек из списка.

    Дистанционное управление Android устройствами с помощью Bluetooth | 4Tablet-PC

  4. Выбор частоты дискретизации для передачи по блютуз.

    Дистанционное управление Android устройствами с помощью Bluetooth | 4Tablet-PC

  5. Выбрать глубину кодирования звука.

    Дистанционное управление Android устройствами с помощью Bluetooth | 4Tablet-PC

  6. Режим аудиоканала (моно или стерео)

    Дистанционное управление Android устройствами с помощью Bluetooth | 4Tablet-PC

  7. Выбор качества воспроизведения

    Дистанционное управление Android устройствами с помощью Bluetooth | 4Tablet-PC

  8. Максимально количество подключенных устройств.

    Дистанционное управление Android устройствами с помощью Bluetooth | 4Tablet-PC

Вот столько смартфон имеет настроек блютуз на Андроиде. Возможно, они будут дополняться и меняться с дальнейшими версиями ОС.

Обзор android bluetooth api

Bluetooth API располагается в пакетеandroid.bluetooth. В его состав входит несколько классов:

  • BluetoothAdapter– отвечает за работу с установленным в телефоне Bluetooth модулем. Экземпляр этого класса есть в любой программе, использующей bluetooth. В состав этого класса входят методы, позволяющие производить поиск доступных устройств, запрашивать список подключенных устройств, создавать экземпляр класса BluetoothDevice на основании известного MAC адреса и создавать BluetoothServerSocket для ожидания запроса на соединение от других устройств.
  • BluetoothDevice– класс, ассоциирующийся с удаленным Bluetooth устройством. Экземпляр этого класса используется для соединения через BluetoothSocket или для запроса информации об удаленном устройстве (имя, адресс, класс, состояние).
  • BluetoothSocket– интерфейс для Bluetooth socket, аналогичный TCP сокетам. Это точка соединения, позволяющая обмениваться данными с удаленным устройством через InputStream и OutputStream.
  • BluetoothServerSocket– представляет открытый сокет сервера, готовый к обработке входящего запроса. Для того чтобы соединить два Android устройства, одно из них должно открыть сокет с помощью этого класса. Когда удаленное устройство пошлет запрос на соединение, BluetoothServerSocket вернет объект BluetoothSocket.
  • BluetoothClass– описывает основные параметры Bluetooth модуля. Объект этого класса доступен только в режиме чтения и может быть полезен  при определении типа устройства.
  • BluetoothProfile– интерфейс, представляющий Bluetooth профиль (спецификацию беспроводного интерфейса для соединения устройств через Bluetooth). Примером профиля может служить Hands-Free profile, определяющий порядок работы с беспроводной гарнитурой.
  • BluetoothHeadset– обеспечивает поддержку bluetooth гарнитур. Включает в себя профили Bluetooth Headset и Hands-Free (v1.5).
  • BluetoothA2dp– Описывает Advanced Audio Distribution Profile, определяющий передачу потока высококачественных аудиоданных через bluetooth.
  • BluetoothHealth– определяет proxy для Health Device Profile.
  • BluetoothHealthCallback– абстрактный класс, который можно использовать для реализации обратных вызовов от BluetoothHealth. Для того чтобы регистрировать изменение состояния Bluetooth устройства нужно на основе этого класса создать собственный и переопределить в нем callback методы.
  • BluetoothHealthAppConfiguration– конфигурация, которая используется для соединения с различными медицинскими bluetooth устройствами.
  • BluetoothProfile.ServiceListener– интерфейс, который посылает уведомление BluetoothProfile IPC  клиентам при их подключении и отключении от сервиса.

В рамках этой статьи мы не будем углубляться в суть работы с медицинскими  bluetooth устройствами и сосредоточимся на первых четырех классах.

Ответы на вопросы читателей

Я не могу обновить программное обеспечение без Play Market. А Play Market говорит, что нужно обновить программное обеспечение.

Обновите версию Андроид либо переустановите Play Market через сайт apkmirror. Если не поможет, придется делать сброс настроек (hard reset).

Позавчера купили новый телефон (Samsung galaxy A50). После обновления ПО карта SD перестала читаться, в т.ч. на других телефонах.

На эту тему есть инструкция, как починить карту памяти . Скорее всего, обнаружены ошибки чтения и нужно отформатировать носитель в поддерживаемой файловой системе.

Когда будет доступно новое обновление Андроид?

У меня телефон Huawei U9500, и я не знала, что надо обновить версию. Сейчас у меня Андроид 4.0.3, как обновить прошивку до новой версии?

Процесс обновления прошивки Huawei описан здесь . Вкратце, есть два способа обновления прошивки Huawei U9500.

  1. Достаем аккумулятор, зажимаем кнопки громкости на телефоне. После этого начнется процесс обновления Андроид.
  2. Заходим в Настройки -> Память -> Обновление ПО -> Обновление SD-карты, запускаем обновление ОС Android.

Как обновить версию Андроид? Читала на разных сайтах, пробовала, не получается. У меня Android 4.4.4.

У меня Samsung Duos, версия Андроид 4.1.2 не могу обновить операционную систему до большей версии. Помогите, пожалуйста, обновить!

Для начала нужно узнать, можно ли обновить Андроид на вашем телефоне до версии 5.x. Оказывается, нет. Дело в том, что технические характеристики вашего телефона не позволяют вам устанавливать более новые версии Android.

Пытаюсь обновить версию 8 до самой новой. Пишет «Ошибка» и показывает вскрытого Андроида с висящим над ним красным треугольником с восклицательным знаком.

Приобрел НТС one m7. Не могу обновить Андроид 4.4.2. Аппарат не находит обновление ПО, как решить эту проблему? Как его обновить?

У меня Moto x play, обновлять систему не хочу, постоянно появляется сообщение «Доступно ПО android 6.0.1”, которое дико раздражает.

Для отключения обновлений прошивки, перейдите в настройки Android, раздел О телефоне – Обновление ПО и отключите обновления, сняв галочку напротив соответствующего пункта.

Полетела память на устройстве (телефон перестал включаться), ее заменили, но прошивку поставили не родную. Обновлений для нее нет. Можно ли мне через Kies откатить Андроид (поставить родную) и обновлять ее?

Планшет Acer Iconia A1-810. У меня нет обновлений прошивки. нажимаю обновление системы и пишет «для вашего устройства обновление требуется».

Не открывается номер сборки на Андроиде. Кликала долго. Как быть?

Передача данных

После успешного соединения, каждое из соединенных устройств имеет объект BluetoothSocket с помощью которого легко реализовать передачу/прием данных:

  1. С помощью методов getInputStream() и getOutputStream() полуить объекты InputStream и OutputStream, управляющие передачей через сокет.
  2. Читать и писать данные в поток с помощью методов read(byte[]) и write(byte[]).

Вы должны использовать отдельный поток для чтения и записи данных. Это важно, поскольку методы read(byte[]) и write(byte[]) являются блокирующими и их вызов в основном потоке может парализовать вашу программу. Главный цикл в этом отдельном потоке должен считывать данные из InputStream. Для записи в OutputStream имеет смысл создать отдельный public метод.

privateclass ConnectedThreadextends 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;
 
// Получить входящий и исходящий потоки данных
try{
tmpIn= socket.getInputStream();
tmpOut= socket.getOutputStream();} catch(IOException e){}
 
mmInStream= tmpIn;
mmOutStream= tmpOut;}
 
public void run(){
byte[] buffer=new byte[1024];// буферный массив
int bytes;// bytes returned from read()
 
// Прослушиваем InputStream пока не произойдет исключениеwhile(true){
try{// читаем из InputStream
bytes= mmInStream.read(buffer);// посылаем прочитанные байты главной деятельности
mHandler.obtainMessage(MESSAGE_READ, bytes,-1, buffer).sendToTarget();} catch(IOException e){break;}}}
 
/* Вызываем этот метод из главной деятельности, чтобы отправить данные
удаленному устройству */public void write(byte[] bytes){
try{
mmOutStream.write(bytes);} catch(IOException e){}}
 
/* Вызываем этот метод из главной деятельности,
чтобы разорвать соединение */public void cancel(){
try{
mmSocket.close();} catch(IOException e){}}

В конструкторе создаются объекты для работы с потоками данных, после чего поток оживает входящие данные. После того как прочитан очередной блок данных из входящего потока он посылается в главную деятельность посредствам вызова метода Handler родительского класса.

По для взаимодействия пк и смартфона

Способ 2. Поднять на устройстве FTP (SSH, SMB, HTTP, HTTPS, WebDAV, AFP) -сервер. Способ надёжный и простой, требует WiFi-соединения с компьютером. Поднять FTP-сервер на устройстве способны такие программы, как On Air (предлагает также взаимодействие по протоколам WebDAV и AFP), SwiFTP, также возможность встроена в программы File Expert и Remote Web Desktop.

On Air отличается простым интерфейсом и минимумом настроек. После старта сервера генерируется четырёхзначный цифровой пароль (при попытках брута сервер обваливается после n-го количества запросов, по всей видимости, встроенная мера предосторожности), отображается адрес сервера. Основные недостатки в том, что нельзя вручную задавать имя пользователя, пароль (можно только указать, что этот пароль всегда будет статичным), порт сервера, share-каталог. Достоинство — простота.

SwiFTP FTP Server наиболее полноценный FTP-сервер из тех, которые я перепробовал. Указывается имя пользователя, пароль, порт и даже share-каталог (только здесь нашёл такую опцию). Недостаток — отсутствие возможности шаринга в один клик (имеется ввиду, что нельзя создать на рабочем столе ярлык, при щелчке на который поднимался бы ftp-сервер), и сам интерфейс не располагает.

File Expert (мой выбор) — приложение, выступающее как файловый менеджер, но включающее в себя как FTP, так и WEB-сервер. Достаточно настроек, нельзя только указать share-каталог (всегда sdcard). Можно создать ярлык быстрого запуска FTP- или WEB-сервера.

Remote Web Desktop (Full-версия платная) выступает как многофункциональный WEB-сервер, дополнительно встроен и FTP-сервер. Большой недостаток — в бесплатной версии для FTP-сервера ограничена скорость — всего 100 kb/s (в среднем без ограничения ~2-4 Mb/s). Однако WEB-сервер обладает широким спектром возможностей. В платной версии возможно взаимодействие по протоколу HTTPS (нигде больше не видел такой возможности). Аналогов достаточно (обычно в названии содержат Web Desktop или что-то похожее), однако Remote Web Desktop наиболее функциональный, в бесплатной версии не так много ограничений.

Samba Filesharing (предложено belk) позволяет поднять на устройстве SMB-сервер. Наиболее актуально для пользователей Windows — устройство будет отображаться как общая сетевая папка. Нужен рут.

Платная QuickSSHd запускает SSH-сервер на смартфоне, на ПК остаётся воспользоваться каким-либо SCP/SFTP клиентом (Windows: WinSCP; Linux: OpenSSH; Mac: Cyberduck).

Поиск устройств

Для того, чтобы начать сканирование радиодиапазона на предмет наличия доступных устройств просто вызовите метод startDiscovery(). Сканирование происходит в отдельном асинхронном потоке. Метод возвращает true, если запуск сканирования прошел успешно. Обычно процесс сканирования занимает порядка 10-15 секунд.

Чтобы получить информацию о найденных устройствах Ваше приложение должно зарегистрировать BroadcastReceiver для интента ACTION_FOUND. Этот интент вызывается для каждого найденного устройства. Интент содержит дополнительные поля EXTRA_DEVICE и EXTRA_CLASS, которые содержат объекты BluetoothDevice и BluetoothClass соответственно.

// Создаем BroadcastReceiver для ACTION_FOUNDprivate final BroadcastReceiver mReceiver=new BroadcastReceiver(){public void onReceive(Context context, Intent intent){
String action= intent.getAction();// Когда найдено новое устройствоif(BluetoothDevice.ACTION_FOUND.equals(action)){// Получаем объект BluetoothDevice из интента
BluetoothDevice device= intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);//Добавляем имя и адрес в array adapter, чтобы показвать в ListView
mArrayAdapter.add(device.getName() "n"  device.getAddress());}}};// Регистрируем BroadcastReceiver
IntentFilter filter=new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);// Не забудьте снять регистрацию в onDestroy
 

Поиск Bluetooth устройств требует много ресурсов. Как только Вы нашли подходящее устройство, не забудьте остановить процесс сканирования. Это можно сделать с помощью метода cancelDiscovery(). Кроме того, если ваш телефон уже находится в соединении с каким-либо устройством, сканирование может значительно сузить ширину пропускания канала, поэтому лучше воздержаться от поиска новых устройств при установленном соединении.

Сервер

При соединении устройств одно из них должно вести себя как сервер, то есть удерживать открытый BluetoothServerSocket. Цель сервера – ждать запроса на входящее соединение, и когда оно подтверждено, создать BluetoothSocket. После этого BluetoothServerSocket можно закрыть. Рассмотрим поэтапно процедуру соединения с точки зрения сервера:

  1. Получить BluetoothServerSocket вызвав метод listenUsingRfcommWithServiceRecord(String, UUID). Первый параметр метода представляет собой идентификационное имя вашего сервиса. Система автоматически добавит его в базу Service Discovery Protocol (SDP). Обычно в качестве этого параметра просто указывают название приложения. Второй параметр также идентифицирует сервис. Этот параметр используется клиентом при подтверждении соединения.
  2. Начинаем прослушивать запрос на соединения через метод accept().  Это блокирующий метод, который возвращает результат либо когда соединение подтверждено, либо когда произошло исключение. Соединение считается подтвержденным, когда удаленное устройство пошлет запрос на соединение с UUID, указанным при регистрации серверного сокета. В случае успеха, accept() возвращает настроенный на соединение BluetoothSocket.
  3. Если Вы хотите принять дополнительное соединение, вызовите метод close(). Это приведет к освобождению сокета и всех его ресурсов, но не закроет соединенный BluetoothSocket. В отличие от TCP/IP, RFCOMM  позволяет работать только с одним клиентом на канале, поэтому в большинстве случаев имеет смысл вызывать метод close() срезу же после установки принятия сокета.

Поскольку метод accept() является блокирующим, его не стоит вызывать из потока главной деятельности, поскольку это приведет к подвисанию интерфейса. Обычна вся работа с BluetoothServerSocket и BluetoothSocket выполняется в отдельном потоке. Чтобы прекратить выполнение метода accept(), вызовите метод close() для BluetoothServerSocket (или BluetoothSocket) из любого другого потока вашего приложения.

Ниже приведен пример потока, реализующий описанный выше механизм работы

privateclass AcceptThreadextends Thread{private final BluetoothServerSocket mmServerSocket;
 
public AcceptThread(){// используем вспомогательную переменную, которую в дальнейшем// свяжем с mmServerSocket,
BluetoothServerSocket tmp=null;
try{// MY_UUID это UUID нашего приложения, это же значение// используется в клиентском приложении
tmp= mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);} catch(IOException e){}
mmServerSocket= tmp;}
 
public void run(){
BluetoothSocket socket=null;// ждем пока не произойдет ошибка или не// будет возвращен сокетwhile(true){
try{
socket= mmServerSocket.accept();} catch(IOException e){break;}// если соединение было подтвержденоif(socket!=null){// управлчем соединением (в отдельном потоке)
manageConnectedSocket(socket);
mmServerSocket.close();break;}}}
 
/** отмена ожидания сокета */public void cancel(){
try{
mmServerSocket.close();} catch(IOException e){}}}

В этом примере подразумевается, что может быть установлено только одно соединение, поэтому после того, как соединение подтверждено и получен BluetoothSocket, приложение посылает его отдельному потоку, закрывает BluetoothServerSocket и выходит из цикла.

Обратите внимание, когда accept() возвращает BluetoothSocket, сокет уже соединен, поэтому не требуется вызывать метод connect().

manageConnectedSocket() представляет собой метод, внутри которого нужно создать поток для передачи данных. Его возможная реализация будет рассмотрена ниже.

Вы должны закрыть BluetoothServerSocket сразу же после завершения прослушивания эфира на предмет наличия входящего соединения. В приведенном примере метод close() вызывается сразу после получения объекта BluetoothSocket. Также Вам может понадобиться public метод для остановки приватного BluetoothSocket.

Трюк 4: работаем с bt-адаптером напрямую

Долгое время Bluetooth стеки для Windows предоставляли настолько скудные возможности, что программисты просто обходили эту платформу стороной. Этим объясняется, что большинство программ для серьезных забав c «синим зубом» разрабатываются под никсовую платформу.

Некоторые из хитрых приемов мы разберем именно на это платформе, а именно FreeBSD (напомню, что на диске прошлого номера мы выкладывали свежий 7.0 релиз этой ОС). Сама технология Bluetooth официально стала поддерживаться на ней только с 5-ой ветки на базе подсистемы Netgraph.

  1. Подключаем устройство: kldload ng_ubt
  2. Копируем сценарий подгрузки стека в удобное место: cp /usr/share/examples/netgraph/bluetooth/rc.bluetooth /usr/local/etc/rc.bluetooth
  3. Копируем сценарий подгрузки стека в удобное место и запускаем: sh /usr/local/etc/rc.bluetoots start ubt0

Теперь хочу познакомить тебя с утилитой hccontrol. Это одна из основных программ для работы с BT-модулем. Именно она выполняет все операции, связанные с интерфейсом HCI, и имеет следующий синтаксис: hccontrol –n . Проверим функциональность нашего устройства, просканиров эфир на наличие устройств:

hccontrol –n ubt0hci Inquiry

Как результат, утилита выведет информацию о найденных устройствах, в том числе их MAC-адреса. Надо заметить, что каждое из устройств Bluetooth, будь то хедсет или обыкновенный телефон, представляет некоторый набор сервисов. Базовый перечень включает в себя:

CIP (Common ISDN Access), CTP (Cordless Telephony), DUN (dial-up networking), FAX (FAX), FTRN (Obex File Transwer), HSET (Headset), NAP (Network Access Point). Чтобы выяснить, какие сервисы предоставляет то или иное устройство, используется запрос на специальном протоколе SPD (Service Descovery Protocol).

# spdcontrol -a browse

Трюк 6: перехватываем из эфира разговоры по гарнитуре

Одна из основных угроз радиотехнологий состоит в том, что данные можно перехватить. Первое, что приходит в голову, касаемо Bluetooth – прослушать разговоры людей, использующих гарнитуру. И зачастую это реально! На хакерском фестивале What the Hack в Нидерландах специалисты из группы Trifinite продемонстрировали, как при помощи ноутбука с Linux, специальной программы и направленной антенны можно подслушать, о чем говорит через Bluetooth-гарнитуру водитель проезжающего автомобиля.

Группа разработала программу Car Whisperer («Автомобильный шептун»). Возможности программы относительно невелики: прослушать можно только тех, кто забыл сменить заводские пароли доступа к Bluetooth наподобие «0000» или «1234». Но таких бедолаг, поверь, очень и очень много!

«Шептун» способен вклиниться и успешно пройти «pairing» устройств, получив информацию, передаваемую с каркита или хедсета на мобилку. Хочу обратить внимание: утилита позволяет не только получить информацию, передающуюся между хедсетом и мобилой, но и инжектить туда свою. Мы решили проверить возможности этой программы, скачав Car Whisperer с сайта разработчиков.

Перед началом операции рекомендуется изменить класс своего устройства, особенно если программа будет использоваться с компьютера:

hciconfig адаптер class 0x500204 # 0x500204 — это класс «phone»

В противном случае некоторые «умные» девайсы могут заподозрить неладное. Смотрим синтаксис утилиты, который выглядит следующим образом:

./carwhisperer «что внедряем в линию» «что захватываем из линии» «адрес устройства» [канал]

Мы взяли внедряемый файл прямо из папки утилиты, а в качестве выходного указали out.raw:

./carwhisperer 0 message.raw /tmp/out.raw 00:15:0E:91:19:73

На выходе получаем файл out.raw. Прослушать его в чистом виде нельзя: необходимо преобразовать в аудио формат, для чего потребуется дополнительная утилита. Подойдут довольно многие аудио конвертеры, например SoX:

raw –r 8000 –c 1 –s –w out.raw –t wav –r 44100 –c 2 out.wav

Кроме прослушивания, можно войти в систему, просмотреть телефонную книгу и воспользоваться другими возможностями «свободных рук» с Bluetooth. Принцип такой: сначала осуществляется поиск активных устройств и проверка на предмет сервиса HS (Head Set). Далее исследуется MAC-адрес устройства и производится попытка подключения с использованием стандартного ключа. Если коннект установлен, то с устройством можно делать все, что угодно (в пределах доступного набора AT-команд).

На практике это выглядит следующим образом. Сначала осуществляется поиск всех активных гарнитур с помощью команды «sdptool search HS», которая выдает примерно такой ответ:

Inquiring . Searching for HS on 00:0A:3A:54:71:95 . Service Name: Headset Service RecHandle: 0x10009 Service Class ID List: “Headset” (0x1108) “Generic Audio” (0x1203) Protocol Descriptor List: “L2CAP” (0x0100) “RFCOMM” (0x0003) Channel:

Далее осуществляется попытка открыть RFCOMM соединение на SCO audio channel с помощью команды «rfcomm connect 2 00:0A:3A:54:71:95 1» и посылка нужных AT-команд. Приведу небольшую статистическую заметку о данных авторизации на некоторые модели беспроводных гарнитур:

Nokia (00:02:EE. ) — pin=”5475″ Audi UHV (00:0E:9F. ) — pin=”1234″ O’Neill (00:80:37. ) — pin=”8761″ Cellink (00:0A:94. ) — pin=”1234″ Eazix (00:0C:84. ) — pin=”1234″

Кстати говоря, тот же принцип может использоваться для несанкционированного подключения и ко всем остальным устройствам. При помощи AT-команд и протокола RFCOMM можно, к примеру, прочитать SMS-сообщение или даже отправить его с чужого телефона на платный номер, поставив владельца девайса на деньги. Будь бдителен!

Оцените статью
Радиокоптер.ру
Добавить комментарий