Android stop foreground service executes onStartCommand - android

Why calling context.stopService(stopIntent) is going to execute onStartCommand am i missing something?
i had to do this in the onStartCommand
if (ACTION_STOP_SERVICE == intent?.action) { stopSelf() }
While the doc said specifically this:
onStartCommand Called by the system every time a client explicitly
starts the service by calling Context.startService
The code sample
#AndroidEntryPoint
class MyService : Service() {
private val ACTION_STOP_SERVICE: String = "ACTION_STOP_SERVICE"
private val ACTION_START_SERVICE: String = "ACTION_START_SERVICE"
#OptIn(InternalCoroutinesApi::class)
#ExperimentalCoroutinesApi
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (ACTION_START_SERVICE == intent?.action) {
// Start mqtt client "org.eclipse.paho:org.eclipse.paho.client"
}
if (ACTION_STOP_SERVICE == intent?.action) {
mqtt.disconnect()
stopSelf()
}
val stopIntent = Intent(this.applicationContext, BPSMqttService::class.java)
stopIntent.action = ACTION_STOP_SERVICE
val pStopIntent =
PendingIntent.getService(
BPSApp.instance.applicationContext,
0,
stopIntent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
val notificationIntent =
Intent(this.applicationContext, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this.applicationContext,
0, notificationIntent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
val notification =
NotificationCompat.Builder(this.applicationContext, SERVICE_CHANNEL_ID)
.setContentTitle("My service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_alarms_sync)
.setContentIntent(pendingIntent)
.addAction(0, "Stop", pStopIntent)
.build()
startForeground(1, notification)
return START_STICKY
}
override fun onDestroy() {
try {
super.onDestroy()
Log.d("MyService ", "onDestroy is done")
} catch (ex: Throwable) {
Log.d("MyService ", "onDestroy ${ex.message}")
}
}
override fun onCreate() {
try {
super.onCreate()
Log.d("MyService ", "nCreate is done")
} catch (ex: Throwable) {
Log.d("MyService ", "onCreate ${ex.message}")
}
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
}
And in other places other than the notification i am doing this to stop
val stopIntent = Intent(BPSApp.instance.applicationContext, BPSMqttService::class.java)
stopIntent.action = "ACTION_STOP_SERVICE"
BPSApp.instance.applicationContext.stopService(stopIntent)
And doing this to start
val startIntent = Intent(BPSApp.instance.applicationContext, BPSMqttService::class.java)
startIntent.action = "ACTION_START_SERVICE"
BPSApp.instance.applicationContext.startForegroundService(startIntent);

It looks like you are seeing onStartCommand() being called as a result of your Notification.
The notification action "stop" will call startService(), so that's what you are seeing. In the other places in the code, when you call stopService(), onStartCommand() will not be called.

Related

How to invoke a method on a foreground service by clicking on a notification action?

I have a foreground service. It does some async work in the background and periodically issues a notification asking the user if the work should be stopped.
The notification has a button "Yes, please" and when clicked it must invoke stopAction method.
The code below is where I'm stuck. I'm maybe way off and this can't be done. Any advice?
MainService.kt
...
override fun onCreate() {
subscribeToStopActionRequest()
}
private fun subscribeToStopActionRequest () {
var eventReceiverHelper = EventReceiverHelper { stopAction() }
val filter = IntentFilter().apply {
addAction("${packageName}.stop_action_request")
}
registerReceiver(eventReceiverHelper, filter)
}
private fun stopAction () {
...
}
private fun showNotification () {
val intent = Intent(this, EventService::class.java)
val pendingIntent: PendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)
var notification = NotificationCompat.Builder(this, state.notificationChannelId)
.setContentTitle("Want to stop?")
.addAction(R.drawable.stop_icon, "Yes, please", pendingIntent)
.build()
with(NotificationManagerCompat.from(this)) {
notify(1, notification)
}
}
Event receiver helper
class EventReceiverHelper(val cb: () -> Unit): BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
cb()
}
}
Define a constant:
private const val EXTRA_STOP = "stop";
Then create an intent for your service and put an extra flag:
val intent = Intent(context, YourService::class.java);
intent.putExtra(EXTRA_STOP, true);
Now you can create a pending intent as your handler:
val pendingIntent: PendingIntent = PendingIntent.getService(context, YOUR_REQUEST_CODE, intent, PendingIntent.FLAG_IMMUTABLE)
This pending intent will trigger the onStartCommand method on your service, where you can check whether the stop flag was set.
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (intent != null && intent.getBooleanExtra(EXTRA_STOP, false)) {
stopAction()
}
...
}

How to track the removal of the application and send a notification?

There is a task to make it so that when an application is deleted from the phone, my application sends a notification: "application name" has been deleted.
I do it like this:
Manifest
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="servicereload" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name=".MyService"
android:enabled="true"
android:exported="true" >
</service>
MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val notificationManagerCompat = NotificationManagerCompat.from(this)
notificationManagerCompat.cancelAll()
val serviceIntent = Intent(this, MyService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ContextCompat.startForegroundService(this, serviceIntent)
} else {
startService(Intent(this, MyService::class.java))
}
val intentFilter = IntentFilter()
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED)
intentFilter.addDataScheme("package")
registerReceiver(MyReceiver(), intentFilter)
}
}
MyReceiver
class MyReceiver: BroadcastReceiver() {
val CHANNEL_ID = "ServiceChannel"
#SuppressLint("RemoteViewLayout")
override fun onReceive(context: Context?, intent: Intent?) {
var packageName = ""
try {
packageName = Objects.requireNonNull(intent!!.data)!!.encodedSchemeSpecificPart
Toast.makeText(context, "USER UNINSTALL : $packageName", Toast.LENGTH_SHORT).show()
Log.i("MyLog", "USER UNINSTALL : $packageName")
} catch (ex: Exception) {
Log.i("MyLog", "Exception: $ex")
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(CHANNEL_ID, "Channel", NotificationManager.IMPORTANCE_DEFAULT)
val notificationManager = context!!.getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(notificationChannel)
}
val notifyIntent = Intent(context, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val notifyPendingIntent = PendingIntent.getActivity(context, 200, notifyIntent, 0)
val builder: NotificationCompat.Builder = NotificationCompat.Builder(context!!, CHANNEL_ID).apply {
setSmallIcon(R.mipmap.ic_launcher)
setContentTitle(context.getString(R.string.app_name))
setContentText("App ${packageName.substringAfterLast(".")} has been deleted")
priority = NotificationCompat.PRIORITY_DEFAULT
setContentIntent(notifyPendingIntent)
}
with(NotificationManagerCompat.from(context!!)) {
notify(200, builder.build())
}
}
}
MyService
class MyService : Service() {
override fun onBind(intent: Intent?): IBinder? {
return null
}
#RequiresApi(api = Build.VERSION_CODES.N)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.i("MyLog", "onStartCommand()")
someTask()
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
Log.i("MyLog", "Service onDestroy()")
val intent = Intent()
intent.action = "servicereload"
intent.setClass(this, MyReceiver::class.java)
this.sendBroadcast(intent)
}
override fun onCreate() {
super.onCreate()
Log.i("MyLog", "Service onCreate()")
}
override fun onTaskRemoved(rootIntent: Intent?) {
val intent = Intent(applicationContext, this.javaClass)
intent.setPackage(packageName)
val pendingIntent = PendingIntent.getService(applicationContext, 1, intent, PendingIntent.FLAG_ONE_SHOT)
val alarmManager = applicationContext.getSystemService(ALARM_SERVICE) as AlarmManager
alarmManager.set(AlarmManager.ELAPSED_REALTIME,1000,pendingIntent)
super.onTaskRemoved(rootIntent)
}
private fun someTask() {
Log.i("MyLog", "Service someTask()")
// val intentFilter = IntentFilter()
// intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED)
// intentFilter.addDataScheme("package")
// registerReceiver(MyReceiver(), intentFilter)
Thread {
for (i in 1..50) {
Log.i("MyLog", "Service i = $i")
try {
TimeUnit.SECONDS.sleep(1)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
// stopSelf()
}.start()
}
}
someTask() method, just to see if the service is up and running. I check on API 29+ emulators, if I manage to delete the application before 10 seconds, it works well but starts the second service in parallel, which is not good, and I don’t understand why?! If there is nothing to do, after 10 seconds it throws android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{ab817c0 u0 com.testappremovel/.MyService} If I remove onDestroy () or onTaskRemoved () in the service, there is no problem with parallel launch, but after 10 seconds it is cut down in any case and, accordingly, does not turn back on. I also have methods for determining the name and icon of the application by package in order to display them in the notification, but of course, when the application is already remote, I cannot get this data. Please tell me, how to do it right, so that everything works as it should?

Handler() works slower in Service when sreen is off

I made a Service that is actually a simple background counter.
It just pluses 1 to a last number and then it goes to UI.
My previous problem was about the fact that Handler() sometimes worked very slow when smartphone was turned off or if it wasn't charging. Recently I found the same problem in this forum.
I added PowerManager.WakeLock to my Service and everything worked fine...
But I decided to test it for a longer time and started the app simultaneously on three smartphones and leave them for about an hour and a half. When I returned I have seen a complete difference between three of them.
The first shows 5100 (1 h 25 mins), the second - 2800 (46 mins) and the third - 5660 (1 h 34 mins).
I was pretty sure that wakelock will do the job correctly but now I don't know what happened there.
Here is a code of my Service:
class Timer_Service : Service() {
companion object {
val PARAM_OUT_MSG = "0"
}
var i = 0
private lateinit var wakeLock: PowerManager.WakeLock
private lateinit var mHandler: Handler
private lateinit var mRunnable: Runnable
override fun onBind(p0: Intent?): IBinder? {
TODO("not implemented")
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
wakeLock = powerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
"ExampleApp:Wakelock"
)
wakeLock.acquire()
val broadcastIntent = Intent()
broadcastIntent.action = "com.example.infocell.action.RESPONSE"
mHandler = Handler()
mRunnable = Runnable {
showOrderNumber()
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT)
broadcastIntent.putExtra(PARAM_OUT_MSG, i.toString())
sendBroadcast(broadcastIntent)
}
mHandler.postDelayed(mRunnable, 1000)
return START_NOT_STICKY
}
override fun onDestroy() {
super.onDestroy()
mHandler.removeCallbacks(mRunnable)
}
private fun showOrderNumber() {
i += 1
mHandler.postDelayed(mRunnable, 1000)
}
}
Manifest also contains <uses-permission android:name="android.permission.WAKE_LOCK" />
Finally after various tests I got the most precise way to make a simple counter. Instead of relatively reliable Handle() method I would recommend to use Timer(). It worked absolutely equal on all of my four smartphones. Wakelock is also required for that. I would also test JobScheduler() and CountDownTimer() for getting all testing results but I am glad with timer so far.
I will share my code if someone is looking for solution for such tasks.
class Timer_Service : Service() {
companion object {
val PARAM_OUT_MSG = "0"
}
var i = 0
private lateinit var wakeLock: PowerManager.WakeLock
private lateinit var timer: Timer
override fun onBind(p0: Intent?): IBinder? {
return null
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
wakeLock = powerManager.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK,
"ExampleApp:Wakelock"
)
wakeLock.acquire()
val broadcastIntent = Intent()
broadcastIntent.action = "com.example.infocell.action.RESPONSE"
timer = Timer()
val task = object : TimerTask() {
override fun run() {
if (Trigger.getTrigger() == 0){
showOrderNumber()
// bring 'i' value to main activity
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT)
broadcastIntent.putExtra(PARAM_OUT_MSG, i.toString())
sendBroadcast(broadcastIntent)
}
}
}
timer.schedule(task,0, 1000)
return START_STICKY
}
override fun onCreate() {
super.onCreate()
var notification = createNotification()
startForeground(1, notification)
}
private fun createNotification(): Notification {
val notificationChannelId = "ENDLESS SERVICE CHANNEL"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager;
val channel = NotificationChannel(
notificationChannelId,
"My Service",
NotificationManager.IMPORTANCE_HIGH
).let {
it.description = "Service channel"
it.enableLights(true)
it.lightColor = Color.RED
it.enableVibration(true)
it.vibrationPattern = longArrayOf(100)
it
}
notificationManager.createNotificationChannel(channel)
}
val pendingIntent: PendingIntent = Intent(this, MainActivity::class.java).let { notificationIntent ->
PendingIntent.getActivity(this, 0, notificationIntent, 0)
}
val builder: Notification.Builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) Notification.Builder(
this,
notificationChannelId
) else Notification.Builder(this)
return builder
.setContentTitle("My Service")
.setContentText("Endless service working...")
.setContentIntent(pendingIntent)
.setSmallIcon(R.mipmap.ic_launcher)
.setTicker("Ticker text")
.setPriority(Notification.PRIORITY_HIGH) // for under android 26 compatibility
.build()
}
override fun onDestroy() {
super.onDestroy()
// Trigger is a separate kotlin class with variables
if (Trigger.getTrigger() == 1){
timer.cancel()
timer.purge()
}
}
private fun showOrderNumber() {
i += 1
}
}

Foreground service content intent not resuming the app but relaunching it

I've been browsing many topics about resuming an activity from a foreground service without finding any concrete answer to my problem.
I'm trying to put a foreground service in my app, and I want the app to be resumed when clicking on the service notification instead of relaunching it. I've tried using the getLaunchIntentForPackage() method from PackageManager, which is the closest to what I want to do.
However, the activity's onCreate is still being called when resuming the app by clicking on the notification.
So here is my question, how to resume an app from a notification's content intent?
I'm starting my ForegroundService in the activity's onStop so it gets called when the app is killed or sent to background.
override fun onStop() {
super.onStop()
Log.v(TAG, "onStop")
ForegroundService.startService(this, "Hellooooooo, here is the background")
}
ForegroundService
class ForegroundService: Service() {
companion object {
private const val CHANNEL_ID = "ForegroundServiceChannel"
fun startService(context: Context, message: String) {
val startIntent = Intent(context, ForegroundService::class.java)
startIntent.putExtra("inputExtra", message)
ContextCompat.startForegroundService(context, startIntent)
}
fun stopService(context: Context) {
val stopIntent = Intent(context, ForegroundService::class.java)
context.stopService(stopIntent)
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val input = intent!!.getStringExtra("inputExtra")
val launchIntent = packageManager.getLaunchIntentForPackage(APP_PACKAGE)
val contentIntent = PendingIntent.getActivity(applicationContext, 0,
launchIntent, 0)
val notification: Notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setContentIntent(contentIntent)
.setSmallIcon(R.drawable.ic_call_to_action)
.setOngoing(true)
.build()
startForeground(1, notification)
createNotificationChannel()
return START_NOT_STICKY
}
override fun onBind(p0: Intent?): IBinder? {
return null
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val serviceChannel = NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
)
val manager = getSystemService(
NotificationManager::class.java
)
manager?.createNotificationChannel(serviceChannel)
}
}
}
Try set in the manifest for activity android:launchMode="singleInstance".
Do not forget set some your action to your activity intent:
activityIntent.setAction(ACTION_STARTED_FROM_NOTIFICATION);
Override onNewIntent in the activity.
in onCreate and in onNewIntent do check
if(ACTION_STARTED_FROM_NOTIFICATION.equalsIgnoreCase(intent.getAction()))
{ do what you need }

Handling buttons inside android notifications

I added a button inside a notification
but I don't know how to have it call a function when it's clicked.
I tried an approach like this https://code.google.com/p/languagepickerwidget/source/browse/trunk/trunk/src/org/gnvo/langpicker/LangPicker.java since it's also using a RemoteViews object but nothing happens when I click the button.
This is what I currently have:
private void createNotification(){
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager notificationManager = (NotificationManager) getSystemService(ns);
Notification notification = new Notification(R.drawable.ic_launcher, null, System.currentTimeMillis());
RemoteViews notificationView = new RemoteViews(getPackageName(), R.layout.notification_switch);
//the intent that is started when the notification is clicked (works)
Intent notificationIntent = new Intent(this, SettingsActivity.class);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentView = notificationView;
notification.contentIntent = pendingNotificationIntent;
notification.flags |= Notification.FLAG_NO_CLEAR;
//this is the intent that is supposed to be called when the button is clicked
Intent switchIntent = new Intent(this, switchButtonListener.class);
PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(this, 0, switchIntent, 0);
notificationView.setOnClickPendingIntent(R.id.buttonswitch, pendingSwitchIntent);
notificationManager.notify(1, notification);
}
public static class switchButtonListener extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("TAG", "test");
}
}
I can start an activity with the button but I didn't succeed to have it call a simple function. What would be the best way to do this?
Edit:
I found out that I had to register "switchButtonListener" in AndroidManifest.xml
<receiver android:name="SettingsActivity$switchButtonListener" />
Source: Android Activity with no GUI
It works now.
I found out that I had to register "switchButtonListener" in AndroidManifest.xml
<receiver android:name="SettingsActivity$switchButtonListener" />
Source: Android Activity with no GUI
Later I found out that I can also use code like this to achieve the same thing without modifying the manifest.
switchButtonListener = new SwitchButtonListener();
registerReceiver(switchButtonListener, new IntentFilter(SWITCH_EVENT));
.
public class switchButtonListener extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("TAG", "test");
}
}
.
Intent switchIntent = new Intent(LangService.SWITCH_EVENT);
PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(context, 0, switchIntent, 0);
notificationView.setOnClickPendingIntent(R.id.buttonswitch, pendingSwitchIntent);
Note that this way I can declare the switchButtonListener class without the static attribute (if not static, it would crash in the previous example) giving me much more flexibility.
Don't forget to call unregisterReceiver() later.
In Kotlin you can register a receiver with an anonymous class.
const val STOP_ALARM_ACTION = "STOP_ALARM"
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// ...
registerReceiver(object : BroadcastReceiver() {
override fun onReceive(p0: Context?, p1: Intent?) {
stopAlarm();
}
}, IntentFilter(STOP_ALARM_ACTION))
}
private fun playAlarm() {
ringtone.stop()
val stopIntent = Intent(STOP_ALARM_ACTION)
val stopPendingIntent = PendingIntent.getBroadcast(this, 0, stopIntent, 0)
val notification = NotificationCompat.Builder(this, "Timer1_ALARM")
// ...
.addAction(android.R.drawable.ic_delete, "Stop", stopPendingIntent)
.build()
// ...
}
private fun stopAlarm() {
ringtone.stop()
}
}
I believe it is important to also unregister action. So my way of writing this nicely is:
val playButtonAction = register("play_button_action") {
main.looper?.player?.asStarted { it.stop() }
}
so you can do:
override fun onDestroy() {
super.onDestroy()
unregister(playButtonAction)
}
using:
fun Context.register(action: String, function: () -> void): BroadcastReceiver =
register(IntentFilter(action)) { _, _ -> function() }
fun Context.register(intent: IntentFilter,
function: (Intent, BroadcastReceiver) -> void): BroadcastReceiver {
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) = function(intent, this)
}
registerReceiver(receiver, intent)
return receiver
}
fun Context.unregister(receiver: BroadcastReceiver) {
unregisterReceiver(receiver)
}
And also u use playButtonAction:
val stopIntent = PendingIntent.getBroadcast(this, 0, Intent("play_button_action"),
FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE);
This is my complete Service class:
class LooperPlayNotificationService : Service() {
companion object {
val NOTIFICATIONS_CHANNEL = "${app.packageName} notifications"
}
override fun onBind(intent: Intent): IBinder? = null
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
start()
return START_STICKY
}
override fun onCreate() {
super.onCreate()
start()
}
private val playButtonActionId = "play_button_action"
private lateinit var playButtonAction: BroadcastReceiver
private var started = false
// https://stackoverflow.com/questions/6619143/start-sticky-foreground-android-service-goes-away-without-notice
// There's a bug in 2.3 (not sure if it was fixed yet) where when a Service is killed and restarted,
// its onStartCommand() will NOT be called again. Instead you're going to have to do any setting up in onCreate()
private fun start() {
if (started) return
started = true
startForeground(647823876, createNotification())
playButtonAction = register(playButtonActionId) {
main.looper?.player?.asStarted { it.stop() }
}
}
override fun onDestroy() {
super.onDestroy()
unregister(this.playButtonAction)
}
private fun createNotification() = Builder(this, NOTIFICATIONS_CHANNEL)
.setSmallIcon(outline_all_inclusive_24)
.setContentIntent(getActivity(this, 0, Intent<InstrumentsActivity>(this),
FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE))
.setPriority(PRIORITY_DEFAULT)
.setAutoCancel(false).setOngoing(true)
.addAction(ic_stop_circle_black_24dp, "Stop",
getBroadcast(this, 0, Intent(playButtonActionId),
FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE))
.setContentText(getString(R.string.app_name))
.setContentText(main.looper?.preset?.item?.value?.title?.value).build()
}

Categories

Resources