Cómo grabar audio desde un auricular bluetooth (startBluetoothSco ())
Estoy tratando de grabar audio de auriculares bluetooth, startBluetoothSco () funciona diferente en diferentes versiones de android, Grabación de audio de auriculares bluetooth en android 4.2, 4.4 y 5.0. utilizando los auriculares bluetooth " Nokia BH-310 y 9xxPlantronics ".
SAMPLE_RATE = 8000;
- El dispositivo Android BLE recibe resultados extremadamente irregulares
- Bluetooth olvida PIN
- Android: getBluetoothService () llamado sin BluetoothManagerCallback
- ¿Es el intercambio de archivos Bluetooth completamente seguro?
- Android ymodem sobre bluetooth en Java
- Los dispositivos que ejecutan Android 4.2 graban audio desde un dispositivo bluetooth solo cuando cuando se crea el objeto AudioRecord () como este
AudioSource.DEFAULT
mRecorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
- Los dispositivos que ejecutan Android 4.4 graban audio desde un dispositivo bluetooth sólo cuando cuando se crea el objeto AudioRecord () como este
AudioSource.DEFAULT
mRecorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
O
AudioSource.MIC
mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
- Los dispositivos que ejecutan Android 5.0 Lollipop graban audio desde un dispositivo bluetooth sólo cuando cuando se crea el objeto AudioRecord () como este
AudioSource.VOICE_COMMUNICATION
mRecorder = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); //with other AudioSource types (MIC, DEFAULT) sco returns connected state but record from phone mic
LOG para los estados de conexión del dispositivo Android 5.0
D/inside onRcv﹕ state=0 D/State=﹕ conn -> 0 D/inside onRcv﹕ state=2 D/State=﹕ conn -> 2 D/inside onRcv﹕ state=1 D/inside onRcv﹕ Unregister rcvr D/inside onRcv﹕ Connected Record from bluetooth //But still record from phone mic if Audio record object is created using MIC or DEFAULT
El código completo que estoy usando para hacer arriba está aquí.
BluetoothManager.java public class BluetoothRecordingManager { private static int count = 0; private static int TIMEOUT = 3000; private static int COUNTDOWN_INTERVAL = 1000; private static final int MAX_ATTEPTS_TO_CONNECT = 3; /** * This method check for bluetooh settings (bluetooth flag and bluetooth is * on or off) and decide wheather to record from bluetooth headset or phone * mic. If settings are not correct then start's recording using phone mic. * * @param context * @param BluetoothRecording :- Interface object * @param resume :- Pass through */ public static void checkAndRecord(final Context context, final OnBluetoothRecording BluetoothRecording, boolean resume) { if (getBluetoothFlag() && isBluetoothON()) { Log.d("start bluetooth recording"," calling"); startBluetoothRecording(BluetoothRecording, resume, context); } else { // If Bluetooth is OFF Show Toast else Dont Show if (getBluetoothFlag() && !isBluetoothON()) { Toast.makeText(context, "bluetooth_off", Toast.LENGTH_LONG).show(); // false because recording not started BluetoothRecording.onStartRecording(resume, false); } else { // false because recording not started BluetoothRecording.onStartRecording(resume, false); } } } /** * Connect to bluetooth headset and start recording if headset failed to * connect then records normally using phone mic. * * @param BluetoothRecording * @param resume * @param context */ private static void startBluetoothRecording(final OnBluetoothRecording BluetoothRecording, final boolean resume, final Context context) { final AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); //audioManager.setBluetoothScoOn(true); final CountDownTimer timer = getTimer(BluetoothRecording, audioManager, resume); Log.d("inside","startBlue rec"); final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1); Log.d("inside onRcv","state="+state); if (AudioManager.SCO_AUDIO_STATE_CONNECTED == state ) { // cancel Timer timer.cancel(); Log.d("inside onRcv","Unregister rcvr"); context.unregisterReceiver(this); Log.d("inside onRcv","Connected Record from bluetooth"); // pass through and true because // recording from bluetooth so set 8000kHz BluetoothRecording.onStartRecording(resume, true); } } }; Log.d("calling","registr broadcast rcvr"); context.registerReceiver(broadcastReceiver, new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)); // Start the timer try { // Android 2.2 onwards supports BT SCO for non-voice call use case // Check the Android version whether it supports or not. if(audioManager.isBluetoothScoAvailableOffCall()){ if(audioManager.isBluetoothScoOn()){ Log.d("SCO","stopped SCO"); // audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); audioManager.stopBluetoothSco(); timer.start(); Log.d("Starting sco","start"); audioManager.startBluetoothSco(); }else { timer.start(); Log.d("Starting sco","start"); audioManager.startBluetoothSco(); } }else { Log.d("Sco","Not availiable"); } } catch (Exception e) { Log.d("sco elsepart startBluetoothSCO"," "+e); timer.cancel(); context.unregisterReceiver(broadcastReceiver); BluetoothRecording.onStartRecording(resume, false); } } /** * set the Timeout * * @param BluetoothRecording * @param audioManager * @param resume * @return */ private static CountDownTimer getTimer(final OnBluetoothRecording BluetoothRecording, final AudioManager audioManager, final boolean resume) { return new CountDownTimer(TIMEOUT, COUNTDOWN_INTERVAL) { @Override public void onTick(long millisUntilFinished) { // Do Nothing } @Override public void onFinish() { // stopBluetoothSCO() and start Normal Recording audioManager.stopBluetoothSco(); // false because recording button is already clicked but still not recording. BluetoothRecording.onStartRecording(resume, false); } }; } /** * Return's the bluetooth state * * @return */ private static boolean isBluetoothON() { /*BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter != null) { return bluetoothAdapter.isEnabled(); } else { return false; }*/ return true; } /** * Return's the bluetoothFlag state * * @return */ private static boolean getBluetoothFlag() { return true; } }
MainActivity.java
Esto es cómo estoy creando el objeto de registro de audio y comenzar la grabación.
public class MainActivity extends Activity implements AdapterView.OnItemSelectedListener { public static final int SAMPLE_RATE = 8000; private AudioRecord mRecorder; private File mRecording; private short[] mBuffer; private final String startRecordingLabel = "Start recording"; private final String stopRecordingLabel = "Stop recording"; private boolean mIsRecording = false; private ProgressBar mProgressBar; float iGain = 1.0f; CheckBox gain; Button showPref; OnBluetoothRecording bluetoothRecording; protected int bitsPerSamples = 16; @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment_main); initRecorder() button.setOnClickListener(new OnClickListener() { @Override public void onClick(final View v) { if (!mIsRecording) { BluetoothRecordingManager.checkAndRecord(getApplicationContext(), new OnBluetoothRecording() { @Override public void onStartRecording(boolean state, boolean bluetoothFlag) { Log.d("CallBack", "starting Recording"); if (!mIsRecording) { button.setText(stopRecordingLabel); mIsRecording = true; mRecorder.startRecording(); mRecording = getFile("raw"); startBufferedWrite(mRecording); } else { Log.d("stop", "else part of start"); button.setText(startRecordingLabel); mIsRecording = false; mRecorder.stop(); File waveFile = getFile("wav"); try { rawToWave(mRecording, waveFile); } catch (IOException e) { Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show(); } Toast.makeText(MainActivity.this, "Recorded to " + waveFile.getName(), Toast.LENGTH_SHORT).show(); } } @Override public void onCancelRecording() { } }, true); } else { Log.d("stop", "stopped recording"); button.setText(startRecordingLabel); mIsRecording = false; mRecorder.stop(); File waveFile = getFile("wav"); try { rawToWave(mRecording, waveFile); } catch (IOException e) { Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show(); } final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); //audioManager.setMode(AudioManager.MODE_NORMAL); if (audioManager.isBluetoothScoOn()) { Log.d("SCO", "stopped SCO"); audioManager.stopBluetoothSco(); } Toast.makeText(MainActivity.this, "Recorded to " + waveFile.getName(), Toast.LENGTH_SHORT).show(); } } }); } private void initRecorder() { int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); mBuffer = new short[bufferSize]; Log.d("Creating Obj", "" + Mic); mRecorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); } }
- ¿Cómo detectar el cambio de estado Bluetooth con un receptor de difusión?
- Envío de un archivo utilizando Bluetooth OBEX Perfil de inserción de objetos (OPP)
- Registro de Bluetooth de Android llenando logcat
- Conexión a un puerto bluetooth específico en un dispositivo bluetooth mediante Android
- Desactivar el modo Bluetooth detectable en Android
- La API Bluetooth de Android se conecta a varios dispositivos
- Conexión Bluetooth de Android Seguro Inseguro
- BluetoothLeScanner.startScan () requiere nuevos permisos en Marshmallow?
- Despliegue de formularios de Android con barra de estado translúcida
- Equivalente de onActivityResult para el mortero y el flujo?