Android java record call
SW Call Recorder
SW Call Recorder is an Android application that automatically records phone calls based on user selected phone numbers. It has the following main features:
- The phone numbers are organized into contacts.
- Every contact can have an associated picture selected by the user.
- There are 4 possible recording formats: WAV (Lossless), AAC 128kbs, AAC 64kbps and AAC 32kbps.
- Recordings can be mono or stereo.
- The device can be put automatically on speaker while the application records the call.
- Recordings can be stored in the application’s private storage space or in a public accessible location on the device. If they are stored in a public accessible location, they can be easily transferred to other devices, like a laptop. The location of the recordings on the device can be easily changed.
- Phone calls from private (unknown) numbers are supported.
- The user can rename the recordings.
- The recordings can be played from within the application with the help of a dedicated audio player.
- The audio player can modify the sound volume of the device while playing. After the playing finishes, the audio volume of the device automatically comes back to the previous value.
- The audio player can apply a gain to the audio signal to further control how loud the sound is played.
- The application has 2 themes: light and dark.
Because of the restrictions imposed by Google on requesting permissions from the Call log permission group (https://play.google.com/about/privacy-security-deception/permissions/), the app is currently developed using two branches: the original-app branch and the gpcompliant (from «google play compliant») branch.
The gpcompliant branch does not use the READ_CALL_LOG and PROCESS_OUTGOING_CALLS permissions and consequently the versions of the app compiled from this source cannot obtain the outgoing phone number in all supported versions of Android and cannot obtain the incoming phone number in Android versions 9 and above. This has consequences on the overall appearance and behavior of the app that are documented in the «Recording phone calls» section of the Help menu. These versions have the substring ‘gpcompliant’ appended to the version string.
The original-app branch retains all the functions that were removed from the gpcompliant branch. The versions of the app compiled from this source have the substring ‘original’ appended to the version string.
About
SW Call Recorder is an Android app that records phone calls based on user selected phone numbers.
Источник
Record Phone Calls in Java
Twilio is launching a new Console. Some screenshots on this page may show the Legacy Console and therefore may no longer be accurate. We are working to update all screenshots to reflect the new Console experience. Learn more about the new Console.
In this guide we’ll show you how to use Programmable Voice to record phone calls with your Java web application.
You will learn how to record inbound and outbound calls. In both examples we’ll use Twilio’s Java SDK.
Set up your web application
Twilio makes answering a phone call as easy as responding to an HTTP request. When a phone number you have bought through Twilio receives an incoming call, Twilio will send an HTTP request to your web application asking for instructions on how to handle the call. Your server will respond with an XML document containing TwiML that instructs Twilio on what to do with the call. Those instructions can direct Twilio to read out a message, play an MP3 file, make a recording and much more.
To start answering phone calls, you must:
- Buy and configure a Twilio-powered phone number capable of making and receiving phone calls, and point it at your web application
- Write a web application to tell Twilio how to handle the incoming call using TwiML
- Make your web application accessible on the Internet so Twilio can make an HTTP request when you receive a call
Buy and configure a phone number
In the Twilio Console, you can search for and buy phone numbers in countries around the world. Numbers that have the Voice capability can make and receive voice phone calls from just about anywhere on the planet.
Once you purchase a number, you’ll need to configure that number to send a request to your web application. This callback mechanism is called a webhook. This can be done in the number’s configuration page.
What is a Webhook?
Webhooks are user-defined HTTP callbacks. They are usually triggered by some event, such as receiving an SMS message or an incoming phone call. When that event occurs, Twilio makes an HTTP request (usually a POST or a GET) to the URL configured for the webhook.
To handle a webhook, you only need to build a small web application that can accept the HTTP requests. Almost all server-side programming languages offer some framework for you to do this. Examples across languages include ASP.NET MVC for C#, Servlets and Spark for Java, Express for Node.js, Django and Flask for Python, and Rails and Sinatra for Ruby. PHP has its own web app framework built in, although frameworks like Laravel, Symfony and Yii are also popular.
Whichever framework and language you choose, webhooks function the same for every Twilio application. They will make an HTTP request to a URI that you provide to Twilio. Your application performs whatever logic you feel necessary — read/write from a database, integrate with another API or perform some computation — then replies to Twilio with a TwiML response with the instructions you want Twilio to perform.
What is TwiML?
TwiML is the Twilio Markup Language, which is just to say that it’s an XML document with special tags defined by Twilio to help you build your SMS and voice applications. TwiML is easier shown than explained. Here’s some TwiML you might use to respond to an incoming phone call:
And here’s some TwiML you might use to respond to an incoming SMS message:
Every TwiML document will have the root element and within that can contain one or more verbs. Verbs are actions you’d like Twilio to take, such as a greeting to a caller, or send an SMS in reply to an incoming message. For a full reference on everything you can do with TwiML, refer to our TwiML API Reference.
Record an inbound phone call
Now comes the fun part — writing Java that will handle an incoming HTTP request from Twilio!
In this example we’ll use Java Servlets to respond to the Twilio webhook. We’ll then use TwiML to tell Twilio how to handle the call.
Источник
Полный список
— пишем звук с помощью AudioRecorder
Рассмотренный на прошлом уроке MediaRecorder записывал звук сразу в файл. AudioRecorder не пишет данные, а позволяет нам их получать в приложении. т.е. является посредником между приложением и микрофоном. Когда мы стартуем запись, AudioRecorder начинает получать данные с микрофона и хранит их у себя во внутреннем буфере. Мы можем при создании AudioRecorder указать желаемый размер этого буфера и далее запрашивать из него данные методом read.
Т.е. AudioRecorder будет полезен, если вы хотите как-то обработать данные перед записью в файл или, если вы хотите отправлять данные не в файл, а куда-либо еще.
Напишем приложение, в котором рассмотрим основные методы работы с AudioRecorder.
Project name: P1301_AudioRecorder
Build Target: Android 2.3.3
Application name: AudioRecorder
Package name: ru.startandroid.develop.p1301audiorecorder
Create Activity: MainActivity
Добавим строки в strings.xml:
Нарисуем экран main.xml:
Верхние кнопки стартуют/останавливают запись звука с микрофона в AudioRecorder, нижние – чтение данных из AudioRecorder в наш буфер.
В манифесте добавьте разрешение на запись звука: android.permission.RECORD_AUDIO.
В onCreate мы вызываем свой метод создания AudioRecorder и выводим в лог состояние созданного объекта. Состояние можно получить методом getState. Может быть всего два состояния: STATE_INITIALIZED и STATE_UNINITIALIZED. Означают они соответственно то, что AudioRecorder к работе готов или не готов.
В createAudioRecorder создаем AudioRecorder. Для этого нам понадобится несколько входных параметров:
— источник звука
— сэмплрейт
— режим каналов моно/стерео
— формат аудио
— размер буфера
Сэмплрейт мы ставим 8000. Режим — моно. Формат аудио – 16 бит. Чтобы узнать размер буфера, есть метод getMinBufferSize. Он, исходя из переданных ему на вход данных о формате аудио, возвращает минимально-возможный размер буфера, с которым сможет работать AudioRecorder. Мы получаем минимальный размер и в переменную internalBufferSize помещаем этот размер, умноженный на 4. Такой размер буфера будет в созданном AudioRecord.
Далее создаем AudioRecord. В качестве источника звука указываем микрофон. Также указываем сэмплрейт, режим каналов, формат и размер буфера.
В методе recordStart стартуем запись методом startRecording. С помощью метода getRecordingState получаем статус — идет запись или нет. Вариантов тут два: RECORDSTATE_RECORDING (запись идет) и RECORDSTATE_STOPPED (запись остановлена).
В recordStop останавливаем запись методом stop.
В readStart ставим метку isReading в true. Она будет означать, что мы сейчас находимся в режиме чтения данных из AudioRecorder. Далее создаем новый поток и чтение выполняем в нем, чтобы не занимать основной поток. Мы создаем свой буфер размером myBufferSize и читаем в него данные методом read. Это происходит в цикле, который проверяет, что мы в режиме чтения. Метод read на вход принимает массив (в который будут помещены данные), отступ (если вам надо прочесть данные не сначала, а с какой-то позиции), и размер порции получаемых данных. В readCount метод read возвращает число байт, которые он нам отдал. В totalCount мы суммируем общее количество полученных байтов.
У метода read кстати есть еще несколько реализаций, если эта вам не подходит. Подробнее смотрите в хелпе.
В методе readStop мы выключаем режим чтения, присваивая переменной isReading значение false. Поток из readStart прочтет это значение, выйдет из цикла и завершит свою работу.
В onDestroy выключаем режим чтения и методом release освобождаем ресурсы, занятые AudioRecord.
Все сохраняем, запускаем приложение.
В логах мы видим
minInternalBufferSize = 1024, internalBufferSize = 4096, myBufferSize = 8192
init state = 1
Мы видим, что минимальный размер буфера AudioRecorder насчитал равным 1024. Внутренний буфер будет 4096. Размер нашего буфера будет 8192. Состояние рекордера = 1, это значение переменной STATE_INITIALIZED, значит все ок, к работе готов.
Жмем Start record.
record start
recordingState = 3
Состояние записи рекордера = 3, это значение переменной RECORDSTATE_RECORDING, значит все ок, запись идет.
AudioRecorder сейчас получает данные с микрофона и держит их в своем буфере. Попробуем прочесть эти данные. Жмем Start read, и через несколько секунд Stop read
14:03:48.519: D/myLogs(14361): read start
14:03:48.519: D/myLogs(14361): readCount = 4096, totalCount = 4096
14:03:48.779: D/myLogs(14361): readCount = 4096, totalCount = 8192
14:03:49.039: D/myLogs(14361): readCount = 4096, totalCount = 12288
14:03:49.289: D/myLogs(14361): readCount = 4096, totalCount = 16384
14:03:49.549: D/myLogs(14361): readCount = 4096, totalCount = 20480
14:03:49.809: D/myLogs(14361): readCount = 4096, totalCount = 24576
14:03:50.069: D/myLogs(14361): readCount = 4096, totalCount = 28672
14:03:50.319: D/myLogs(14361): readCount = 4096, totalCount = 32768
14:03:50.569: D/myLogs(14361): readCount = 4096, totalCount = 36864
14:03:50.829: D/myLogs(14361): readCount = 4096, totalCount = 40960
14:03:51.079: D/myLogs(14361): readCount = 4096, totalCount = 45056
14:03:51.179: D/myLogs(14361): read stop
14:03:51.339: D/myLogs(14361): readCount = 4096, totalCount = 49152
Видим, что прошло несколько чтений буфера. Таким образом, мы получали данные с микрофона с помощью AudioRecorder.
Сколько байт занимает секунда звука
Разберемся, как подсчитать сколько места занимает звук, когда его пишешь. Вспоминаем наши параметры, которые мы задавали при создании AudioRecorder: сэмплрейт (как часто считывается звук) = 8000 Hz, формат (сколько места занимает одна запись) = 16 бит, канал = моно. Эти параметры означают, что одна секунда звука будет занимать 8000 * 16 * 1 = 128 000 бит = 16 000 байт.
Теперь посмотрим на логи. Первое чтение звука было в 14:03:48.519, а последнее в 14:03:51.339. Т.е. мы писали звук примерно три секунды. Три секунды – это 16 000 * 3 = 48 000 байт.
Снова смотрим логи, последнее значение totalCount = 49 152. Как видите, расчетная и реальная цифры похожи.
Давайте поменяем параметры в методе createAudioRecorder:
и снова посчитаем:
22 050 (сэмплрейт) * 16 (формат) * 2 (стерео) = 705 600 бит = 88 200 байт занимает теперь секунда звука. Как видите, при улучшении качества увеличились размеры.
Все сохраним, запускаем приложение. Жмем Start record, затем Start read и секунды через три Stop read.
14:15:29.959: D/myLogs(14567): read start
14:15:29.969: D/myLogs(14567): readCount = 8192, totalCount = 8192
14:15:29.969: D/myLogs(14567): readCount = 8192, totalCount = 16384
14:15:30.069: D/myLogs(14567): readCount = 8192, totalCount = 24576
…
14:15:32.479: D/myLogs(14567): readCount = 8192, totalCount = 237568
14:15:32.579: D/myLogs(14567): readCount = 8192, totalCount = 245760
14:15:32.659: D/myLogs(14567): read stop
14:15:32.669: D/myLogs(14567): readCount = 8192, totalCount = 253952
Видим, что примерно за 3 секунды мы считали 253 952 байта. Смотрим наши подсчеты 88 200 * 3 = 264 600. Цифры снова близки.
Это было небольшое отступление от темы урока, чтобы вы имели представление о взаимосвязи таких параметров как время, сэмплрейт, формат, каналы, байты.
Слушатель отданных фреймов
Когда AudioRecorder отдает нам данные, он ведет подсчет отданных фреймов. Фрейм – это единица записи звука. Сколько байт занимает один фрейм? Это мы уже считали чуть раньше – формат * режим каналов. Т.е. если мы пишем звук в формате 16 бит/моно, то фрейм займет 16 * 1 = 16 бит = 2 байта.
Мы можем на AudioRecorder повесить слушателя с парой методов. Один метод будет срабатывать периодически через каждое указанное кол-во отданных фреймов, а другой разово по достижению определенного кол-ва отданных фреймов.
Метод setRecordPositionUpdateListener устанавливает слушателя с методами onPeriodicNotification и onMarkerReached, которые я описал выше. Метод setPositionNotificationPeriod устанавливает кол-во фреймов для срабатывания onPeriodicNotification, а setNotificationMarkerPosition – для срабатывания onMarkerReached.
Т.е. метод onPeriodicNotification будет срабатывать каждые 1000 отданных фреймов. А onMarkerReached – по достижению 10000 отданных фреймов. В onMarkerReached мы остановим чтение.
Все сохраним, запустим приложение и жмем Start record, затем Start read. В этот раз мы можем вручную не останавливать процесс чтения, т.к. он остановится сам по достижении 10000 фреймов.
read start
readCount = 4096, totalCount = 4096
onPeriodicNotification
onPeriodicNotification
onPeriodicNotification
readCount = 4096, totalCount = 8192
onPeriodicNotification
onPeriodicNotification
onPeriodicNotification
readCount = 4096, totalCount = 12288
onPeriodicNotification
onPeriodicNotification
readCount = 4096, totalCount = 16384
onPeriodicNotification
onMarkerReached
onPeriodicNotification
readCount = 4096, totalCount = 20480
Видим, что onPeriodicNotification срабатывал примерно каждые 2000 байт, а onMarkerReached сработал около получения 20000 байт.
Вспоминаем, что один фрейм при текущих настройках занимает два байта. А значит, как мы и указали, метод onPeriodicNotification срабатывал каждые 1000 фреймов, а onMarkerReached – как только было получено 10000 фреймов
На следующем уроке:
— получаем фото и видео, используя системное приложение
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник