Show dialog activity over another app from background

家住魔仙堡 提交于 2019-11-30 09:14:32

问题


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.


回答1:


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.




回答2:


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



来源:https://stackoverflow.com/questions/39479508/show-dialog-activity-over-another-app-from-background

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!