Merge branch 'audiorecorder-3.1.3'

This commit is contained in:
Alexey Kuznetsov 2018-01-02 15:33:20 +03:00
commit cc8f3832cf
3 changed files with 163 additions and 90 deletions

View file

@ -10,8 +10,8 @@ android {
applicationId "com.github.axet.audiorecorder"
minSdkVersion 9
targetSdkVersion 23 // 24+ file:// unable to open
versionCode 232
versionName "3.1.2"
versionCode 233
versionName "3.1.3"
}
signingConfigs {
release {

View file

@ -51,12 +51,17 @@ import com.github.axet.audiolibrary.widgets.PitchView;
import com.github.axet.audiorecorder.R;
import com.github.axet.audiorecorder.app.MainApplication;
import com.github.axet.audiorecorder.app.Storage;
import com.github.axet.audiorecorder.services.BluetoothReceiver;
import com.github.axet.audiorecorder.services.RecordingService;
import java.io.File;
import java.nio.ShortBuffer;
import java.util.concurrent.atomic.AtomicBoolean;
import static android.media.AudioManager.SCO_AUDIO_STATE_CONNECTED;
import static android.media.AudioManager.SCO_AUDIO_STATE_CONNECTING;
import static android.media.AudioManager.SCO_AUDIO_STATE_DISCONNECTED;
public class RecordingActivity extends AppCompatActivity {
public static final String TAG = RecordingActivity.class.getSimpleName();
@ -121,60 +126,34 @@ public class RecordingActivity extends AppCompatActivity {
context.startActivity(i);
}
class RecordingReceiver extends BroadcastReceiver {
boolean bluetoothSource = false; // are we using bluetooth source recording
boolean bluetoothStart = false; // did we start already?
boolean pausedByBluetooth = false;
boolean pause = false; // resumed recording by user, show error only on user actions
class RecordingReceiver extends BluetoothReceiver {
Runnable connected = new Runnable() {
@Override
public void run() {
handler.removeCallbacks(connected);
if (pausedByBluetooth) {
pausedByBluetooth = false;
if (thread == null) {
if (isRecordingReady())
startRecording();
}
}
}
};
public RecordingReceiver(Context context) {
super(context);
}
Runnable disconnected = new Runnable() {
@Override
public void run() {
handler.removeCallbacks(connected);
if (thread != null) {
pausedByBluetooth = true;
stopRecording(getString(R.string.hold_by_bluetooth));
stopBluetooth();
} else {
if (pause) {
pause = false;
Toast.makeText(RecordingActivity.this, R.string.hold_by_bluetooth, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onConnected() {
if (thread == null) {
if (isRecordingReady())
startRecording();
}
};
}
@Override
public void onDisconnected() {
if (thread != null) {
stopRecording(getString(R.string.hold_by_bluetooth));
super.onDisconnected();
}
}
@Override
public void onReceive(final Context context, Intent intent) {
super.onReceive(context, intent);
String a = intent.getAction();
if (a == null)
return;
if (bluetoothSource && a.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
handler.postDelayed(connected, 3000); // give os time ot initialize device, or startBluetoothSco will be ignored
}
if (bluetoothSource && a.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
if (AudioManager.SCO_AUDIO_STATE_CONNECTED == state) {
connected.run();
} else if (AudioManager.SCO_AUDIO_STATE_DISCONNECTED == state) {
disconnected.run();
}
return;
}
if (a.equals(PAUSE_BUTTON)) {
pauseButton();
return;
@ -202,7 +181,7 @@ public class RecordingActivity extends AppCompatActivity {
break;
case TelephonyManager.CALL_STATE_IDLE:
if (pausedByCall) {
if (isRecordingReady())
if (receiver.isRecordingReady())
startRecording();
}
wasRinging = false;
@ -337,7 +316,7 @@ public class RecordingActivity extends AppCompatActivity {
stopRecording(getString(R.string.recording_status_pause));
}
receiver = new RecordingReceiver();
receiver = new RecordingReceiver(this);
IntentFilter filter = new IntentFilter();
filter.addAction(PAUSE_BUTTON);
filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
@ -396,46 +375,20 @@ public class RecordingActivity extends AppCompatActivity {
void pauseButton() {
if (thread != null) {
receiver.pause = false;
stopRecording(getString(R.string.recording_status_pause));
stopBluetooth();
receiver.stopBluetooth();
headset(true, false);
} else {
receiver.pause = true;
stopBluetooth(); // reset bluetooth
receiver.stopBluetooth(); // reset bluetooth
editCut();
if (isRecordingReady()) {
if (receiver.isRecordingReady()) {
startRecording();
}
}
}
boolean startBluetooth() {
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
if (am.isBluetoothScoAvailableOffCall()) {
if (!receiver.bluetoothStart) {
am.startBluetoothSco();
receiver.bluetoothStart = true;
}
if (!am.isBluetoothScoOn()) {
receiver.pausedByBluetooth = true;
return false;
}
}
return true;
}
public boolean isRecordingReady() {
final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this);
if (shared.getString(MainApplication.PREFERENCE_BLUETOOTH, MainApplication.SOURCE_MIC).equals(MainApplication.SOURCE_BLUETOOTH)) {
receiver.bluetoothSource = true;
if (!startBluetooth())
return false;
} else {
receiver.bluetoothSource = false;
}
return true;
}
@Override
protected void onResume() {
super.onResume();
@ -447,7 +400,7 @@ public class RecordingActivity extends AppCompatActivity {
if (start) {
start = false;
if (Storage.permitted(this, PERMISSIONS_AUDIO, RESULT_START)) { // audio perm
if (isRecordingReady())
if (receiver.isRecordingReady())
startRecording();
else
stopRecording(getString(R.string.hold_by_bluetooth));
@ -695,22 +648,13 @@ public class RecordingActivity extends AppCompatActivity {
dialog.show();
}
public void stopBluetooth() {
handler.removeCallbacks(receiver.connected);
AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
if (receiver.bluetoothStart) {
receiver.bluetoothStart = false;
am.stopBluetoothSco();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestory");
stopRecording();
stopBluetooth();
receiver.stopBluetooth();
headset(false, false);
if (receiver != null) {
@ -973,7 +917,7 @@ public class RecordingActivity extends AppCompatActivity {
switch (requestCode) {
case RESULT_START:
if (Storage.permitted(this, permissions)) {
if (isRecordingReady())
if (receiver.isRecordingReady())
startRecording();
} else {
Toast.makeText(this, R.string.not_permitted, Toast.LENGTH_SHORT).show();

View file

@ -0,0 +1,129 @@
package com.github.axet.audiorecorder.services;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.widget.Toast;
import com.github.axet.audiorecorder.R;
import com.github.axet.audiorecorder.activities.RecordingActivity;
import com.github.axet.audiorecorder.app.MainApplication;
// default bluetooth stack for API25, bugged and has to be cleared.
public class BluetoothReceiver extends BroadcastReceiver {
public static int CONNECT_DELAY = 3000; // give os time ot initialize device, or startBluetoothSco will be ignored
public Context context;
public Handler handler = new Handler();
public boolean bluetoothSource = false; // are we using bluetooth source recording
public boolean bluetoothStart = false; // did we start already?
public boolean pausedByBluetooth = false;
public boolean pause = false; // resumed recording by user, show error only on user actions
public boolean connecting = false;
public Runnable connected = new Runnable() {
@Override
public void run() {
handler.removeCallbacks(connected);
if (pausedByBluetooth) {
pausedByBluetooth = false;
onConnected();
}
}
};
public Runnable disconnected = new Runnable() {
@Override
public void run() {
handler.removeCallbacks(connected);
onDisconnected();
if (pause) {
pause = false;
Toast.makeText(context, R.string.hold_by_bluetooth, Toast.LENGTH_SHORT).show();
}
if (connecting) {
connecting = false;
stopBluetooth();
}
}
};
public BluetoothReceiver(Context context) {
this.context = context;
}
public void onConnected() {
}
public void onDisconnected() {
pausedByBluetooth = true;
stopBluetooth();
}
@Override
public void onReceive(Context context, Intent intent) {
String a = intent.getAction();
if (a == null)
return;
if (bluetoothSource && a.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {
handler.postDelayed(connected, CONNECT_DELAY);
}
if (bluetoothSource && a.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
switch (state) {
case AudioManager.SCO_AUDIO_STATE_CONNECTED:
connected.run();
break;
case AudioManager.SCO_AUDIO_STATE_CONNECTING:
connecting = true;
break;
case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
disconnected.run();
break;
}
}
}
boolean startBluetooth() {
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
if (am.isBluetoothScoAvailableOffCall()) {
if (!bluetoothStart) {
am.startBluetoothSco();
bluetoothStart = true;
}
if (!am.isBluetoothScoOn()) {
pausedByBluetooth = true;
return false;
}
}
return true;
}
public void stopBluetooth() {
handler.removeCallbacks(connected);
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
if (bluetoothStart) {
bluetoothStart = false;
am.stopBluetoothSco();
}
}
public boolean isRecordingReady() {
final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context);
if (shared.getString(MainApplication.PREFERENCE_BLUETOOTH, MainApplication.SOURCE_MIC).equals(MainApplication.SOURCE_BLUETOOTH)) {
bluetoothSource = true;
if (!startBluetooth())
return false;
} else {
bluetoothSource = false;
}
return true;
}
}