I am trying to show an incoming call notification using a full screen intent which I've managed to do.
The problem when tapping on the Accept action button I'm unable to open the app if it's closed, or bring to the front, etc ...
The weird thing is that clicking on the background of the notification will do exactly what I want, but that's not what I'm after. I want the user to be able to reject without having to open the app.
I've tried starting the MainActivity from a service and also a BroadcastReceiver.
Neither of those two options seem to work.
This is how I'm building the notification - everything works as expected here ...
public class IncomingCallNotificationService extends Service {
#TargetApi(Build.VERSION_CODES.O)
private Notification buildNotification(
String title,
String text,
PendingIntent pendingIntent,
Bundle extras,
int notificationId,
String channelId
) {
Log.d(TAG, "buildNotification: " + extras.get(Constants.CALL_ID).toString());
String callId = extras.get(Constants.CALL_ID).toString();
Intent rejectIntent = new Intent(getApplicationContext(), IncomingCallNotificationService.class);
rejectIntent.setAction(Constants.ACTION_REJECT);
rejectIntent.putExtra(Constants.NOTIFICATION_ID, notificationId);
PendingIntent pendingIntentReject = PendingIntent.getService(getApplicationContext(), notificationId, rejectIntent, getPendingIntentFlag());
Intent acceptIntent = new Intent(getApplicationContext(), IncomingCallNotificationService.class);
acceptIntent.setAction(Constants.ACTION_ACCEPT);
acceptIntent.putExtra(Constants.NOTIFICATION_ID, notificationId);
acceptIntent.putExtra(Constants.CALL_ID, callId);
PendingIntent pendingIntentAccept = PendingIntent.getService(getApplicationContext(), notificationId, acceptIntent, getPendingIntentFlag());
long[] mVibratePattern = new long[]{0, 400, 400, 400, 400, 400, 400, 400};
Notification.Builder builder =
new Notification.Builder(getApplicationContext(), channelId)
.setSmallIcon(R.drawable.ic_call_end_white_24dp)
.setContentTitle(title)
.setContentText(text)
.setPriority(Notification.PRIORITY_MAX)
.setCategory(Notification.CATEGORY_CALL)
.setFullScreenIntent(pendingIntent, true)
.setContentIntent(pendingIntent)
.setExtras(extras)
.setVibrate(mVibratePattern)
.setAutoCancel(true)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.addAction(android.R.drawable.ic_menu_delete, getString(R.string.decline), pendingIntentReject)
.addAction(android.R.drawable.ic_menu_call, getString(R.string.answer), pendingIntentAccept);
return builder.build();
}
}
This is what eventually gets called when tapping the accept button:
private void accept(String callId) {
Log.d(TAG, "accepting call: " + callId);
endForeground();
SoundPoolManager.getInstance(this).stopRinging();
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra(Constants.CALL_ID, callId);
startActivity(intent);
}
Related
I am trying to send a int Extra to an Activity when a notification is tapped. When I tap the notification the activity launches, but the extra is always null.
I have checked a lot of similar questions but they haven't helped me solve the problem. (I tried using onNewIntent() but it was never called). How can I successfully send the Extra?
This is the BroadcastReceiver where the intent is created:
public class EventAlarmNearReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent nextIntent = new Intent().setClass(context, EventActivity.class);
nextIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
int id = 1234;
nextIntent.putExtra("Id", (long) id);
nextIntent.setAction("nearReceiverAction");
PendingIntent nextPendingIntent = PendingIntent.getActivity(context, 1022, nextIntent, PendingIntent.FLAG_UPDATE_CURRENT);
String text = "Your " + intent.getStringExtra("Name") + " is starting soon. Please read your documents.";
NotificationsDeliver.getInstance().sendNotification(context, "Meeting Mate", text, nextPendingIntent);
}
}
This is the method from NotificationsDeliver where the notification is sent:
public void sendNotification(#NonNull Context context, String title, String text, PendingIntent pendingIntent ) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_event_note_white_24dp)
.setContentTitle(title)
.setContentText(text)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVibrate(new long[] { 1000, 1000, 1000 })
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(999, builder.build());
}
This is onCreate method from EventActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
long id = intent.getLongExtra("id", 0);
}
I would guess that it's because you have capitalized the word "id" differently when putting vs getting the extra; compare:
nextIntent.putExtra("Id", (long) id);
// ^^^^
vs
long id = intent.getLongExtra("id", 0);
// ^^^^
Try using the same capitalization for both.
My app creates a notification and an item in a Data Base with that id.
When the user dismiss the notification I want to get that notification id, and using it to perform a research in the Data Base. I already have a pending Intent that allows me to know when a notification is dismissed.
The broadcast Reciever:
final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Action to perform when notification is dismissed
unregisterReceiver(this);
}
};
Code that creates a notification:
Intent intent = new Intent("NOTIFICATION_DELETED");
PendingIntent pendintIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
registerReceiver(receiver, new IntentFilter("NOTIFICATION_DELETED"));
notification = new Notification.Builder(this, channelId)
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.icon_notification)
.setAutoCancel(true)
.setDeleteIntent(pendintIntent)
.build();
notificationManager.notify(idUnico =(int)((new
Date().
getTime() /1000L)%Integer.MAX_VALUE),notification );
reminder.setText("");
titoloE.setText("");
saveNotif();
checkForConsent();
You need to set the notificationId you are using to show notfication in the intent passed to pending intent.
int notifiId = (int)((new Date().getTime() /1000L)%Integer.MAX_VALUE);
Intent intent = new Intent("NOTIFICATION_DELETED");
// set id to intent
intent.putExtra("NOTIFICATION_ID", notifiId);
PendingIntent pendintIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
registerReceiver(receiver, new IntentFilter("NOTIFICATION_DELETED"));
notification = new Notification.Builder(this, channelId)
.setContentTitle(title)
.setContentText(text)
.setSmallIcon(R.drawable.icon_notification)
.setAutoCancel(true)
.setDeleteIntent(pendintIntent)
.build();
notificationManager.notify(notifiId, notification);
Then in your broadcast receiver you can get the Id
final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Action to perform when notification is dismissed
if (intent.hasExtra("NOTIFICATION_ID") {
int id = intent.getIntExtra("NOTIFICATION_ID", -1);
// Use Id
}
unregisterReceiver(this);
}
};
So when the user receives a notification while the lockscreen is on the screen should light up.
private void unlockScreen() {
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
I have this to unlock the screen. Then I'm using this to call it
private void updateNotification(int notificationCode)
{
switch(notificationCode)
{
case NotificationService.InterceptedNotificationCode.FACEBOOK_CODE:
shapeRoundButton.setImageResource(R.drawable.toggle_on);
unlockScreen();
break;
case NotificationService.InterceptedNotificationCode.OTHER_NOTIFICATIONS_CODE:
shapeRectangleButton.setImageResource(R.drawable.toggle_on);
break;
}
}
The shapeRoundButton.setImageResource(R.drawable.toggle_on) works perfectly fine, but the unlockScreen(); doesn't. The notification is being received.
Anyone know why the screen isn't being unlocked or how I can unlock the screen? Cheers!
see this
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isScreenOn();
Log.e("screen on.................................", ""+isScreenOn);
if(isScreenOn==false)
{
WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |PowerManager.ACQUIRE_CAUSES_WAKEUP |PowerManager.ON_AFTER_RELEASE,"MyLock");
wl.acquire(10000);
WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyCpuLock");
wl_cpu.acquire(10000);
}
Try using an IntentService. Replace your intent target with your intent service:
Intent yepIntent = new Intent(context, MyIntentService.class);
yepIntent.putExtra("foo", true);
yepIntent.putExtra("bar", "more info");
PendingIntent yepPendingIntent = PendingIntent.getService(context, notificationId, yepIntent, PendingIntent.FLAG_CANCEL_CURRENT);
notificationBuilder.addAction(R.drawable.icon_of_choice, "My Action", yepPendingIntent);
Register your service in the Manifest:
<service
android:name="app.great.mypackage.MyIntentService"
android:exported="false"/>
Your Service could look like this:
public class MyIntentSerice extends IntentService {
#Override
protected void onHandleIntent(Intent intent) {
Log.d("myapp", "I got this awesome intent and will now do stuff in the background!");
// .... do what you like
}
}
UPDATE with feedback from Name
The trick seems to be to
Use a service
Add the intent not as an action or a contentIntent, but with the RemoteViews method.
Combined it will be:
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setOngoing(true)
.setSmallIcon(R.drawable.abc_ic_menu_share_mtrl_alpha)
.setContentTitle("My notification")
.setContentText("Hello World!");
int notificationId = 1;
Intent yepIntent = new Intent(this, MyIntentService.class);
yepIntent.setAction("test");
yepIntent.putExtra("foo", true);
yepIntent.putExtra("bar", "more info");
PendingIntent yepPendingIntent = PendingIntent.getService(this,
notificationId, yepIntent, PendingIntent.FLAG_CANCEL_CURRENT);
// doesn't show up on my lock-screen
//builder.addAction(R.drawable.abc_ic_menu_share_mtrl_alpha, "My Action",
yepPendingIntent);
// asks for unlock code for some reason
//builder.setContentIntent(yepPendingIntent);
// Bingo
RemoteViews view = new RemoteViews(getPackageName(), R.layout.notification);
view.setOnClickPendingIntent(R.id.notification_closebtn_ib, yepPendingIntent);
builder.setContent(view);
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
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();