I want to create application that can play a streaming music . When I press home my app can running in background but when I open another application that use more memory my app will stop and killed by android system . Anyone have another idea to run my music player app in background?
thank you
You have to implement a foreground service:
https://developer.android.com/guide/components/services.html#Foreground
A foreground service is a service that's considered to be something
the user is actively aware of and thus not a candidate for the system
to kill when low on memory. A foreground service must provide a
notification for the status bar, which is placed under the "Ongoing"
heading, which means that the notification cannot be dismissed unless
the service is either stopped or removed from the foreground.
Example:
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
Look the activity lifecycle :)
http://developer.android.com/guide/topics/fundamentals/activities.html
I think you must do a service.
Related
App is targeting to 27 and I am testing on android oreo 8.0 device.
compileSdkVersion 27
targetSdkVersion 27
When user clicks on the download button, app starts a foreground intent service and also notifies the user through a notification.
Within the onCreate of IntentService , app also fulfils the promise to call the startForeground(int id, Notification notification) method.
So,
//On click of download button
ContextCompat.startForegroundService(context, intent);
//Within the onCreate() of IntentService()
startForeground(id, notification);
In case when app is in foreground, everything works perfect. But when user swiped out and thus kills the app; I restart the download and it works, downloading starts; but android system displays a notification - "<#appname#> is running in background".
So user now can see two notification
one from my app showing the download progress and
another from android system, showing that my app is running in background.
Is this fine? How can I avoid the notification from android system?
Here is how I manage swipe out app kill:
#Override
public void onTaskRemoved(Intent rootIntent) {
Context localContext = getApplicationContext();
Intent restartServiceIntent = new Intent(localContext,
HandlePendingDownload.class);
restartServiceIntent.putExtra(DMConstants.ACTION_SWIPE_OUT, Boolean.TRUE);
restartServiceIntent.setPackage(getPackageName());
PendingIntent restartServicePendingIntent = PendingIntent.getBroadcast(
localContext, 1, restartServiceIntent,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) localContext
.getSystemService(Context.ALARM_SERVICE);
if (FWCompat.isKitKat_19_OrNewer()) {
alarmService.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 1900,
restartServicePendingIntent);
} else {
alarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 1900,
restartServicePendingIntent);
}
super.onTaskRemoved(rootIntent);
}
Then later within onReceive() I call :
ContextCompat.startForegroundService(context, downloadIntent);
So to summarize,
Once the app is killed how to avoid the notification shown from android system, that the app is running in background? as I am already showing download notification to user, so the user is aware of that.
Also one more question, is there any way to get the intent withing onCreate() of IntentService?
I need to get the id of download content, which is passed in the intent as extra param. Cause based on this I can show the notification within onCreate()
As of now I am showing one "starting download" notification, then in onStartCommand() I clear that notification and create a new notification based on content Id.
From Android Documentation
Foreground
A foreground service performs some operation that is noticeable to the user. For example, an audio app would use a foreground service to play an audio track. Foreground services must display a Notification. Foreground services continue running even when the user isn't interacting with the app.
https://developer.android.com/guide/components/services.html
If the notification isn't properly started, then the service will be killed. Maybe you are looking for a different type of service. Maybe look into a bound service?
Bound A service is bound when an application component binds to it by
calling bindService(). A bound service offers a client-server
interface that allows components to interact with the service, send
requests, receive results, and even do so across processes with
interprocess communication (IPC). A bound service runs only as long as
another application component is bound to it. Multiple components can
bind to the service at once, but when all of them unbind, the service
is destroyed.
I have tried running a service in background. Have used Start_Sticky.
Basically this answer. It works in many devices fine but in some devices like Xiaomi Lenovo the service dies when app is removed from "recent app" screen. I have also tried deactivating power saver for particular apps and full system but that doesn't work either.
How do I make it work in those devices? I know its possible because some apps (like whatsapp) and games are able to send notification even when the app is not in "recent app" screen.
You can create the alarm with 1min in the onTaskRemoved() method in your service class. It will automatically invoke after the 1min and restarts the service.
In service class
public void onTaskRemoved(Intent rootIntent) {
Intent restartService = new Intent(getApplicationContext(), YourService.class);
restartService.setPackage(Yourpackagename);
PendingIntent restartServiceIntent = PendingIntent.getService(getApplicationContext(), 1, restartService, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealTime()+1000, restartServiceIntent);
}
I'm working on location tracking application using FusedLocationProvider. I have a background service which tracks location of phone in every 5 minutes.
All works well with it, but once the phone goes idle then after 3 to 4 hours of time, the background service stops to take location. When user unlocks the phone the tracking start again.
Can someone please guide me what could be causing the issue?
One possibility could be Android M Doze Mode. When the device is unplugged and stationary for a period of time, the system attempts to conserve battery by restricting apps access to CPU-intensive services. Doze mode starts after about 1h of inactivity, periodic tasks etc. are then scheduled to maintenance windows. When the user unlocks the device, doze mode is turned off again.
You find more information about Doze Mode in the developer docs:
http://developer.android.com/training/monitoring-device-state/doze-standby.html
Maybe your service is being stopped because the phone needs to free up memory so it kills your service. Make sure your service is set as a foreground service.
A foreground service is a service that's considered to be something the user is actively aware of and thus not a candidate for the system to kill when low on memory. A foreground service must provide a notification for the status bar, which is placed under the "Ongoing" heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.
http://developer.android.com/guide/components/services.html
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
Android will put your service to sleep after being idle for a while. You can use WakeLock to prevent that from happening.
public int onStartCommand (Intent intent, int flags, int startId)
{
PowerManager mgr = (PowerManager)getSystemService(Context.POWER_SERVICE);
mWakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
mWakeLock.acquire();
...
return START_STICKY;
}
public void onDestroy(){
...
mWakeLock.release();
}
I have an application that keeps a global instance of an ExoPlayer instance to facilitate audio streams in the background.
After opening lots of apps, the audio stops playing.
It happens as follows:
open Activity that starts playing audio
press back button to close Activity
the audio is still playing and keeps doing so if you leave the device alone (as intended)
However, when you open a dozen or more apps after the last step, the ExoPlayer stops playing at some point.
My guess is that a memory cleanup happens and thus ExoPlayer gets deallocated. I tried to get more information from the logs, but that has provided little help so far.
Keeping a reference of the ExoPlayer inside an android.app.Service doesn't make a difference.
The device I am testing on is a Nexus 5 with Android 5.1.x, but the issue happens on other devices too.
I couldn't find a solution in the ExoPlayer documentation pages nor on StackOverflow or Google. Does anyone know the correct way to prevent the ExoPlayer from stopping playback?
To make sure a Service stays alive as much as possible without being killed by the system, you need to make sure you start it as a foreground service.
This means there will be a notification informing the user of the active service so he can be aware of it. Because of that, you must start the service with a corresponding notification. Here is the example from the docs:
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
I am developing notification app in android that shows notification on particular date and time that i set using date picker. It shows correctly if my app is running in background. But when i force stop my app or if device switched off &restarted, notification does not show. How to show notification even if app force closed or device restarted.
You can't. Notifications are attached to application's context. If the application is killed/destroyed, your notification also goes away with it.
What you may do is to re-create those notifications once your application or it's service is started. For that, make sure you do catch android.intent.action.BOOT_COMPLETED broadcast in order to implement this automatically.
You should consider using AlarmManager instead of a service.
Set an alarm at the desired date/time with a custom intent. In the BroadcastReceiver, you create and show the Notification.
If the Device is restarted, you might need also to listen to the BOOT_COMPLETED Intent and reset the alarms.
EDIT:
An example:
long time = // time in milliseconds of when you want your Alarm
PendingIntent mIntent = PendingIntent.getBroadcast(context,
0, new Intent("YOUR_CUSTOM_INTENT"), PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP,
time, mIntent );
Then Catch the YOUR_CUSTOM_INTENT intent in a BroadcastReceiver, show the notification and set the following alarm.