This question already has answers here:
Android - implementing startForeground for a service?
(11 answers)
Closed 1 year ago.
I am new to android. Can anyone post the link or code for "android foreground service example with notification". I googled , but didn't get any example of foreground service.
Create a Notification, perhaps using Notification.Builder or NotificationCompat.Builder, and pass that to startForeground() on the service:
public class Downloader extends IntentService {
private static int FOREGROUND_ID=1338;
public Downloader() {
super("Downloader");
}
#Override
public void onHandleIntent(Intent i) {
startForeground(FOREGROUND_ID,
buildForegroundNotification(filename));
// do useful work here
stopForeground(true);
}
private Notification buildForegroundNotification(String filename) {
NotificationCompat.Builder b=new NotificationCompat.Builder(this);
b.setOngoing(true);
b.setContentTitle(getString(R.string.downloading))
.setContentText(filename)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setTicker(getString(R.string.downloading));
return(b.build());
}
}
(a trimmed-down service from this sample project)
A better example would be:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Start Foreground Intent ");
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Intent previousIntent = new Intent(this, ForegroundService.class);
previousIntent.setAction(Constants.ACTION.PREV_ACTION);
PendingIntent ppreviousIntent = PendingIntent.getService(this, 0,
previousIntent, 0);
Intent playIntent = new Intent(this, ForegroundService.class);
playIntent.setAction(Constants.ACTION.PLAY_ACTION);
PendingIntent pplayIntent = PendingIntent.getService(this, 0,
playIntent, 0);
Intent nextIntent = new Intent(this, ForegroundService.class);
nextIntent.setAction(Constants.ACTION.NEXT_ACTION);
PendingIntent pnextIntent = PendingIntent.getService(this, 0,
nextIntent, 0);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.drawable.truiton_short);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Truiton Music Player")
.setTicker("Truiton Music Player")
.setContentText("My Music")
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(
Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true)
.addAction(android.R.drawable.ic_media_previous,
"Previous", ppreviousIntent)
.addAction(android.R.drawable.ic_media_play, "Play",
pplayIntent)
.addAction(android.R.drawable.ic_media_next, "Next",
pnextIntent).build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
notification);
} else if (intent.getAction().equals(Constants.ACTION.PREV_ACTION)) {
Log.i(LOG_TAG, "Clicked Previous");
} else if (intent.getAction().equals(Constants.ACTION.PLAY_ACTION)) {
Log.i(LOG_TAG, "Clicked Play");
} else if (intent.getAction().equals(Constants.ACTION.NEXT_ACTION)) {
Log.i(LOG_TAG, "Clicked Next");
} else if (intent.getAction().equals(
Constants.ACTION.STOPFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Stop Foreground Intent");
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
Took reference from a tutorial here.. maybe of help to you
Related
Hi I am setting a notification for incoming call with two actions : Answer and Decline . I need to set Green color for Answer action and red for Decline . But i couldnt find a solution.
Here is my code :
NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext,"Call")
.setSmallIcon(R.drawable.ic_stat_rider_logo)
.setContentIntent(contentIntent)
.setContentTitle(generalFunc.retrieveLangLBl("","LBL_SINCH_NOTIFICATION_CONTENT"))
.setContentText(call.getHeaders().get("Name") +" "+ generalFunc.retrieveLangLBl("","LBL_SINCH_NOTIFICATION_TITLE"));
builder.addAction(getServiceNotificationAction(mContext, denyCallIntent(mContext,call),R.drawable.ic_call_icon, R.string.decline));
builder.addAction(getServiceNotificationAction(mContext, answerCallIntent(mContext,call),R.drawable.com_facebook_close, R.string.answer));
if (callActivityRestricted()) {
builder.setFullScreenIntent(contentIntent, true);
builder.setPriority(NotificationCompat.PRIORITY_HIGH);
builder.setCategory(NotificationCompat.CATEGORY_CALL);
}
private NotificationCompat.Action getServiceNotificationAction(Context context, Intent intent, int iconResId, int titleResId) {
PendingIntent pendingIntent = Build.VERSION.SDK_INT >= 26 ? PendingIntent.getForegroundService(context, 0, intent, 0)
: PendingIntent.getService(context, 0, intent, 0);
return new NotificationCompat.Action(iconResId, context.getString(titleResId), pendingIntent);
}
I tried setColor() , but it sets unique color for both actions.
Please help me to solve this . thanks in advance
I have tried your code and achieved it with the help of Spannable class.
public void sendOnChannel1(View v) {
String title = editTextTitle.getText().toString();
String message = editTextMessage.getText().toString();
Intent activityIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this,
0, activityIntent, 0);
Intent broadcastIntent = new Intent(this, NotificationReceiver.class);
broadcastIntent.putExtra("toastMessage", message);
PendingIntent actionIntent = PendingIntent.getBroadcast(this,
0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this, App.CHANNEL_1_ID)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle(title)
.setContentText(message)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setContentIntent(contentIntent)
.setAutoCancel(true)
.setColorized(true)
.setOnlyAlertOnce(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.addAction(R.mipmap.ic_launcher, getMyActionText(R.string.answer,R.color.green), actionIntent)
.addAction(R.mipmap.ic_launcher, getMyActionText(R.string.decline,R.color.red), actionIntent)
.build();
notificationManager.notify(1, notification);
}
Here is a helping method which i used:
private Spannable getMyActionText(#StringRes int stringRes, #ColorRes int colorRes) {
Spannable spannable = new SpannableString(this.getText(stringRes));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
spannable.setSpan(
new ForegroundColorSpan(this.getColor(colorRes)), 0, spannable.length(), 0);
}
return spannable;
}
Below is the method I am using to build a notification for a media player application. Currently, the song information is being displayed correctly but the action buttons for prev, play, next are not being displayed.
This is what is displayed with the notification after calling buildNotification();
private void buildNotification(Notification.Action action) {
String ID = "sage.musicplayer.Service.MusicService";
/*Bitmap albumArtBitmap = null;
if(album_art != null) {
try {
albumArtBitmap = Glide.with(getApplicationContext()).asBitmap().load(album_art).into(100, 100).get();
}catch(Exception e) {
e.printStackTrace();
}
}else if(albumID > -1) {
albumArtBitmap = musicUtils.getAlbumArt(albumID);
}else{
albumArtBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.new_album_art);
}*/
Intent intent = new Intent(MusicService.this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
Intent intentPrev = new Intent(ACTION_PREV);
Intent intentPlayPause;
if(isPng())
intentPlayPause = new Intent(ACTION_PAUSE);
else
intentPlayPause = new Intent(ACTION_PLAY);
Intent intentNext = new Intent(ACTION_NEXT);
PendingIntent pendingPrev = PendingIntent.getActivity(this, 0, intentPrev, PendingIntent.FLAG_IMMUTABLE);
PendingIntent pendingPlayPause = PendingIntent.getActivity(this, 0, intentPlayPause, PendingIntent.FLAG_IMMUTABLE);
PendingIntent pendingNext = PendingIntent.getActivity(this, 0, intentNext, PendingIntent.FLAG_IMMUTABLE);
NotificationCompat.Builder notification = new NotificationCompat.Builder(getApplicationContext());
notification.setContentTitle(songTitle)
.setWhen(System.currentTimeMillis())
.setChannelId(ID)
.setSmallIcon(R.drawable.logo)
.setContentText(songArtist)
.setLargeIcon(musicUtils.getAlbumArt(albumID))
.setDeleteIntent(pendingIntent)
.setPriority(Notification.PRIORITY_MAX)
.setStyle(new androidx.media.app.NotificationCompat.MediaStyle().setMediaSession(MediaSessionCompat.Token.fromToken(mediaSession.getSessionToken())))
.addAction(R.drawable.prev, "Prev", pendingPrev)
.addAction(R.drawable.playbutton, "Play", pendingPlayPause)
.addAction(R.drawable.next, "Next", pendingNext);
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(getApplicationContext());
notificationManagerCompat.notify(NOTIFY_ID, notification.build());
}
If your drawables (R.drawable.prev, etc) are vectorial and not images, it won't work. I had the same issue today.
I made a MediaPlayer some time ago and I faced a big issue. The audio can't be played in the background so I must use Service. At this point, I managed to play the music and to stop it, but when I click play again, it restarts and I don't know what to do. I am new to coding. Other than that I want to make a working seekbar and a textView for player position, but that for another time. If there is someone to help me I would really appreciate it.
Here is the code I am using now:
btPause = findViewById(R.id.btPauseMusic);
btPlay = findViewById(R.id.btPlayMusic);
btPlay.setOnClickListener(v -> {
startService(new Intent(this, BackgroundMusicService.class));
btPlay.setVisibility(View.GONE);
btPause.setVisibility(View.VISIBLE);
});
btPause.setOnClickListener(v -> {
stopService(new Intent(this, BackgroundMusicService.class));
btPause.setVisibility(View.GONE);
btPlay.setVisibility(View.VISIBLE);
});
}
The service:
public class BackgroundMusicService extends Service {
private MediaPlayer mediaPlayer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer = MediaPlayer.create(this, R.raw.ding_dong);
mediaPlayer.start();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
}
}
Add this notification code in your BackgroundMusicService inside on onCreate.
Intent stopSelf = new Intent(this, BackgroundMusicService.class);
stopSelf.setAction("Stop");
PendingIntent pStopSelf = PendingIntent
.getService(this, 0, stopSelf
, PendingIntent.FLAG_CANCEL_CURRENT);
Notification notification;
NotificationCompat.Action action =
new NotificationCompat.Action.Builder(
0, "Pause", pStopSelf
).build();
Intent startSelf = new Intent(this, BackgroundMusicService.class);
stopSelf.setAction("Start");
PendingIntent pstartSelf = PendingIntent
.getService(this, 0, stopSelf
, PendingIntent.FLAG_CANCEL_CURRENT);
Notification notifications;
NotificationCompat.Action actions =
new NotificationCompat.Action.Builder(
0, "Play", pstartSelf
).build();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel("channal", "Notification", NotificationManager.IMPORTANCE_HIGH);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(serviceChannel);
notification = new NotificationCompat.Builder(this, "channal")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText("Music.")
.setPriority(Notification.PRIORITY_MAX)
.addAction(action)
.addAction(actions).build();
} else {
notification = new NotificationCompat.Builder(this, "channal")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("App name")
.setContentText("Music.")
.setPriority(Notification.PRIORITY_MAX)
.addAction(action)
.addAction(actions)
.build();
}
NotificationManager notificationManager =
(NotificationManager) getSystemService(Service.NOTIFICATION_SERVICE);
notificationManager.notify(1, notification);
startForeground(1, notification);
In onStartCommand your intent actions are called where you can pause and play the music by using the length.
int length=0;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if ("STOP".equals(intent.getAction())) {
//inside here pause the music.
mediaPlayer.pause();
length = mediaPlayer.getCurrentPosition();
}else if ("Start".equals(intent.getAction())) {
//inside here play the music with seekto by length where the music was.
mediaPlayer.start();
mediaPlayer.seekTo(length);
}
return START_STICKY;
}
Note: If you still did not understand anything you can ask me in the comment.
I am developing an application, I have 2 buttons in an on the notification. How can I know which button the user has clicked?
This my Notification codes;
public void NotificationSettings(Context context){
Intent stateIntent = new Intent(context, MyBroadcastReceiver.class);
stateIntent.putExtra("id", 100);
PendingIntent pendingIntent =
PendingIntent.getBroadcast(context, 0, stateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder = new NotificationCompat.Builder(context, "access2020")
.setSmallIcon(R.drawable.ic_baseline_add_alert_24)
.setContentTitle("Academy Notification")
.setContentText("Hey this is an important notifications")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.addAction(R.drawable.ic_baseline_add_alert_24, "Set Active", pendingIntent)
.addAction(R.drawable.ic_baseline_add_alert_24,"Dismiss", pendingIntent);
notificationManager = NotificationManagerCompat.from(context);
}
and My Broadcast
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "test", Toast.LENGTH_SHORT).show();
int notificationId = intent.getIntExtra("id", 0);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.cancel(notificationId);
}
You should pass an identifier to the intent as an extra and then retrieve in your BroadcastReceiver.
public void NotificationSettings(Context context){
// put an extra identifier for Set Active Action
Intent setActiveStateIntent = new Intent(context, MyBroadcastReceiver.class);
setActiveStateIntent.putExtra("id", 100);
setActiveStateIntent.putExtra("action", "Action.SetActive");
PendingIntent setActivePendingIntent =
PendingIntent.getBroadcast(context, 0, setActiveStateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// put an extra identifier for Dismiss
Intent dismissStateIntent = new Intent(context, MyBroadcastReceiver.class);
dismissStateIntent.putExtra("id", 100);
dismissStateIntent.putExtra("action", "Action.Dismiss");
PendingIntent dismissPendingIntent =
PendingIntent.getBroadcast(context, 0, dismissStateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder = new NotificationCompat.Builder(context, "access2020")
.setSmallIcon(R.drawable.ic_baseline_add_alert_24)
.setContentTitle("Academy Notification")
.setContentText("Hey this is an important notifications")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.addAction(R.drawable.ic_baseline_add_alert_24, "Set Active", setActivePendingIntent)
.addAction(R.drawable.ic_baseline_add_alert_24,"Dismiss", dismissPendingIntent);
notificationManager = NotificationManagerCompat.from(context);
}
Then in your BroadcastReceiver you can do the following:
public void onReceive(Context context, Intent intent) {
if(intent.getStringExtra("action").equals("Action.Dismiss")) {
// perform your dismiss action
} else if (intent.getStringExtra("action").equals("Action.SetActive")) {
// perform your set active logic
} else {
// handle invalid action
}
}
I solved with this way but still i am not sure it is the right way
public void NotificationSettings(Context context){
Intent stateIntent0 = new Intent(context, MyBroadcastReceiver.class);
Intent stateIntent1 = new Intent(context, MyBroadcastReceiver.class);
stateIntent0.putExtra("id", 100);
stateIntent1.putExtra("id", 200);
PendingIntent pendingIntent0 =
PendingIntent.getBroadcast(context, 0, stateIntent0, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent1 =
PendingIntent.getBroadcast(context, 1, stateIntent1, PendingIntent.FLAG_UPDATE_CURRENT);
builder = new NotificationCompat.Builder(context, "lemubitA")
.setSmallIcon(R.drawable.ic_baseline_add_alert_24)
.setContentTitle("Lemubit Academy Notification")
.setContentText("Hey this is an important notifications")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.addAction(R.drawable.ic_baseline_add_alert_24, "Set Active", pendingIntent0)
.addAction(R.drawable.ic_baseline_add_alert_24,"Dismiss", pendingIntent1);
notificationManager = NotificationManagerCompat.from(context);
}
AND this my Broadcast
int notificationId = intent.getIntExtra("id", 0);
Toast.makeText(context, notificationId+"", Toast.LENGTH_SHORT).show();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.cancel(notificationId);
I tried to put PendingIntent Notification in my android project but i had this error it says wrong first argument found android view.View.OnClickListener required android content,context.
Am going to show the code error , the "this" under else notification has its error.
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
Notification noti = new Notification.Builder(this)
this error
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int targetId = view.getId();
if (targetId == R.id.button) {
Toast.makeText(getApplicationContext(), "You have " + numMessages++ + " message", Toast.LENGTH_SHORT).show();
} else {
if (numMessages > 0) {
Intent intent = new Intent();
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
Notification noti = new Notification.Builder(this)
.setTicker("You Have " + numMessages++ + " message")
.setContentTitle("OneDiver")
.setContentText("Content")
.setSmallIcon(R.drawable.ic_od_icon_24dp)
.setContentIntent(pIntent).getNotification();
noti.flags = Notification.FLAG_AUTO_CANCEL;
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, noti);
}
}
If this code is in an activity, say YourActivity.class, you need to replace "this" with "YourActivity.this". Because in an OnClickListener, "this" is referring to the OnClickListener instead of the activity.