Show dialog activity over another app from background
Asked Answered
D

3

7

Say you have an app A which opens up another app B (e.g. a map), which is not controlled by you (i.e. it's a preexisting app). So now app A is in the background. Suppose an event occurs and A wants to show a floating dialog over app B's UI (while leaving app B's activity visible behind it). Is this possible?

(The usual answer to this would be to display a notification, but this is not a mass market app, and we are trying to get the user's attention very directly.)

Currently, I was trying to do something like this:

// This code runs in a class other than app A's main activity,
// and the "activity" variable used here is a reference to that activity.
Intent intent = new Intent(activity, NotificationDialogActivity.class);
// EDIT: I'm not exactly sure whether NEW_TASK helps here or not
// so I removed it, but the REORDER_TO_FRONT would ideally cause
// app A's dialog activity to be moved to the front of the back stack?
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
// The "msg" variable here is just some data being passed to the dialog activity
// I included it here only so it is clear that there is a purpose.
intent.putExtra(NotificationDialogActivity.EXTRA_MSG, msg);
activity.startActivity(intent);

from within app A (the one in the background).

But what happens when I do that is that the dialog gets inserted between the original app A activity and the app B activity on the back stack.

Decretive answered 13/9, 2016 at 21:47 Comment(0)
D
13

In order to have a dialog activity shown over another application, a few things must be done:

  • The dialog activity must have a translucent theme, to allow the other application to show up behind it (see @android:style/Theme.Translucent.NoTitleBar)
  • The dialog activity must not fill the screen, for the same reason (see Window.setLayout)
  • The dialog activity must be part of a separate task from the base activity, so that it when it is shown above the other application, it does not pull the base activity above the other application as well (see FLAG_ACTIVITY_NEW_TASK)
  • The dialog activity must be brought to the front, so that it is still shown if the activity it is being launched from is running in the background (see FLAG_ACTIVITY_REORDER_TO_FRONT)
  • The dialog activity must show a dialog somehow, e.g. by creating a class which extends the Dialog class directly

In the code that starts the dialog activity:

Intent intent = new Intent(baseActivity, DialogActivity.class);
// NEW_TASK allows the new dialog activity to be separate from the existing activity.
// REORDER_TO_FRONT causes the dialog activity to be moved to the front,
// if it's already running.
// Without the NEW_TASK flag, the existing "base" activity
// would be moved to the front as well.
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(DialogActivity.EXTRA_SOME_PARAM, someParamValue);
// The activity must be started from the application context.
// I'm not sure why exactly.
baseActivity.getApplicationContext().startActivity(intent);

In the above, baseActivity is a reference to the main activity of the application.

It may help to give the dialog activity a launchMode of singleInstance, ensuring that it never accumulates other activities in its task, but this may be unnecessary. The @android:style/Theme.Translucent.NoTitleBar theme allows the activity underneath it to show through.

<activity
    android:name=".DialogActivity"
    android:launchMode="singleInstance"
    android:theme="@android:style/Theme.Translucent.NoTitleBar">
</activity>

For the dialog activity itself, it may be necessary to adjust its window to ensure that it doesn't fill the whole screen:

 getWindow().setLayout(
    ViewGroup.LayoutParams.MATCH_PARENT,
    ViewGroup.LayoutParams.WRAP_CONTENT
);

Likewise, in the dialog activity's layout XML, it may also be necessary:

android:layout_width="fill_parent"
android:layout_height="wrap_content"

For the dialog itself, you can do a lot of things, but one solution is to extend the Dialog class:

class DialogActivity extends Dialog { ... }

To show the dialog from the activity, just create a new instance of the Dialog and call its show() method.

Decretive answered 25/9, 2016 at 20:10 Comment(1)
if you try this and your getting your new dialog on top of an existing activity in the background, try adding android:taskAffinity="" in the manifest, so your transparent activity always opens in a new task as clarified in this answer #35729417Simulate
H
0

This question I think is answered by Nanda Gopal in anothe thread. But not here so let me try.

I got the solution from : https://blog.mindorks.com/how-to-create-a-transparent-activity-in-android

Which is:

 <style name="Theme.AppCompat.Transparent.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
     <item name="android:windowIsTranslucent">true</item>
     <item name="android:windowBackground">@android:color/transparent</item>
     <item name="android:windowContentOverlay">@null</item>
     <item name="android:windowNoTitle">true</item>
     <item name="android:windowIsFloating">true</item>
     <item name="android:backgroundDimEnabled">false</item>
</style>

But since I am using APK Builder on my phone which has no Compat or Support library; the following worked for me:

 <style name="Test" parent="@android:style/Theme.Dialog">
     <item name="android:windowIsTranslucent">true</item>
     <item name="android:windowBackground">@android:color/transparent</item>
     <item name="android:windowContentOverlay">@null</item>
     <item name="android:windowNoTitle">true</item>
     <item name="android:windowIsFloating">true</item>
     <item name="android:backgroundDimEnabled">false</item>
</style>
Hardwick answered 4/12, 2019 at 17:40 Comment(0)
R
-1

Yes it is possible. What you need to implement custom actions and broadcast receiver to registered your custom event.

Your app A triggers a custom action and your broadcast receiver which is written in app B and registered to that action can detect event. Then all you need to show dialog in your receiver.

That may be tricky. Good luck

Repression answered 13/9, 2016 at 21:53 Comment(3)
I just clarified my post a little - the app B in this situation is not an app that I am writing. It's actually a preexisting app on the device.Decretive
So if the question is how to show dialog, you already gave correct answer. You need to use floating views as Facebook messenger does. You can find tutorials in the web by writing floating heads as messenger keywordsWhitehot
Is there any way to do this by showing an activity from app A (non-full-screen ideally) in front of app B? Instead of going the floating-view-using-the-window-manager approach like Facebook does? Basically, it I could simply bring one app A activity to the front over app B's activity, that would be the simplest way. But I'm not sure if that's possible.Decretive

© 2022 - 2024 — McMap. All rights reserved.