diff --git a/app/release/com.cliambrown.easynoise-v0.5-release.aab b/app/release/com.cliambrown.easynoise-v0.5-release.aab new file mode 100644 index 0000000..7a2eb06 Binary files /dev/null and b/app/release/com.cliambrown.easynoise-v0.5-release.aab differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b06d270..b7f040c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,6 +15,20 @@ android:supportsRtl="true" android:theme="@style/Theme.EasyNoise"> + + + + + + + - @@ -80,10 +93,10 @@ android:exported="true"> + - \ No newline at end of file diff --git a/app/src/main/java/com/cliambrown/easynoise/EasyNoiseWidget.kt b/app/src/main/java/com/cliambrown/easynoise/EasyNoiseWidget.kt index a5ad103..aa69924 100644 --- a/app/src/main/java/com/cliambrown/easynoise/EasyNoiseWidget.kt +++ b/app/src/main/java/com/cliambrown/easynoise/EasyNoiseWidget.kt @@ -10,7 +10,6 @@ import android.widget.RemoteViews import com.cliambrown.easynoise.helpers.* import android.app.PendingIntent import android.content.ComponentName -import android.os.Build /** * Implementation of App Widget functionality. @@ -49,7 +48,7 @@ class EasyNoiseWidget : AppWidgetProvider() { if (context == null) { return } - Util.startPlayerService(context, TOGGLE_PLAY) + PlayerService.start(context, TOGGLE_PLAY) } fun setPlaying(context: Context?, isPlaying: Boolean) { diff --git a/app/src/main/java/com/cliambrown/easynoise/MainActivity.kt b/app/src/main/java/com/cliambrown/easynoise/MainActivity.kt index ebfa1f7..f7caf6f 100644 --- a/app/src/main/java/com/cliambrown/easynoise/MainActivity.kt +++ b/app/src/main/java/com/cliambrown/easynoise/MainActivity.kt @@ -1,7 +1,6 @@ package com.cliambrown.easynoise import android.Manifest -import android.animation.AnimatorListenerAdapter import android.content.* import androidx.appcompat.app.AppCompatActivity import android.os.Bundle @@ -17,7 +16,6 @@ import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import android.content.Intent import android.net.Uri -import android.util.Log import android.view.Menu import android.view.animation.Animation import androidx.constraintlayout.widget.ConstraintLayout diff --git a/app/src/main/java/com/cliambrown/easynoise/NotificationUtils.kt b/app/src/main/java/com/cliambrown/easynoise/NotificationUtils.kt index 4b2b106..2fbc6d0 100644 --- a/app/src/main/java/com/cliambrown/easynoise/NotificationUtils.kt +++ b/app/src/main/java/com/cliambrown/easynoise/NotificationUtils.kt @@ -11,7 +11,6 @@ import android.os.Build import android.view.View import android.widget.RemoteViews import androidx.core.app.NotificationCompat -import androidx.core.content.ContextCompat import com.cliambrown.easynoise.helpers.* class NotificationUtils(base: Context?) : ContextWrapper(base) { diff --git a/app/src/main/java/com/cliambrown/easynoise/OutsidePauseReceiver.kt b/app/src/main/java/com/cliambrown/easynoise/OutsidePauseReceiver.kt index b93d4c0..d43e4cc 100644 --- a/app/src/main/java/com/cliambrown/easynoise/OutsidePauseReceiver.kt +++ b/app/src/main/java/com/cliambrown/easynoise/OutsidePauseReceiver.kt @@ -11,44 +11,46 @@ class OutsidePauseReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { - val action = intent.action - var playerAction: String? = null - - when (action) { + val playerAction = when (intent.action) { PHONE_STATE -> { // Phone call start/stop val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE) val states = arrayOf("IDLE", "RINGING", "OFFHOOK") if (!states.contains(state)) return if (state == "IDLE") { - playerAction = CALL_ENDED + CALL_ENDED } else { - playerAction = CALL_STARTED + CALL_STARTED } } AudioManager.ACTION_AUDIO_BECOMING_NOISY -> { // Headphones unplugged / disconnected - playerAction = AUDIO_BECOMING_NOISY + AUDIO_BECOMING_NOISY } HEADSET_PLUG -> { // Wired headset monitoring val state = intent.getIntExtra("state", 0) - if (state > 0) playerAction = HEADPHONES_CONNECTED + if (state > 0) HEADPHONES_CONNECTED + else null } HEADSET_STATE_CHANGED -> { // Bluetooth monitoring val state = intent.getIntExtra("android.bluetooth.headset.extra.STATE", 0) - if (state == 2) playerAction = HEADPHONES_CONNECTED + if (state == 2) HEADPHONES_CONNECTED + else null } CONNECTION_STATE_CHANGED -> { // Bluetooth, works for Ice Cream Sandwich val state = intent.getIntExtra("android.bluetooth.profile.extra.STATE", 0) - if (state == 2) playerAction = HEADPHONES_CONNECTED + if (state == 2) HEADPHONES_CONNECTED + else null } + else -> null } if (playerAction != null) { PlayerService.start(context, playerAction) } + } } \ No newline at end of file diff --git a/app/src/main/java/com/cliambrown/easynoise/PlayerService.kt b/app/src/main/java/com/cliambrown/easynoise/PlayerService.kt index 8c20b30..b0d5c35 100644 --- a/app/src/main/java/com/cliambrown/easynoise/PlayerService.kt +++ b/app/src/main/java/com/cliambrown/easynoise/PlayerService.kt @@ -3,6 +3,7 @@ package com.cliambrown.easynoise import android.app.Activity import android.app.Service import android.content.Context +import android.content.ComponentName import android.content.Intent import android.content.IntentFilter import android.content.SharedPreferences @@ -12,6 +13,7 @@ import android.media.SoundPool import android.os.Binder import android.os.Build import android.os.IBinder +import android.service.quicksettings.TileService import com.cliambrown.easynoise.helpers.* import android.widget.Toast import kotlin.math.roundToInt @@ -38,6 +40,16 @@ class PlayerService : Service(), SoundPool.OnLoadCompleteListener { var outsidePauseReceiver: OutsidePauseReceiver? = null + companion object { + fun start(context: Context, action: String): Boolean { + Intent(context, PlayerService::class.java).setAction(action).run { + if (Build.VERSION.SDK_INT < 26) context.startService(this) + else context.startForegroundService(this) + } + return true + } + } + inner class LocalBinder : Binder() { // Return this instance of LocalService so clients can call public methods fun getService(): PlayerService = this@PlayerService @@ -156,7 +168,7 @@ class PlayerService : Service(), SoundPool.OnLoadCompleteListener { fun loadNoise() { val noise = getPrefs().getString("noise", "fuzz") currentNoise = noise - var resource: Int = when (noise) { + val resource: Int = when (noise) { resources.getString(R.string.fuzz) -> R.raw.fuzz resources.getString(R.string.gray) -> R.raw.grey_noise resources.getString(R.string.gray_2) -> R.raw.grey_noise_2 @@ -228,6 +240,12 @@ class PlayerService : Service(), SoundPool.OnLoadCompleteListener { wasPlaying = toPlaying getPrefs().edit().putBoolean("wasPlaying", toPlaying).apply() } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + TileService.requestListeningState( + this, + ComponentName(this, QSTileService::class.java.getName()) + ) + } } fun dismiss() { @@ -274,14 +292,4 @@ class PlayerService : Service(), SoundPool.OnLoadCompleteListener { } if (tempIsPlaying) play(false) } - - companion object { - fun start(context: Context, action: String): Boolean { - Intent(context, PlayerService::class.java).setAction(action).run { - if (Build.VERSION.SDK_INT < 26) context.startService(this) - else context.startForegroundService(this) - } - return true - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/cliambrown/easynoise/QSTileService.kt b/app/src/main/java/com/cliambrown/easynoise/QSTileService.kt new file mode 100644 index 0000000..90a9ef9 --- /dev/null +++ b/app/src/main/java/com/cliambrown/easynoise/QSTileService.kt @@ -0,0 +1,40 @@ +package com.cliambrown.easynoise + +import android.graphics.drawable.Icon +import android.os.Build +import android.service.quicksettings.Tile +import android.service.quicksettings.TileService +import androidx.annotation.RequiresApi +import com.cliambrown.easynoise.helpers.* + +@RequiresApi(Build.VERSION_CODES.N) +class QSTileService : TileService() { + + override fun onTileAdded() { + super.onTileAdded() + updateTile() + } + + override fun onClick() { + super.onClick() + if(qsTile.state == Tile.STATE_INACTIVE) { + PlayerService.start(applicationContext, PLAY) + } else { + PlayerService.start(applicationContext, PAUSE) + } + } + + override fun onStartListening() { + super.onStartListening() + updateTile() + } + + fun updateTile() { + val isPlaying = getSharedPreferences(applicationContext.packageName, 0) + .getBoolean("isPlaying", false) + val resource = if (isPlaying) R.drawable.notification_icon else R.drawable.paused_notification_icon + qsTile.setIcon(Icon.createWithResource(this, resource)) + qsTile.state = if (isPlaying) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE + qsTile.updateTile() + } +} \ No newline at end of file diff --git a/app/src/main/res/menu/main_toolbar.xml b/app/src/main/res/menu/main_toolbar.xml index 206869e..330da8e 100644 --- a/app/src/main/res/menu/main_toolbar.xml +++ b/app/src/main/res/menu/main_toolbar.xml @@ -1,7 +1,6 @@ -