Показаны сообщения с ярлыком работа с устройствами. Показать все сообщения
Показаны сообщения с ярлыком работа с устройствами. Показать все сообщения

вторник, 22 мая 2012 г.

Играем с акселерометром в Android

И ещё одно замечательное устройство в нашем Android-девайсе дождалось своего примера использования. Использование акселерометра занимает особое место в приложениях (особенно в играх) для Android. Камерой и микрофоном мы могли бы пользоваться и в ноутбуке, а вот этим устройством - вряд ли. Только смартфоном можно размахивать из стороны в сторону в игровом процессе, и тут не обойтись без снятия данных с датчика ускорения. Сам процесс получения данных с акселероматра очень прост и не заслуживает отдельной статьи, поэтому мы сделаем небольшую игру, построенную на использовании акселерометра.
Принцип игры будет заключаться как раз в "размахивании" смартфоном: нужно будет махнуть сильнее чем противник, желательно не разбив аппарат при этом ;)
Как и у всякой приличной игры будет возможность сохранить свои достижения и т.п. Итак, приступим:

воскресенье, 13 мая 2012 г.

Работа с GPS и Google Maps в Android

Продолжаем осваивать аппаратные возможности Android-смартфонов. В предыдущих постах мы  изучили, как использовать в наших приложениях микрофон и камеру. Теперь возьмёмся за более сложную тему: GPS. Сложность, конечно же, относительная. В сети есть масса примеров кода, с помощью которого можно получить координаты клиента, поэтому чтобы сделать наш пример интереснее, соединим получение координат с их использованием. В этой статье вы узнаете как получить доступ к Google Maps API, отобразить карту с различными её "плюшками" и вывести на неё наши координаты, полученные различными способами: по спутникам, данным мобильной сети или wifi.
Итак, приступим:

четверг, 10 мая 2012 г.

Работа с камерой в Android-приложении


За что особенно люблю Andriod - так это за обилие аппаратных "плюшек". Тут тебе и микрофон/динамик и gps и wifi, тут и фото/видео камера и так далее... В результате способов применений у этого маленького девайса, а значит простора для программиста, который под него пишет - очень много.
Я уже писал о работе с микрофоном в Android-приложениях, сегодня удостоим внимания камеру. Примеров того, как реализовать простое приложения для фотографирования достаточно много, поэтому в этой статье я покажу кроме всего прочего, как работать с полученной фотографией, в частности как её обрезать. Наше простое приложение может не только сфотографировать вашего знакомого, но и выделить его лицо из кадра, например для сохранения в списке контактов.

пятница, 3 июня 2011 г.

Работа со звуком в Android-приложении

На днях возникла задача: получить и проанализировать амплитуду сигнала с микрофона в Android. Задача, в принципе, простая. В обычном случае мы используем класс MediaRecorder таким вот образом:
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile("/dev/null");
recorder.prepare();
recorder.start();
for(int i=0; i<10; i++) {
 System.err.println("current amplitude is:"+recorder.getMaxAmplitude());
 try {
   Thread.sleep(1000);
 } catch (Exception e) {}
}
recorder.stop();
recorder.reset();
recorder.release();

В этом фрагменте мы теоретически должны получить 10 отметок максимальной амплитуды сигнала за периоды чтения по секунде с первой до десятой. Для этого мы читаем сигнал с микрофона в "никуда", и используем getMaxAmplitude(), который согласно документации должен возвращать значение максимальной амплитуды за период с последнего вызова метода до данного момента. В чём проблема? На моём LG P500 этот метод всегда возвращает ноль :(
Исследования на тему "Почему" дали немного. Гораздо интереснее ответ на вопрос

Как всё-таки получать амплитуду сигнала?
Класс MediaRecorder крайне неудобен для работы с сигналом напрямую. Даже если бы я смог его использовать, запись данных в файл - далеко не всё, что обычно нужно при захвате звука. Для наложения фильтров и анализа сигнала удобнее получить сигнал в массив и работать с ним "на лету". К счастью есть ещё один класс в Android SDK, который нас выручит. Это AudioRecord.
Работать с ним несколько сложнее, но мы не боимся трудностей :)

public class AmplitudeReader extends Thread {
 
  private AudioRecord audioRecord;
  private int bufflen;
  private static final int SAMPPERSEC = 48000;
 
  public AmplitudeReader() {
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
    int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_DEFAULT;
    int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
    bufflen = AudioRecord.getMinBufferSize(SAMPPERSEC, channelConfiguration, audioEncoding);
    audioRecord = new AudioRecord(android.media.MediaRecorder.AudioSource.MIC, SAMPPERSEC, channelConfiguration, audioEncoding, bufflen);
    audioRecord.startRecording();
  }
 
  private short getMax(short[] arr, int count) {
    short m = 0;
    for (int i = 0; i < count; i++) {
      short c = (short) Math.abs(arr[i]);
      if (m < c) {
        m = c;
      }
    }
    return m;
  }
 
  @Override
  public void run() {
    for(int i=0; i<11; i++) {
      short[] curr = new short[bufflen];
      int currread = audioRecord.read(curr, 0, bufflen);
      System.err.println("current amplitude is:" + getMax(curr, currread));
    }
    audioRecord.stop();
    audioRecord.release();
  }
}

В этом примере мы выводим в лог десять значений амплитуды, снятые "на лету" с каждого буфера чтения. Размер буфера система нам установит сама исходя из настроек. Обычно это 4Кb. Понятно, что получением амплитуды мы можем не ограничиться. Сигнал после считывания представлен у нас в массиве байтов (или short, смотря какой метод использовать для чтения). Совершая с элементами этого массива различные действия мы можем усиливать сигнал, подавлять постоянную составляющую, сглаживать и т.п.
И ещё одна особенность: для использования MediaRecorder нам понадобятся 2 разрешения: на чтение и на запись звука на карту: android.permission.RECORD_AUDIO и android.permission.WRITE_EXTERNAL_STORAGE, для использования AudioRecord - только первое из них.