Skip to content

Commit 344c01c

Browse files
feat: Add Audio Output quick settings tile
- Added a new Quick Settings tile to open the native Android audio output switcher dialog. - Created `AudioOutputTileService` to manage the tile's functionality. - Added `ic_audio_output` vector drawable for the tile icon. - Added the `audio_output` string and its translations for the tile label. - Registered the new service in `AndroidManifest.xml`. - Incremented `versionCode` to 37 and `versionName` to "3.1.0".
1 parent 9ad3351 commit 344c01c

File tree

31 files changed

+157
-26
lines changed

31 files changed

+157
-26
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
# Version 3.0.5:
1+
# Version 3.1.0:
22

33
- **New**: Added new translations so the app now speaks Arabic (Egypt), Bengali (Bangladesh), Spanish (Mexico), Filipino (Philippines), Korean (South Korea), Urdu (Pakistan), and Vietnamese (Vietnam).
4+
- **New**: Added a new Audio Output Switcher to open the native Android audio output switcher when is not abialabile.
45
- **Minor**: Updated our build tools and libraries to keep everything running smoothly.
56
- **Minor**: Improved our analytics setup for better crash reporting.
67

app/build.gradle.kts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ android {
1515
applicationId = "com.d4rk.musicsleeptimer.plus"
1616
minSdk = 23
1717
targetSdk = 36
18-
versionCode = 36
19-
versionName = "3.0.5"
18+
versionCode = 37
19+
versionName = "3.1.0"
2020
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2121
@Suppress("UnstableApiUsage")
2222
androidResources.localeFilters += listOf(
@@ -39,15 +39,19 @@ android {
3939
keyAlias = signingProps["KEY_ALIAS"].toString()
4040
keyPassword = signingProps["KEY_PASSWORD"].toString()
4141
}
42-
}
43-
else {
42+
} else {
4443
android.buildTypes.getByName("release").signingConfig = null
4544
}
4645
}
4746

4847
buildTypes {
4948
release {
50-
signingConfig = signingConfigs.getByName("release")
49+
val signingFile = rootProject.file("signing.properties")
50+
signingConfig = if (signingFile.exists()) {
51+
signingConfigs.getByName("release")
52+
} else {
53+
null
54+
}
5155
isMinifyEnabled = true
5256
isShrinkResources = true
5357
isDebuggable = false

app/src/main/AndroidManifest.xml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
<uses-permission android:name="android.permission.INTERNET" />
66
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
77
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
8-
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
8+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"
9+
tools:ignore="ForegroundServicesPolicy" />
910

1011
<application
1112
android:appCategory="audio"
@@ -37,6 +38,21 @@
3738
android:value="true" />
3839
</service>
3940

41+
<service
42+
android:name=".services.AudioOutputTileService"
43+
android:exported="true"
44+
android:icon="@drawable/ic_audio_output"
45+
android:label="@string/audio_output"
46+
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
47+
<intent-filter>
48+
<action android:name="android.service.quicksettings.action.QS_TILE" />
49+
</intent-filter>
50+
51+
<meta-data
52+
android:name="android.service.quicksettings.TILE"
53+
android:value="false" />
54+
</service>
55+
4056
<receiver
4157
android:name=".receivers.SleepNotificationReceiver"
4258
android:exported="false" />
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.d4rk.musicsleeptimer.plus.services
2+
3+
import android.app.PendingIntent
4+
import android.content.ComponentName
5+
import android.content.Intent
6+
import android.graphics.drawable.Icon
7+
import android.os.Build
8+
import android.service.quicksettings.Tile
9+
import android.service.quicksettings.TileService
10+
import android.util.Log
11+
import android.widget.Toast
12+
import androidx.annotation.RequiresApi
13+
import com.d4rk.musicsleeptimer.plus.R
14+
15+
/**
16+
* Quick Settings tile that opens the native Android audio output picker dialog.
17+
*
18+
* The tile interacts with SystemUI by sending a broadcast that triggers the
19+
* system dialog used to switch between audio routes such as headphones,
20+
* speakers, and Bluetooth devices.
21+
*/
22+
@RequiresApi(Build.VERSION_CODES.N)
23+
class AudioOutputTileService : TileService() {
24+
companion object {
25+
private const val TAG = "AudioOutputTileService"
26+
private const val ACTION_MEDIA_OUTPUT =
27+
"com.android.systemui.action.LAUNCH_SYSTEM_MEDIA_OUTPUT_DIALOG"
28+
private const val PACKAGE_SYSTEMUI = "com.android.systemui"
29+
private const val RECEIVER_CLASS =
30+
"com.android.systemui.media.dialog.MediaOutputDialogReceiver"
31+
}
32+
33+
override fun onStartListening() {
34+
super.onStartListening()
35+
updateTile()
36+
}
37+
38+
override fun onClick() {
39+
super.onClick()
40+
openMediaOutputDialog()
41+
}
42+
43+
private fun openMediaOutputDialog() {
44+
try {
45+
val intent = Intent(ACTION_MEDIA_OUTPUT).apply {
46+
component = ComponentName(PACKAGE_SYSTEMUI, RECEIVER_CLASS)
47+
}
48+
49+
val pendingIntent = PendingIntent.getBroadcast(
50+
this, 0, intent, PendingIntent.FLAG_IMMUTABLE
51+
)
52+
53+
pendingIntent.send()
54+
} catch (exception: Exception) {
55+
val errorMessage =
56+
"Failed to open audio output dialog: ${exception.javaClass.simpleName}: ${exception.message}"
57+
Log.e(TAG, errorMessage, exception)
58+
showToast(errorMessage)
59+
}
60+
}
61+
62+
private fun updateTile() {
63+
val tile = qsTile ?: return
64+
tile.label = getString(R.string.audio_output)
65+
tile.icon = Icon.createWithResource(this, R.drawable.ic_audio_output)
66+
tile.state = Tile.STATE_ACTIVE
67+
tile.updateTile()
68+
}
69+
70+
private fun showToast(message: String) {
71+
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
72+
}
73+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:width="24dp"
4+
android:height="24dp"
5+
android:viewportWidth="24.0"
6+
android:viewportHeight="24.0"
7+
android:tint="#FFFFFF">
8+
<path
9+
android:fillColor="#FFFFFF"
10+
android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z" />
11+
</vector>

app/src/main/res/values-ar-rEG/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
<resources>
33
<string name="tile_subtitle">اضغط على البدء</string>
44
<string name="app_description">اضبط موسيقاك على التوقف بعد أن تغفو</string>
5+
<string name="audio_output">مخرج الصوت</string>
56
</resources>

app/src/main/res/values-bg-rBG/strings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
<resources>
33
<string name="app_description">Настройте музиката си да спира, след като заспите.</string>
44
<string name="tile_subtitle">Докоснете, за да започнете</string>
5-
</resources>
5+
<string name="audio_output">Аудио изход</string>
6+
</resources>

app/src/main/res/values-bn-rBD/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
<resources>
33
<string name="tile_subtitle">শুরু করতে আলতো চাপুন</string>
44
<string name="app_description">আপনি ঘুমিয়ে পড়ার পরে আপনার সংগীত বন্ধ করুন</string>
5+
<string name="audio_output">অডিও আউটপুট</string>
56
</resources>

app/src/main/res/values-de-rDE/strings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
<resources>
33
<string name="tile_subtitle">Tippe, um zu starten</string>
44
<string name="app_description">Stellen Sie Ihre Musik so ein, dass sie nach dem Einschlafen stoppt.</string>
5-
</resources>
5+
<string name="audio_output">Audioausgabe</string>
6+
</resources>

app/src/main/res/values-es-rGQ/strings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
<resources>
33
<string name="tile_subtitle">Toca para empezar</string>
44
<string name="app_description">Configure su música para que se detenga después de quedarse dormido.</string>
5-
</resources>
5+
<string name="audio_output">Salida de audio</string>
6+
</resources>

0 commit comments

Comments
 (0)