diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1d8320f14..03a801129 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -279,6 +279,23 @@ + + + + + + + + + + + + { + // Reiniciar la grabación para aplicar el nuevo estado del motor + restartRecording() + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/me/timschneeberger/rootlessjamesdsp/utils/Constants.kt b/app/src/main/java/me/timschneeberger/rootlessjamesdsp/utils/Constants.kt index b367b8b93..527696974 100644 --- a/app/src/main/java/me/timschneeberger/rootlessjamesdsp/utils/Constants.kt +++ b/app/src/main/java/me/timschneeberger/rootlessjamesdsp/utils/Constants.kt @@ -7,6 +7,12 @@ object Constants { const val PREF_APP = "application" const val PREF_VAR = "variable" + + + const val ACTION_WIDGET_CLICK = "me.timschneeberger.rootlessjamesdsp.ACTION_WIDGET_CLICK" + + + // DSP-relevant preference namespaces const val PREF_BASS = "dsp_bass" const val PREF_COMPANDER = "dsp_compander" @@ -45,4 +51,6 @@ object Constants { // Intent extras const val EXTRA_SAMPLE_RATE = BuildConfig.APPLICATION_ID + ".extra.service.SAMPLE_RATE" + + const val ACTION_ENGINE_STATE_CHANGED = "me.timschneeberger.rootlessjamesdsp.ACTION_ENGINE_STATE_CHANGED" } \ No newline at end of file diff --git a/app/src/main/java/me/timschneeberger/rootlessjamesdsp/utils/EngineUtils.kt b/app/src/main/java/me/timschneeberger/rootlessjamesdsp/utils/EngineUtils.kt index f0e5c2bff..90ab22d47 100644 --- a/app/src/main/java/me/timschneeberger/rootlessjamesdsp/utils/EngineUtils.kt +++ b/app/src/main/java/me/timschneeberger/rootlessjamesdsp/utils/EngineUtils.kt @@ -31,14 +31,22 @@ object EngineUtils : KoinComponent { } preferences.set(R.string.key_powered_on, isOn) return + } sdkAbove(Build.VERSION_CODES.Q) { // Rootless - if (!isOn) + if (!isOn) { RootlessAudioProcessorService.stop(this) - else - launchService(activityStarter) + } else { + RootlessAudioProcessorService.start(this, null) + } } + + // Guardar el estado del motor en las preferencias SIEMPRE + preferences.set(R.string.key_powered_on, isOn) + } + fun isEngineEnabled(context: Context): Boolean { + return preferences.get(R.string.key_powered_on, false, Boolean::class) } } \ No newline at end of file diff --git a/app/src/main/java/me/timschneeberger/rootlessjamesdsp/widget/EngineToggleWidgetProvider.kt b/app/src/main/java/me/timschneeberger/rootlessjamesdsp/widget/EngineToggleWidgetProvider.kt new file mode 100644 index 000000000..f61003232 --- /dev/null +++ b/app/src/main/java/me/timschneeberger/rootlessjamesdsp/widget/EngineToggleWidgetProvider.kt @@ -0,0 +1,62 @@ +package me.timschneeberger.rootlessjamesdsp.widget + +import android.app.PendingIntent +import android.appwidget.AppWidgetManager +import android.appwidget.AppWidgetProvider +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.widget.RemoteViews +import me.timschneeberger.rootlessjamesdsp.R +import me.timschneeberger.rootlessjamesdsp.utils.Constants +import me.timschneeberger.rootlessjamesdsp.utils.EngineUtils +import timber.log.Timber + +class EngineToggleWidgetProvider : AppWidgetProvider() { + + override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { + for (appWidgetId in appWidgetIds) { + updateWidget(context, appWidgetManager, appWidgetId) + } + } + + override fun onReceive(context: Context, intent: Intent) { + super.onReceive(context, intent) + + when (intent.action) { + Constants.ACTION_ENGINE_STATE_CHANGED, + Constants.ACTION_SERVICE_STARTED, + Constants.ACTION_SERVICE_STOPPED -> { + val appWidgetManager = AppWidgetManager.getInstance(context) + val thisWidget = ComponentName(context, EngineToggleWidgetProvider::class.java) + val appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget) + onUpdate(context, appWidgetManager, appWidgetIds) + } + } + } + + private fun updateWidget(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int) { + Timber.d("Updating widget with ID: $appWidgetId") + + val views = RemoteViews(context.packageName, R.layout.widget_engine_toggle) + + val iconResource = if (EngineUtils.isEngineEnabled(context)) { + R.drawable.ic_engine_on + } else { + R.drawable.ic_engine_off + } + views.setImageViewResource(R.id.widget_engine_icon, iconResource) + + val intent = Intent(context, WidgetActionReceiver::class.java) + intent.action = Constants.ACTION_WIDGET_CLICK + val pendingIntent = PendingIntent.getBroadcast( + context, + 0, + intent, + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE + ) + views.setOnClickPendingIntent(R.id.widget_engine_icon, pendingIntent) + + appWidgetManager.updateAppWidget(appWidgetId, views) + } +} \ No newline at end of file diff --git a/app/src/main/java/me/timschneeberger/rootlessjamesdsp/widget/WidgetActionReceiver.kt b/app/src/main/java/me/timschneeberger/rootlessjamesdsp/widget/WidgetActionReceiver.kt new file mode 100644 index 000000000..e5a4514aa --- /dev/null +++ b/app/src/main/java/me/timschneeberger/rootlessjamesdsp/widget/WidgetActionReceiver.kt @@ -0,0 +1,29 @@ +package me.timschneeberger.rootlessjamesdsp.widget + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import androidx.localbroadcastmanager.content.LocalBroadcastManager +import me.timschneeberger.rootlessjamesdsp.utils.Constants +import me.timschneeberger.rootlessjamesdsp.utils.EngineUtils +import me.timschneeberger.rootlessjamesdsp.utils.EngineUtils.toggleEnginePower // <-- Correct import +import timber.log.Timber + +class WidgetActionReceiver : BroadcastReceiver() { + + + override fun onReceive(context: Context, intent: Intent) { + Timber.d("Widget action received") + Timber.d("WidgetActionReceiver: onReceive() triggered") // Add this log + when (intent.action) { + Constants.ACTION_WIDGET_CLICK -> { // Maneja la acción del widget + Timber.d("Alternando el estado del motor: ${!EngineUtils.isEngineEnabled(context)}") + context.toggleEnginePower(!EngineUtils.isEngineEnabled(context)) + + // Notificar al servicio sobre el cambio de estado + val updateIntent = Intent(Constants.ACTION_ENGINE_STATE_CHANGED) + context.sendBroadcast(updateIntent) // Utilizar sendBroadcast() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_engine_off.xml b/app/src/main/res/drawable/ic_engine_off.xml new file mode 100644 index 000000000..860643aa1 --- /dev/null +++ b/app/src/main/res/drawable/ic_engine_off.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_engine_on.xml b/app/src/main/res/drawable/ic_engine_on.xml new file mode 100644 index 000000000..7308fe42e --- /dev/null +++ b/app/src/main/res/drawable/ic_engine_on.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/widget_preview.xml b/app/src/main/res/drawable/widget_preview.xml new file mode 100644 index 000000000..1322802fc --- /dev/null +++ b/app/src/main/res/drawable/widget_preview.xml @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_dsp_main.xml b/app/src/main/res/layout/activity_dsp_main.xml index 4b4110eb7..c174daf36 100644 --- a/app/src/main/res/layout/activity_dsp_main.xml +++ b/app/src/main/res/layout/activity_dsp_main.xml @@ -50,9 +50,12 @@ android:id="@+id/power_toggle" android:layout_width="wrap_content" android:layout_height="wrap_content" - app:layout_anchor="@id/bar" - app:srcCompat="@drawable/ic_twotone_power_settings_24dp" + android:contentDescription="@string/power_button_alt" android:hapticFeedbackEnabled="true" - android:contentDescription="@string/power_button_alt" /> + android:rotation="-25" + android:rotationX="37" + android:rotationY="33" + app:layout_anchor="@id/bar" + app:srcCompat="@drawable/ic_twotone_power_settings_24dp" /> \ No newline at end of file diff --git a/app/src/main/res/layout/widget_engine_toggle.xml b/app/src/main/res/layout/widget_engine_toggle.xml new file mode 100644 index 000000000..c80ca33e4 --- /dev/null +++ b/app/src/main/res/layout/widget_engine_toggle.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6e109ec2a..9bc312b71 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -650,4 +650,6 @@ The JamesDSP magisk package installed on your device is outdated and not supported by this app anymore.\n\nPlease retrieve the latest JamesDSP magisk package ZIP and install it via Magisk.\nNote that the magisk package may replace this app with the official JamesDSP app.\n\nDo you want to visit the download website for the Magisk packages now? Failed to start. The installed JamesDSP magisk package is too old and not supported by this app anymore. + + Toggle audio processing engine diff --git a/app/src/main/res/xml/widget_engine_toggle_info.xml b/app/src/main/res/xml/widget_engine_toggle_info.xml new file mode 100644 index 000000000..91fda58e3 --- /dev/null +++ b/app/src/main/res/xml/widget_engine_toggle_info.xml @@ -0,0 +1,11 @@ + + + \ No newline at end of file