I have an application which in turn runs a foreground service. The application has a start/stop button as part of its notification which as can be guessed starts and stops the foreground service. Upon clicking on the start button a Pending Intent gets triggered.
Consider the following scenario:
The application has been destroyed [removed from the recent items list] but the notification is still visible.
I am able to start and stop the foreground service even when the app has been destroyed, as on clicking the notification button triggers a Pending intent (which in turn call a broadcast receiver).
But, what I have observed is that after a day or two, upon clicking the buttons on the notification the pending intent is not triggered (that is the foreground service does not start). This begs the question, does pending intent have a lifetime after the encompassing application has been destroyed? Or am I missing something else here?
My pending intent call:
Intent notificationBroadcastIntent = new Intent(this, MyBroadcastReceiver.class);
PendingIntent playIntent = PendingIntent.getBroadcast(this, MY_REQUEST_CODE,
notificationBroadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
The Broadcast Receiver called by the pending intent (which in turn starts the foreground service):
#Override
public void onReceive(Context context, Intent intent) {
Log.i(MyBroadcastReceiver.class.getSimpleName(), "MyBroadcastReceiver called to update service notification");
if (isMyForegroundServiceRunning(MyForegroundService.class, context)) {
Intent stopIntent = new Intent(context, MyForegroundService.class);
stopIntent.setAction(STOP_SERVICE_ACTION);
context.startService(stopIntent);
} else {
Intent startIntent = new Intent(context, MyForegroundService.class);
startIntent.setAction(START_SERVICE_ACTION);
context.startService(startIntent);
}
}
PendingIntents do not expire. However, they are not persistent and will not survive a reboot of the device.
To see if the PendingIntent still exists, you can use the following adb command:
adb shell dumpsys activity intents
This lists all of the PendingIntents in the system. You can also look at the notifications using:
adb shell dumpsys notification
This will show all Notifications, including the PendingIntents that are set for them.
Related
I have am alarm manager through which i set a time to trigger on it by providing a broadcast receiver, onReceive method of broadcast receiver calls successfully but any idea how to launch app from onReceive if app is not running in foreground?
Menifest
<receiver
android:exported="true"
android:name=".AlarmReceiver" />
BroadcastReceiver
#Override
public void onReceive(Context context, Intent intent)
{
Intent scheduledIntent = new Intent(context, MainActivity.class);
scheduledIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(scheduledIntent);
}
MainActivity
AlarmManager alarmManager=(AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent=new Intent(this,AlarmReceiver.class);
PendingIntent pendingIntent=PendingIntent.getBroadcast(this,1000,intent,0);
alarmManager.set(AlarmManager.RTC_WAKEUP,timeInMillis,pendingIntent);
Kindly help
Thanks
It is basically a radio music stream using exoplayer , what we need is user set a time on which he want it to play , and when that time comes stream start playing automatically .
A background service will only run for one minute on Android 8.0+. For a music player, you will want a foreground service, where the associated Notification gives the user playback controls (e.g., pause, resume, stop).
First, you should use workManager
Also, Brodcastreciver has limits on different android versions doc
This is my requirement.
I have an application which can be force kill by user. I want this application to receive broadcast from other app to execute some task even it is forced kill.
I am trying to make another app with service which will send a broadcast in event 1 mins to my first application.
My first application should receive this broadcast even it is forced kill.
This is what I am trying to do.
in First app:
BroadcastReceiver dummy = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("broadcast Received","broadcast Received");
}
};
IntentFilter filter = new IntentFilter("com.action.blockapp");
registerReceiver(dummy,filter);
In my second app.
Intent intent = new Intent("com.action.blockapp");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.setPackage("com.example.myapplication2");
sendBroadcast(intent);
I am not able to receive the broadcast when my app is forced kill.
Please suggest.
My point . You need to declare revice in the service running in the background. Your specific revice declared in the manifest<receiver android:name=".service.NotifyReceiver" />
</application>
When the service is run. You can get notifications from revice like below
Intent intent1 = new Intent(context, NotifyReceiver.class);
intent1.setAction(action);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
Hope to help you!
You have registered your BroadcastReceiver dynamically, in code. When your app is force stopped, that code is no longer running and your BroadcastReceiver no longer exists. It is no longer registered.
You will need to create a proper class that extends BroadcastReceiver and create a manuifest entry <receiver> for that with an <intent-filter> that matches the broadcast Intent you are broadcasting.
I am bit new to android. I would like to know how to communicate with a foreground started service.
So, I got a Foreground service with a notification.
This notification has a (X) button to stop the service.
The service got a Static broadcastreceiver.
public static class NotificationStopButtonHandler extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Close Clicked",Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "In Closed");
// imposible to do context.stopForground(true) or
// to call any other private coded by me
}
}
So my question is :
Is BroadcastReceiver is the best way ?
If it is : How I can communicate with the service to call stopForeground in the broadcastReceiver ?
Thanks in advance for your responses.
Same question like mien... But I would like to know which are the other solution than broadcastReceiver. thx
In your notification you will have a PendingIntent for the X button. I presume you have built that PendingIntent with
PendingIntent.getBroadcast(/* ... */);
What you can do instead is to create a PendingIntent for your service
Intent intent = /* intent for starting your service */;
intent.putExtra("STOP_FOREGROUND", true);
PendingIntent.getService(context, requestCode, intent, flags);
and in the intent you pass to the PendingIntent you would add an extra (STOP_FOREGROUND). When this intent is fired, your service will get called in onStartCommand(). Here you check the intent and if it contains your extra, you know you're expected to call stopForeground.
Instead of broadcasts, you can use PendingIntent with an Intent to the Service and tell the Service to shut down. You assign the PendingIntent to the close button action and/or to the notifications onDelete call when you build the notification.
Assuming that you're starting the Service with the notification, you can put commands in the Intent to tell the service to stop itself. Service#onStartCommand will be called on the service with the new Intent. The service checks for the shutdown call and calls stopSelf() when done.
Basically, the reason this works is because there can only be one Service started. Every subsequent attempt to start the service will send the intent to Service#onStartCommand, but it will not restart the Service. Thus, this is a way you can send commands to the service through means outside of binding. Plus it's way cleaner than using broadcasts.
This is the scenario...
App is opened
User clicks on a button that starts a service.
(Service always is run in background and check recieving new data from server)
User presses home key and then long presses home key and clears application from task list completely.
Service continues to run, although app has closed.
I can determine whether that app has been killed or not by reading this link:
How to determine app is running from service
How can I start MainActivity(That its app compeltely killed) from the runnning service again when new data recieving from server(as an event) ?
You can broadcast an action and use a BroadCastReceiver to receive it and start the MainActivity from onReceive method of the BroadCastReceiver:
public void onReceive(Context context, ...)
{
Intent intent = new Intent(context,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
or from a service use:
Intent intent = new Intent(this,MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
In my app I have a notification in the task bar and when clicked it starts a new Activity view of my program. However when I try and use the stop button to stop my service from within this view, nothing happens. I am assuming when I press the notification button that it does not keep my ACTIVITY linked with the service.
When my app is first opened, the service is started by using the Intent below:
Intent svc = new Intent(this, StreamService.class);
startService(svc);
Then in the service:
//Intent passed when notification is selected.
Intent notificationIntent = new Intent(this, HomeActivity.class);
Any idea how to link back to my running service? Or perhaps bring the original activity/view back to the front when the notification is selected?
The Intent that you can attach to the notification should have a service intent, with a specific action. In your service's onStart method, you can check it's a close action, and then you can call stopSelf().
If the Activity you are opening from the notification is part of the same application as the service, then it is be able to stop the service. Try to use:
Intent svc = new Intent(this, StreamService.class);
stopService(svc);