How to reference a view in a customized notification - java

In the below posted code i am create a notification with a customized layout. the layout of the notification contains three action buttons.
the problem i have now is, i can not reference any of the buttons in the code so that I can navigate to another activity based on the action button clicked.what i am trying to do is when Action button 1
is clicked then Activity 1 shows up, when Action button 2 is clicked then Activity 2 shows up and so on.
Please let me know how to reference the views in customized layout of the notification?
code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Using RemoteViews to bind custom layouts into Notification
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_notification);
String notification_title = "Notification_Title";
String notification_text = "Notification_Text";
// Open NotificationView Class on Notification Click
Intent intent = new Intent(this, NotificationReply.class);
// Send data to NotificationView Class
intent.putExtra("title", notification_title);
intent.putExtra("text", notification_text);
// Open NotificationView.java Activity
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
// Set Icon
.setSmallIcon(R.mipmap.ic_launcher)
// Set Ticker Message
.setTicker("Ticker")
// Dismiss Notification
.setAutoCancel(true)
// Set PendingIntent into Notification
.setContentIntent(pIntent)
// Set RemoteViews into Notification
.setContent(remoteViews);
Intent intentAction1 = new Intent(this, ActAction1.class);
PendingIntent pendingIntentActAction1 = PendingIntent.getBroadcast(this, 1,intentAction1, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.btn_action1, pendingIntentActAction1);
Intent intentAction2 = new Intent(this, ActAction2.class);
PendingIntent pendingIntentActAction2 = PendingIntent.getBroadcast(this, 2,intentAction2, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.btn_action2, pendingIntentActAction2);
Intent intentAction3 = new Intent(this, ActAction3.class);
PendingIntent pendingIntentActAction3 = PendingIntent.getBroadcast(this, 3,intentAction3, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setPendingIntentTemplate(R.id.btn_action3, pendingIntentActAction3);
// Create Notification Manager
NotificationManager notificationmanager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Build Notification with Notification Manager
notificationmanager.notify(0, builder.build());
}
}

The key success for navigation is to use proper pending intent and use different values for your requestCode.
You could receive the event in broadcastReceiver building the pending intent (e,g, with params) that way:
private PendingIntent buildPendingIntent(String someurl) {
Intent intent= new Intent(mContext, SomeReceiver.class);
final Uri uri = Uri.parse(someurl);
intent.setData(uri);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(KEY, VALUE)
return PendingIntent.getBroadcast(mContext.getApplicationContext(),
CONSTANT_FOR_THIS_INTENT_TYPE, intent,
PendingIntent.FLAG_CANCEL_CURRENT);
}
Or you could navigate to activity just by pending intent:
private PendingIntent buildPendingIntent2() {
Intent intent = new Intent(mContext, SomeActivity.class);
intent.putExtra(KEY, VALUE);
settingsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
return PendingIntent.getActivity(mContext.getApplicationContext(),
OTHER_CONSTANT_FOR_OTHER_ACTION,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
Please notice that CONSTANT_FOR_THIS_INTENT_TYPE and OTHER_CONSTANT_FOR_OTHER_ACTION must have different values
And after you have this pending intents you should attach them to your views:
view.setOnClickPendingIntent(com.app.btn1, buildPendingIntent1());
view.setOnClickPendingIntent(com.app.btn2, buildPendingIntent2());

You have to use RemoteViews#setOnClickPendingIntent() API:
Equivalent to calling setOnClickListener(android.view.View.OnClickListener) to launch the provided PendingIntent.
Intent firstIntent = new Intent(context, FirstActivity.class);
PendingIntent firstPendingIntent = PendingIntent.getBroadcast(this, 0, firstIntent, 0);
RemoteViews notificationView = ...
notificationView.setOnClickPendingIntent(R.id.first_button, firstPendingIntent);

You have to use RemoteViews#setOnClickPendingIntent() API:
I get your mistake you are trying to launch an activity with PendingIntent.getBroadcast() which only send a broadcast message, so ideally a broadcast receiver should be registered with the same intent filter action. In your case it should ideally be PendingIntent.getActivity
Now you can launch with the following pending intent the flag value was incorrect I can assume for everyone else, hence pending intent wasn't fired.
Intent firstIntent = new Intent(context, FirstActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(appContext, 101, firstIntent,
PendingIntent.FLAG_UPDATE_CURRENT); // For opening activity ideally this should work
If this doesn't work you can try sending a broadcast and listen for it to verify that broadcast is also sent or not:-
PendingIntent pendingIntent = PendingIntent.getBroadcast(appContext, 0, firstIntent, PendingIntent.FLAG_ONE_SHOT); // for sending broadcast and listens in broadcast reciever

Related

Instead of pendingIntent, execute function in Notification.addAction() . Is it possible?

I want a method to be executed when I press a button on my notification. For that purpose I am adding an action with a PendingIntent to my notification:
Intent intent = new Intent(context, AlertActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
Notification notification = new Notification.Builder(MainActivity.this)
.setContentTitle("New Notification")
.setContentText("Click Here")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.addAction(R.mipmap.ic_launcher, "Test2", pendingIntent)
.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(0, notification);
That works, however I don't want to start an Activity when the user invokes the action. I just need to do some work.
For that purpose I implemented a Service which should be targeted by the PendingIntent instead:
public class MyServices extends IntentService {
public MyServices() {
super("MyServices");
}
#Override
protected void onHandleIntent(Intent intent) {
clearNotification();
}
public void clearNotification() {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.cancel(0);
Intent intent = new Intent(MyServices.this, MainActivity.class);
//Starting new activity just to check
startActivity(intent);
}
}
I create the PendingIntent like this:
final Intent intent = new Intent(context, MyServices.class);
final PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
However when I invoke the action on my notification nothing happens. What am I doing wrong?
A Notification is not part of your application. It is managed by the OS. It just so happens that there are APIs you can use to show/cancel/etc notifications.
A pending intent allows for external code (Notifications for example) to launch your app/activity/service/broadcastreceiver. This cannot be done without a pending intent.
What my task is to execute some piece of code when a specific action button is clicked, and clear notification; without starting any activity
You don't have to start an activity. You can do it in a broadcastreceiver that has no UI. Or, as CommonsWare suggested, use an IntentService, depending on what what you are doing in your "piece of code". IntentServices handle work in a separate thread.

When user taps on the push notification message, my app launches. How to make the app display the push message in full?

Good day!
I have successfully sent push notification message to my app on android, and when I tap on the message, it launches my app. May I ask how do I pass intent/bundle to MainActivity from the push notification so that when the app is launched, it can display the push notification message in full within the app? Thank you very much!
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Explicitly specify that GcmMessageHandler will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GcmMessageHandler.class.getName());
showNotification(context, intent);
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
private void showNotification(Context context, Intent intent) {
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MainActivity.class), 0);
String title = intent.getExtras().getString("nTitle");
String message = intent.getExtras().getString("nMessage");
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context);
Notification notification = mBuilder.setContentIntent(contentIntent)
.setSmallIcon(R.drawable.face)
.setColor(context.getResources().getColor(R.color.wallet_holo_blue_light))
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.fuckya))
.setWhen(0)
.setAutoCancel(true)
.setContentTitle(title)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentText(message).build();
mBuilder.setContentIntent(contentIntent);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
}
Regards,
Lorkh
Replace to:
Intent mainActivityIntent = new Intent(context, MainActivity.class);
String title = intent.getExtras().getString("nTitle");
String message = intent.getExtras().getString("nMessage");
mainActivityIntent.putExtra("nTitle", title);
mainActivityIntent.putExtra("nMessage",message);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, mainActivityIntent), 0);
And retrieve this values inside your MainActivity via getIntent();

Android intent via notification not keeping extra data

I'm trying to pass a String via an intent stored in a notification.
But when I get the String out of the intent in the new fragment, it's a null and it gives me a NullPointerException.
Code to create notification (in method A of fragment A in activity A)
Notification.Builder mBuilder = new Notification.Builder(getActivity().getBaseContext());
mBuilder.setContentTitle("My first notification");
mBuilder.setContentText("Click to see the details...");
mBuilder.setSmallIcon(R.drawable.ic_launcher);
//Intent maken voor notification
Intent intentVoorNotificatie = new Intent(getActivity(), activity_detail_notification.class);
EditText edTekst = (EditText) getActivity().findViewById(R.id.etTekst);
String strTekstNotificatie = edTekst.getText().toString();
intentVoorNotificatie.putExtra("detailNotificatie", strTekstNotificatie);
//Intent naar PendingIntent converteren
PendingIntent pIntentVootNotificatie = PendingIntent.getActivity(getActivity().getBaseContext(),
0, intentVoorNotificatie, PendingIntent.FLAG_ONE_SHOT);
mBuilder.setContentIntent(pIntentVootNotificatie);
//Notificatie tonen
NotificationManager mNotificationManager = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1,mBuilder.build());
Method A of fragment B in activity B
//Haal doorgegeven tekst uit intent
Intent intent = getActivity().getIntent();
String strTekst = intent.getStringExtra("detailNotificatie");
TextView tvTekst = (TextView) getActivity().findViewById(R.id.tvDetailVanNotificatie);
tvTekst.setText(strTekst);
I get the nullPointer on the setText() method due to the String being empty when extracting it from the intent.
Did I do something wrong for data to get lost or dismissed?
Try to change this code `
PendingIntent pIntentVootNotificatie = PendingIntent.getActivity(getActivity().getBaseContext(),
0, intentVoorNotificatie, PendingIntent.FLAG_ONE_SHOT);
to this `
PendingIntent pIntentVootNotificatie = PendingIntent.getActivity(getActivity().getBaseContext(),
0, intentVoorNotificatie, PendingIntent.FLAG_UPDATE_CURRENT);

Recreate Activity when pressing the notification - how to?

I have a clickable notification, that opens my application when clicked. Howewer, old activity isn't deleted, so, when I close app, there's the same activity under previous...hope you understand.
So, how can I delete old activity?
The code below is situated in service. And I need to destroy Main activity.
void sendNotif() {
Intent in = new Intent(this, MainActivity.class);
PendingIntent pin = PendingIntent.getActivity(this, 0, in, 0);
Notification notif = new Notification.Builder(this)
.setContentTitle("App launched")
.setContentText("Press to open app")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pin)
.build();
notif.flags |= Notification.FLAG_NO_CLEAR;
nm.notify(1, notif);
}
Kotlin:
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
val pendingIntent = PendingIntent.getActivity(applicationContext, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT)
Why don't you just add a flag to your Intent when you create your PendingIntent like this:
Intent in = new Intent(this, getClass()).addFlags(Intent.FLAG_CANCEL_CURRENT));
PendingIntent pin = PendingIntent.getActivity(this, 0, in, 0);
Try adding these flags to your intent.
in.setFlags(FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK);
See this for explanation.
onPause()
{
MainActivity.this.finish();
}

Android - Why Activity is Open after click notification?

I have a function to display a notification, which I call from various activities.
public static void CrearNotificacion(Context pContexto, String pTituloBarra, String pTitulo, String pTexto){
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) pContexto.getSystemService(ns);
Notification notification = new Notification(R.drawable.icono, pTituloBarra, System.currentTimeMillis());
notification.defaults |= Notification.DEFAULT_SOUND;
Intent notificationIntent = new Intent(pContexto, pContexto.getClass());
PendingIntent contentIntent = PendingIntent.getActivity(pContexto, 0, notificationIntent, 0);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(pContexto, pTitulo, pTexto, contentIntent);
mNotificationManager.notify(1, notification);
}
works perfect, the problem is that pressing on the notification opens the activity that created the notification and that's wrong, I think the notiifcacion activity should not open when I select the notification.
Why? there any way to fix this?
I do not want to open any activity when I select the notification.
thanks from now.
In order to have no action taken when clicking the notification, you may set an empty Intent as follows:
Intent notificationIntent = new Intent() ;
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;
Intent notificationIntent = new Intent(pContexto, pContexto.getClass());
i guess this is the line you have to change with
Intent notificationIntent = new Intent(pContexto, yourClass.class);

Categories