I am trying to get my on going notification to have a button, when clicked it should call my service which is controlling audio playback.
Here is my notification with the intent
Intent intent = new Intent(context, AudioStreamService.class);
Random generator = new Random();
PendingIntent i = PendingIntent.getActivity(context, 579, intent,PendingIntent.FLAG_UPDATE_CURRENT);
final NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(title)
.setContentText(text)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setLargeIcon(picture)
.setTicker(ticker)
.setNumber(number)
.setOngoing(true)
.addAction(
R.drawable.ic_action_stat_reply,
res.getString(R.string.action_reply),
i);
notify(context, builder.build());
Here is the on start for my service
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("APP ID", "APP ID - service called ");
if(isPlaying){
stop();
}
else {
play();
}
return Service.START_STICKY;
}
The log is never triggered when called from the action in the notification. But the service is used by a button in the app and works fine. Log gets called as do commands below.
Use :
PendingIntent pendingIntent = PendingIntent.getService(context, 579, intent,PendingIntent.FLAG_UPDATE_CURRENT);
instead of :
PendingIntent pendingIntent = PendingIntent.getActivity(context, 579, intent,PendingIntent.FLAG_UPDATE_CURRENT);
^^ This is used to start an activity from the notification.
Related
How would I stop the foreground service using the notification it creates in the class?
Intent stopnotificationIntent = new Intent(this, HelloIntentService.class);
//Not sure which is the current action to set
stopnotificationIntent.setAction("ACTION.STOPFOREGROUND_ACTION");
PendingIntent pIntent = PendingIntent.getService(this, 0, stopnotificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, channelId)
.addAction(0, "Cancel", pIntent);
startForeground(1111, notificationBuilder.build());
the button is created from .addAction and I want to stop that current foreground service
String ACTION_STOP_SERVICE= "STOP";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (ACTION_STOP_SERVICE.equals(intent.getAction())) {
Log.d(Statics.LOG_TAG,"called to cancel service");
stopSelf();
}
Intent stopSelf = new Intent(this, HelloIntentService.class);
stopSelf.setAction(ACTION_STOP_SERVICE);
PendingIntent pStopSelf = PendingIntent
.getService(this, 0, stopSelf
,PendingIntent.FLAG_CANCEL_CURRENT); // That you should change this part in your code
notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentText("Bla Bla Bla")
.setSmallIcon(R.drawable.ic_notification)
.setContentIntent(pendingNotificationIntent)
.addAction(R.drawable.xxxx,"Close", pStopSelf)
.setSound(null)
.build();
startForeground(REQUEST_CODE, notification);
}
I have a never-ending foreground service which shows a notification, but in my device which is having an Android version as nougat.
For some time the notification is not visible(i think most probably because the service has stopped working) and after some time it is visible again automatically.
So I am not able to detect what exactly can be a reason for this.
Attaching the code part in which I have started the service.
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
//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);
RemoteViews notificationView = new RemoteViews(this.getPackageName(), R.layout.notification);
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
Notification notification = new NotificationCompat.Builder(this,"100")
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setColor(Color.parseColor("#00f6d8"))
.setContent(notificationView)
.setPriority(Notification.PRIORITY_MIN)
.setOngoing(true).build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, notification);
return START_REDELIVER_INTENT;
}
I am using cordova to build my android application. Since android kills service, i am binding service with a notification to avoid service kill.
Here is my method how i bind the service with notification
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
context = this.getApplicationContext();
notifyService();
return START_NOT_STICKY;
}
private void notifyService() {
String package_name = this.getApplication().getPackageName();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
this.getApplication().getResources().getIdentifier("icon", "drawable-hdpi", package_name));
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Smart Home")
.setContentText("Smart Home running in background")
.setSmallIcon(this.getApplication().getResources().getIdentifier("icon", "drawable-hdpi", package_name))
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
startForeground(notificationId, notification);
}
Here's the output
Notification is generated but notification title is not as i set. Also, when i click this notification, it's moving to app info activity. But i want to move to my main activity.
Does anyone faced this same issue? Or my code need any change for cordova?
when i click this notification, it's moving to app info activity. But i want to move to my main activity to achieve this
change this line
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
to this line
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Hope it helps you
Figured it out after a long try. Problem was with my pending intent activity name. Below code worked for me
String package_name = this.getApplication().getPackageName();
Intent notificationIntent = context.getPackageManager().getLaunchIntentForPackage(package_name);
I have a notifications system working that a service is scheculing then and the notifications are working fine.
I have some notifications that require user input/action.
Here is the code where I build my notification:
public int onStartCommand(Intent intent, int flag, int startId)
{
super.onStartCommand(intent , flag, startId);
Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Context context = this.getApplicationContext();
notificationManager = (NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE);
Intent mIntent = new Intent(this, MainActivity.class);
pendingIntent = PendingIntent.getActivity(context, 0, mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification builder = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN ) {
builder = new Notification.Builder(this)
.setContentTitle(Utils.Title)
.setContentText(Utils.Body)
.setSmallIcon(R.drawable.ic_launcher)
.addAction(0, Utils.button1Value, pendingIntent)
.addAction(0, Utils.button2Value, pendingIntent)
.setSound(uri)
.setContentIntent(pendingIntent)
.build();
}
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(Utils.NotificationID, builder);
return START_STICKY;
My question is: How do I get what button in the notification user clicked? In other words, how can I create some sort of button listener for those 2 actions in the notification?
Also, how can I stack my notifications so they don`t appear all separated? I have read on Google API that I need to use .setGroup, but that is not working. Can anyone share some example of notification stacking ?
********** Added *************
final static String GROUP_KEY = "myGroup"; // added String to identify the group
public int onStartCommand(Intent intent, int flag, int startId)
{
super.onStartCommand(intent , flag, startId);
Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Context context = this.getApplicationContext();
notificationManager = (NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE);
Intent mIntent = new Intent(this, MainActivity.class);
pendingIntent = PendingIntent.getActivity(context, 0, mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification builder = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN ) {
builder = new Notification.Builder(this)
.setContentTitle(Utils.Title)
.setContentText(Utils.Body)
.setSmallIcon(R.drawable.ic_launcher)
.setGroup(GROUP_KEY) // added group for Stacking
.addAction(0, Utils.button1Value, pendingIntent)
.addAction(0, Utils.button2Value, pendingIntent)
.setSound(uri)
.setContentIntent(pendingIntent)
.build();
}
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, builder); // ID is always the same because the notifications are all stacking into one, tried with unique ID not working either
return START_STICKY;
For button listener problem:
Notification action will trigger that pendingIntent, so just put your custom intent into it. Each text should have a different pendingIntent so that you can distinguish it.
public int onStartCommand(Intent intent, int flag, int startId) {
//......
Intent mIntent1 = new Intent(this, MainActivity.class);
mIntent1.setAction("clickAc1");
PendingIntent pendingIntent1 = PendingIntent.getActivity(context, 0, mIntent1, PendingIntent.FLAG_UPDATE_CURRENT);
Intent mIntent2 = new Intent(this, MainActivity.class);
mIntent2.setAction("clickAc2");
PendingIntent pendingIntent2 = PendingIntent.getActivity(context, 0, mIntent2, PendingIntent.FLAG_UPDATE_CURRENT);
Intent it = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, it, PendingIntent.FLAG_UPDATE_CURRENT);
Notification builder = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
builder = new Notification.Builder(this)
.setContentTitle("Title")
.setContentText("Text")
.setSmallIcon(R.drawable.your_logo)
.addAction(0, "ac1", pendingIntent1)
.addAction(0, "ac2", pendingIntent2)
.setSound(uri)
.setContentIntent(pendingIntent)
.build();
}
and when user click the text ac1, then you can handle it in MainActivity(or other context you want.
//MainActivity
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.d("probe","onNewIntent:"+intent.getAction());
//response your click event by case intent.getAction(),
//it will be `clickAc1` or `clickAc2`, the string you write down in intent.setAction
}
If you use custom RemoteViews, you can follow this:
Intent intent = new Intent("Your Custom intent string, like com.yourpackage.ClickButtonXXX");
pendingIntent = PendingIntent.getService(getApplicationContext(),
yourRequestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mRemoteViews.setOnClickPendingIntent(R.id.yourViewId, pendingIntent);
then your can response it with override Service.onStartCommand(Intent intent, int flags, int startId), case intent.getAction(); to distinguish different button.
Stacking messages:
I found this in this notification history article:
.setGroup(GROUP_KEY_MESSAGES) // added group for Stacking
.setGroupSummary(true)
.setContentTitle(count+" new notes")
.setStyle(new NotificationCompat.BigTextStyle().setSummaryText(count+" more"))
.build();
count++;
If you use Notification, change NotificationCompat.BigTextStyle() to Notification.BigTextStyle().
I think this may be what you want.
The roll-up notification cheats a little bit.
I have prepared a simple test app which posts a notification on a button click:
The source code from MainActivity.java creating the notification is displayed below:
Button showButton = (Button) findViewById(R.id.show);
showButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent appIntent = new Intent(mContext, MainActivity.class);
appIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
appIntent.putExtra("my_data", 12345);
String question = getString(R.string.the_question);
PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, appIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(mContext)
.setContentTitle(question)
.setContentText(question)
.setTicker(question)
.setWhen(System.currentTimeMillis())
.setContentIntent(contentIntent)
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher)
.build();
mManager.notify(NOTIFY_ID, notification);
}
});
My question is: how to modify the notification, so that the user is asked a Yes/No question (in this case: "Do you want to open the car?") and - after she selects Yes or No to launch the same app and run a corresponding method in it (in this case: openCar() or closeCar() method).
I probably should use NotificationCompat.Action.Builder - but how exactly?
Also I am not really sure if this code is the correct code for launching an app from notification and what flags should I use:
Intent appIntent = new Intent(mContext, MainActivity.class);
appIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
And finally I wonder if hardcodidng some random number in NOTIFY_ID is the correct way when posting notifications?
Here is a source code I used for notification with Login/Register action.
private void sendNotification(String message, String title) {
try {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Intent secondActivityIntent = new Intent(this, SecondActivity.class);
PendingIntent secondActivityPendingIntent = PendingIntent.getActivity(this, 0 , secondActivityIntent, PendingIntent.FLAG_ONE_SHOT);
Intent thirdActivityIntent = new Intent(this, ThridActivity.class);
PendingIntent thirdActivityPendingIntent = PendingIntent.getActivity(this, 0 , thirdActivityIntent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_3d_rotation_white_36dp)
.setContentTitle(title)
.setContentText(message)
.addAction(R.drawable.ic_lock_open_cyan_600_24dp,"Login",secondActivityPendingIntent)
.addAction(R.drawable.ic_lock_pink_700_24dp,"Register",thirdActivityPendingIntent)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
} catch (Exception e) {
e.printStackTrace();
}
}
To use it: simply call this method sendNotification(String yourMessage, String yourTitle)
e.g. sendNotification("Hello Message", "Hello Title")
Here is a snapshot of the output
Notify user on pending Intent.. an example is here..
public void notifyUser() {
NotificationManager notificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(HappyActivity.this, NotificationDialog.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
// use the flag FLAG_UPDATE_CURRENT to override any notification already
// there
pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification(R.drawable.ic_launcher,
"Question.....?????", System.currentTimeMillis());
notification.flags = Notification.FLAG_AUTO_CANCEL
| Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND;
notification.setLatestEventInfo(this, "title",
"Explanation of question..", pendingIntent);
// 10 is a random number I chose to act as the id for this notification
notificationManager.notify(10, notification);
}