Full Screen Notification only showing as a Heads Up
Asked Answered
E

3

29

I have been banging my head against the table with this problem for 3 days now, please tell me where I have strayed.

When I am getting an incoming VoIP call, I am trying to show a full screen notification, just like the PhoneApp does. I am ok with heads up, if the user is in an immersive activity. However, I am getting only a heads up notification, and never getting a full screen. I need to notification to ignore the lock screen as well.

Here is what I am doing:

String callJson = call.toJson(uber).toString();
uber.requestWakeState(UberVoice.WAKE_STATE_FULL);

final Notification.Builder builder = new Notification.Builder(uber);
builder.setSmallIcon(R.drawable.switch_notification);
if (image != null) {
    builder.setLargeIcon(image);
}
builder.setOngoing(true);

PendingIntent inCallPendingIntent =
        PendingIntent.getActivity(uber, 234,
                UberVoice.createInCallIntent(), 0);
builder.setContentIntent(inCallPendingIntent);

builder.setContentText(body);
builder.setUsesChronometer(false);

builder.setContentTitle(title);

builder.setCategory(Notification.CATEGORY_CALL);
builder.setVisibility(Notification.VISIBILITY_PUBLIC);

builder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE), AudioManager.STREAM_RING);
builder.setVibrate(new long[]{500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500});

builder.setPriority(Notification.PRIORITY_MAX);
builder.setTicker(title);
builder.setFullScreenIntent(inCallPendingIntent, true);

builder.addAction(R.drawable.hangup_action, "Reject", CallService.getPendingIntent(uber, callJson, CallService.REJECT));
builder.addAction(R.drawable.answer_action, "Answer", CallService.getPendingIntent(uber, callJson, CallService.ANSWER));

NotificationManager notificationManager = (NotificationManager) uber.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = builder.build();
notificationManager.notify(INCOMING_CALL_NOTIFICATION_ID, notification);

Here is the createInCallIntent code:

public static Intent createInCallIntent() {
    Intent intent = new Intent(Intent.ACTION_MAIN, null);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
            | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
            | Intent.FLAG_ACTIVITY_NO_USER_ACTION);
    intent.setClassName("<package>", IncomingCallActivity.class.getName());
    return intent;
}

And here is the IncomingCallActivity.onCreate()

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
            | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
            | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;

    getWindow().addFlags(flags);

    setContentView(R.layout.activity_incoming_call);

I have tried starting this activity directly(uber is Application reference)

Intent incomingCallIntent = new Intent(uber, IncomingCallActivity.class);
String callJson = call.toJson(uber).toString();
incomingCallIntent.putExtra("call", callJson);

incomingCallIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

uber.startActivity(incomingCallIntent);

What am I doing wrong?

Ellamaeellan answered 3/9, 2015 at 0:19 Comment(18)
Notification.fullScreenIntent: The system UI may choose to display a heads-up notification, instead of launching this intent, while the user is using the device.Modestomodesty
Yea no I get that, but obviously my phone "chooses" to show full screen for phone, why not for my app? My phone app correctly shows heads-up if I am in an immersive activity.Ellamaeellan
@Ellamaeellan If a notification with id INCOMING_CALL_NOTIFICATION_ID is already active, fullScreenIntent for the new notification will be ignored. Could this be the problem you're dealing with?Thorsten
@Thorsten unfortunately not, I tried changing the ID randomlyEllamaeellan
@Ellamaeellan Ok. Its odd. Is the issue present on multiple devices? Have you tested on a device running vanilla android? I also recommend calling notificationManager.cancel(INCOMING_CALL_NOTIFICATION_ID) right before notificationManager.notify(INCOMING_CALL_NOTIFICATION_ID, notification).Thorsten
If showing a "notification" regardless what the user is doing is what you required, the best bet may be just launching an Activity on receiving an incoming call.Instrumental
@Instrumental Unfortunately launching an activity doesn't work, as it doesn't get through the lock screen.Ellamaeellan
@Ellamaeellan the solutions provided here should be able to bypass the lock screen: https://mcmap.net/q/502711/-disable-lock-screenInstrumental
The call app uses the flag FLAG_SHOW_WHEN_LOCKED to display InCallUi ontop of lock screen. InCallUi shows an activity not a notification in lock screen.Fag
Disabling the lock screen will not yield the result you want (and may not be supported). The flag FLAG_DISMISS_KEYGUARD will show the bouncer before your activity for secure lock screens. You can use both resulting in dismiss if insecure and ontop if secure, but, some versions of Android have bugs where one of the flags are ignored if used together.Fag
@Thorsten yep running on Nexus 5 with everything stock. Tried calling cancel.Ellamaeellan
Yea none of these things work. The Call app is not directly showing an activity, they are doing this notification thing which then presents it as an activity.Ellamaeellan
@Leo, that's not at all what it's doing. androidxref.com/5.1.1_r6/xref/packages/apps/InCallUI/src/com/… if you have those flags you will be shown ontop of lock screen. Look at InCallActivity to see how to do it.Fag
this part fell out: it's not at all what it's doing to be ontop of lock screen, the full screen intent that it sets does not magically mean it can show stuff ontop of lock screen, any app can do it if it has the correct window flags.Fag
@Fag uh, so I still don't understand. You are saying that instead of showing a notification I should do: Intent incomingCallIntent = new Intent(uber, IncomingCallActivity.class); String callJson = call.toJson(uber).toString(); incomingCallIntent.putExtra("call", callJson); incomingCallIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); <application>.startActivity(incomingCallIntent); This does bring up the screen if the device is unlocked. Otherwise nothing happens. I have added int flags = FLAG_SHOW_WHEN_LOCKED | FLAG_TURN_SCREEN_ON; getWindow().addFlags(flags);Ellamaeellan
Post your activity code in your question, code in comments is unreadable. :)Fag
Are you using android 5.0? Also try moving the flag setting to onAttachToWindow, the flags apply to the current window, which may or may not be the same one you are attached to.Fag
Can you share the code of CallService.getPendingIntent and activity_incoming_call layout file ?Poler
E
5

Figured it out! It was something stupid just as I suspected.

In my IncomingCallActivity I had the following bit of code

public void onPause() {
    super.onPause();
    finish();
}

It turns out that something having to do with how Notifications get shown actually calls onPause, therefore finishing the activity.

Thanks to @JohanShogun for attempting to help out.

Ellamaeellan answered 11/9, 2015 at 20:26 Comment(6)
I don't think you need FLAG_DISMISS_KEYGUARD though. That way the user's phone will still be locked when they hang up. An added security benefit.Hendry
You do, you cannot unlock someone's phone like this, it just temporarily ignores the lock.Ellamaeellan
I know for a fact that FLAG_DISMISS_KEYGUARD will unlock the device if the user doesn't have a secure lock, like if the user just has swipe-to-unlock configured. You are right, though, if the user has a pattern of pin configuredHendry
Do you still have to explicitly start the activity or does the notification do it automatically?Irresolute
@wdavies973 the notification does it automatically, as long as you have full screen intent on there.Ellamaeellan
@Ellamaeellan Have you tested this on Samsung devices? For some reason, when the device is unlocked, but not in an app on a Samsung device, it still shows a notification.Irresolute
M
6

If I understood your question correctly, you forgot to add flag WindowManager.LayoutParams.FLAG_FULLSCREEN in IncomingCallActivity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    int flags = WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
            | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
            | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
            | WindowManager.LayoutParams.FLAG_FULLSCREEN;

    getWindow().addFlags(flags);

This combination needed to show activity while screen is locked. Hope it helps.

Mcginnis answered 11/9, 2015 at 9:6 Comment(1)
Nope, this had nothing to do with it.Ellamaeellan
E
5

Figured it out! It was something stupid just as I suspected.

In my IncomingCallActivity I had the following bit of code

public void onPause() {
    super.onPause();
    finish();
}

It turns out that something having to do with how Notifications get shown actually calls onPause, therefore finishing the activity.

Thanks to @JohanShogun for attempting to help out.

Ellamaeellan answered 11/9, 2015 at 20:26 Comment(6)
I don't think you need FLAG_DISMISS_KEYGUARD though. That way the user's phone will still be locked when they hang up. An added security benefit.Hendry
You do, you cannot unlock someone's phone like this, it just temporarily ignores the lock.Ellamaeellan
I know for a fact that FLAG_DISMISS_KEYGUARD will unlock the device if the user doesn't have a secure lock, like if the user just has swipe-to-unlock configured. You are right, though, if the user has a pattern of pin configuredHendry
Do you still have to explicitly start the activity or does the notification do it automatically?Irresolute
@wdavies973 the notification does it automatically, as long as you have full screen intent on there.Ellamaeellan
@Ellamaeellan Have you tested this on Samsung devices? For some reason, when the device is unlocked, but not in an app on a Samsung device, it still shows a notification.Irresolute
D
1
//in android 10 a permssion is used try it
 
 <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/>
Dilapidated answered 19/3, 2021 at 11:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.