Implement bluetooth autospawn / autoplayback feature #235
This commit is contained in:
parent
574224ff99
commit
d0f9b049de
9 changed files with 79 additions and 0 deletions
|
@ -8,6 +8,11 @@
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
|
||||||
|
<!-- Bluetooth auto-connect functionality -->
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" android:minSdkVersion="31" />
|
||||||
|
<uses-feature android:name="android.hardware.bluetooth" android:required="false"/>
|
||||||
|
|
||||||
<!-- Work around ExoPlayer requiring network permissions we do not use -->
|
<!-- Work around ExoPlayer requiring network permissions we do not use -->
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.ACCESS_NETWORK_STATE"
|
android:name="android.permission.ACCESS_NETWORK_STATE"
|
||||||
|
@ -102,6 +107,15 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<!-- Auxio's auto-playback on BT connect receiver. -->
|
||||||
|
<receiver
|
||||||
|
android:name=".playback.system.BluetoothConnectReceiver"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
<!-- Auxio's one and only AppWidget. -->
|
<!-- Auxio's one and only AppWidget. -->
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".widgets.WidgetProvider"
|
android:name=".widgets.WidgetProvider"
|
||||||
|
|
|
@ -23,6 +23,7 @@ import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import org.oxycblt.auxio.databinding.ActivityMainBinding
|
import org.oxycblt.auxio.databinding.ActivityMainBinding
|
||||||
|
@ -73,6 +74,18 @@ class MainActivity : AppCompatActivity() {
|
||||||
if (!startIntentAction(intent)) {
|
if (!startIntentAction(intent)) {
|
||||||
playbackModel.startAction(InternalPlayer.Action.RestoreState)
|
playbackModel.startAction(InternalPlayer.Action.RestoreState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check bluetooth connect permissions if required for bt autoconnect feature
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
val settings = Settings(this)
|
||||||
|
if (settings.bluetoothAutoplay) {
|
||||||
|
ActivityCompat.requestPermissions(
|
||||||
|
this,
|
||||||
|
arrayOf<String>(android.Manifest.permission.BLUETOOTH_CONNECT),
|
||||||
|
BLUETOOTH_PERMISSION_REQUEST_ID
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewIntent(intent: Intent?) {
|
override fun onNewIntent(intent: Intent?) {
|
||||||
|
@ -141,5 +154,6 @@ class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val KEY_INTENT_USED = BuildConfig.APPLICATION_ID + ".key.FILE_INTENT_USED"
|
private const val KEY_INTENT_USED = BuildConfig.APPLICATION_ID + ".key.FILE_INTENT_USED"
|
||||||
|
private const val BLUETOOTH_PERMISSION_REQUEST_ID = 1337 * 42;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.oxycblt.auxio.playback.system
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothProfile
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
|
import org.oxycblt.auxio.playback.state.InternalPlayer
|
||||||
|
import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
||||||
|
import org.oxycblt.auxio.settings.Settings
|
||||||
|
|
||||||
|
class BluetoothConnectReceiver : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
if (intent.action == android.bluetooth.BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED) {
|
||||||
|
val newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED)
|
||||||
|
if (newState == BluetoothProfile.STATE_CONNECTED) {
|
||||||
|
val settings = Settings(context)
|
||||||
|
if (settings.bluetoothAutoplay) {
|
||||||
|
// make sure required services are up and running
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
context.startForegroundService(Intent(context, PlaybackService::class.java))
|
||||||
|
} else {
|
||||||
|
context.startService(Intent(context, PlaybackService::class.java))
|
||||||
|
}
|
||||||
|
// start playback
|
||||||
|
val playbackManager = PlaybackStateManager.getInstance()
|
||||||
|
playbackManager.startAction(InternalPlayer.Action.RestoreState)
|
||||||
|
playbackManager.changePlaying(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -135,6 +135,10 @@ class Settings(private val context: Context, private val callback: Callback? = n
|
||||||
val headsetAutoplay: Boolean
|
val headsetAutoplay: Boolean
|
||||||
get() = inner.getBoolean(context.getString(R.string.set_key_headset_autoplay), false)
|
get() = inner.getBoolean(context.getString(R.string.set_key_headset_autoplay), false)
|
||||||
|
|
||||||
|
/** Whether a connected bluetooth device should cause Auxio to spawn and start playback */
|
||||||
|
val bluetoothAutoplay: Boolean
|
||||||
|
get() = inner.getBoolean(context.getString(R.string.set_key_bluetooth_autoplay), false)
|
||||||
|
|
||||||
/** The current ReplayGain configuration */
|
/** The current ReplayGain configuration */
|
||||||
val replayGainMode: ReplayGainMode
|
val replayGainMode: ReplayGainMode
|
||||||
get() =
|
get() =
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
package org.oxycblt.auxio.settings
|
package org.oxycblt.auxio.settings
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
|
@ -44,6 +46,8 @@ import org.oxycblt.auxio.util.isNight
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.showToast
|
import org.oxycblt.auxio.util.showToast
|
||||||
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||||
|
import java.security.Permission
|
||||||
|
import java.util.jar.Manifest
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual fragment containing the settings menu. Inherits [PreferenceFragmentCompat].
|
* The actual fragment containing the settings menu. Inherits [PreferenceFragmentCompat].
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
<string name="set_audio">Audio</string>
|
<string name="set_audio">Audio</string>
|
||||||
<string name="set_headset_autoplay">Kopfhörer: automatische Wiedergabe</string>
|
<string name="set_headset_autoplay">Kopfhörer: automatische Wiedergabe</string>
|
||||||
<string name="set_headset_autoplay_desc">Beginne die Wiedergabe immer, wenn Kopfhörer verbunden sind (funktioniert nicht auf allen Geräten)</string>
|
<string name="set_headset_autoplay_desc">Beginne die Wiedergabe immer, wenn Kopfhörer verbunden sind (funktioniert nicht auf allen Geräten)</string>
|
||||||
|
<string name="set_bluetooth_autoplay">Bluetooth: automatische Wiedergabe</string>
|
||||||
|
<string name="set_bluetooth_autoplay_desc">Auxio starten und Wiedergabe fortführen, sobald ein Bluetooth Audio fähiges Gerät verbunden wurde</string>
|
||||||
<string name="set_replay_gain">ReplayGain-Strategie</string>
|
<string name="set_replay_gain">ReplayGain-Strategie</string>
|
||||||
<string name="set_pre_amp">ReplayGain-Prälautverstärkung</string>
|
<string name="set_pre_amp">ReplayGain-Prälautverstärkung</string>
|
||||||
<string name="set_pre_amp_desc">Während der Musikwiedergabe, trifft die Prälautverstärkung dem aktuellem Abgleich zu</string>
|
<string name="set_pre_amp_desc">Während der Musikwiedergabe, trifft die Prälautverstärkung dem aktuellem Abgleich zu</string>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
<string name="set_key_alt_notif_action" translatable="false">KEY_ALT_NOTIF_ACTION</string>
|
<string name="set_key_alt_notif_action" translatable="false">KEY_ALT_NOTIF_ACTION</string>
|
||||||
|
|
||||||
<string name="set_key_headset_autoplay" translatable="false">auxio_headset_autoplay</string>
|
<string name="set_key_headset_autoplay" translatable="false">auxio_headset_autoplay</string>
|
||||||
|
<string name="set_key_bluetooth_autoplay" translatable="false">auxio_bluetooth_autoplay</string>
|
||||||
<string name="set_key_replay_gain" translatable="false">auxio_replay_gain</string>
|
<string name="set_key_replay_gain" translatable="false">auxio_replay_gain</string>
|
||||||
<string name="set_key_pre_amp" translatable="false">auxio_pre_amp</string>
|
<string name="set_key_pre_amp" translatable="false">auxio_pre_amp</string>
|
||||||
<string name="set_key_pre_amp_with" translatable="false">auxio_pre_amp_with</string>
|
<string name="set_key_pre_amp_with" translatable="false">auxio_pre_amp_with</string>
|
||||||
|
|
|
@ -180,6 +180,8 @@
|
||||||
<string name="set_audio">Audio</string>
|
<string name="set_audio">Audio</string>
|
||||||
<string name="set_headset_autoplay">Headset autoplay</string>
|
<string name="set_headset_autoplay">Headset autoplay</string>
|
||||||
<string name="set_headset_autoplay_desc">Always start playing when a headset is connected (may not work on all devices)</string>
|
<string name="set_headset_autoplay_desc">Always start playing when a headset is connected (may not work on all devices)</string>
|
||||||
|
<string name="set_bluetooth_autoplay">Bluetooth autoplay</string>
|
||||||
|
<string name="set_bluetooth_autoplay_desc">A connected bluetooth audio device causes Auxio to spawn and start playback</string>
|
||||||
<string name="set_replay_gain">ReplayGain strategy</string>
|
<string name="set_replay_gain">ReplayGain strategy</string>
|
||||||
<string name="set_replay_gain_track">Prefer track</string>
|
<string name="set_replay_gain_track">Prefer track</string>
|
||||||
<string name="set_replay_gain_album">Prefer album</string>
|
<string name="set_replay_gain_album">Prefer album</string>
|
||||||
|
|
|
@ -74,6 +74,11 @@
|
||||||
app:summary="@string/set_headset_autoplay_desc"
|
app:summary="@string/set_headset_autoplay_desc"
|
||||||
app:title="@string/set_headset_autoplay" />
|
app:title="@string/set_headset_autoplay" />
|
||||||
|
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
app:key="@string/set_key_bluetooth_autoplay"
|
||||||
|
app:summary="@string/set_bluetooth_autoplay_desc"
|
||||||
|
app:title="@string/set_bluetooth_autoplay" />
|
||||||
|
|
||||||
<org.oxycblt.auxio.settings.ui.IntListPreference
|
<org.oxycblt.auxio.settings.ui.IntListPreference
|
||||||
app:defaultValue="@integer/replay_gain_dynamic"
|
app:defaultValue="@integer/replay_gain_dynamic"
|
||||||
app:entries="@array/entries_replay_gain"
|
app:entries="@array/entries_replay_gain"
|
||||||
|
|
Loading…
Reference in a new issue