从后台在另一个应用程序上显示对话框 activity
Show dialog activity over another app from background
假设您有一个应用程序 A,它打开了另一个应用程序 B(例如地图),而后者不受您的控制(即它是一个预先存在的应用程序)。所以现在应用程序 A 在后台。假设发生了一个事件,A 想在应用 B 的 UI 上显示一个浮动对话框(同时让应用 B 的 activity 在它后面可见)。这可能吗?
(通常对此的回答是显示通知,但这不是大众市场应用程序,我们正试图非常直接地引起用户的注意。)
目前,我正在尝试做这样的事情:
// 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);
来自应用 A(后台应用)。
但是当我这样做时发生的事情是对话框被插入之间原始应用程序 A activity 和背面的应用程序 B activity堆叠.
是的,这是可能的。您需要实现自定义操作和广播接收器才能注册您的自定义事件。
您的应用程序 A 触发了一个自定义操作,您在应用程序 B 中编写并注册到该操作的广播接收器可以检测到事件。然后你需要在你的接收器中显示对话框。
这可能很棘手。祝你好运
为了在另一个应用程序上显示一个对话框 activity,必须做一些事情:
- 对话框 activity 必须有一个半透明的主题,以允许其他应用程序显示在它后面(参见
@android:style/Theme.Translucent.NoTitleBar
)
- 对话框 activity 不得填满屏幕,原因相同(参见
Window.setLayout
)
- 对话框 activity 必须是独立于基础 activity 的任务的一部分,这样当它显示在其他应用程序上方时,它不会拉动基础 activity 也高于其他应用程序(参见
FLAG_ACTIVITY_NEW_TASK
)
- 对话框 activity 必须放在最前面,这样即使从 activity 启动它的 运行 在后台,它仍然会显示(参见
FLAG_ACTIVITY_REORDER_TO_FRONT
)
- 对话框 activity 必须以某种方式显示对话框,例如通过创建一个 class 直接扩展
Dialog
class
在启动对话框的代码中 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);
在上面,baseActivity
是对应用程序主要 activity 的引用。
给对话 activity 一个 launchMode
的 singleInstance
可能会有所帮助,确保它永远不会在其任务中累积其他活动,但这可能是不必要的。 @android:style/Theme.Translucent.NoTitleBar
主题允许其下方的 activity 显示出来。
<activity
android:name=".DialogActivity"
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
</activity>
对于对话框 activity 本身,可能需要调整其 window 以确保它不会填满整个屏幕:
getWindow().setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
同样,在对话框activity的布局XML中,可能还需要:
android:layout_width="fill_parent"
android:layout_height="wrap_content"
对于对话框本身,您可以做很多事情,但一种解决方案是扩展 Dialog
class:
class DialogActivity extends Dialog { ... }
要显示来自 activity 的对话框,只需创建一个新的对话框实例并调用其 show()
方法。
我认为 Nanda Gopal 在另一个帖子中回答了这个问题。但这里没有,让我试试。
我的解决方案来自:https://blog.mindorks.com/how-to-create-a-transparent-activity-in-android
即:
<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>
但是因为我在 phone 上使用 APK Builder,它没有兼容或支持库;以下对我有用:
<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>
假设您有一个应用程序 A,它打开了另一个应用程序 B(例如地图),而后者不受您的控制(即它是一个预先存在的应用程序)。所以现在应用程序 A 在后台。假设发生了一个事件,A 想在应用 B 的 UI 上显示一个浮动对话框(同时让应用 B 的 activity 在它后面可见)。这可能吗?
(通常对此的回答是显示通知,但这不是大众市场应用程序,我们正试图非常直接地引起用户的注意。)
目前,我正在尝试做这样的事情:
// 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);
来自应用 A(后台应用)。
但是当我这样做时发生的事情是对话框被插入之间原始应用程序 A activity 和背面的应用程序 B activity堆叠.
是的,这是可能的。您需要实现自定义操作和广播接收器才能注册您的自定义事件。
您的应用程序 A 触发了一个自定义操作,您在应用程序 B 中编写并注册到该操作的广播接收器可以检测到事件。然后你需要在你的接收器中显示对话框。
这可能很棘手。祝你好运
为了在另一个应用程序上显示一个对话框 activity,必须做一些事情:
- 对话框 activity 必须有一个半透明的主题,以允许其他应用程序显示在它后面(参见
@android:style/Theme.Translucent.NoTitleBar
) - 对话框 activity 不得填满屏幕,原因相同(参见
Window.setLayout
) - 对话框 activity 必须是独立于基础 activity 的任务的一部分,这样当它显示在其他应用程序上方时,它不会拉动基础 activity 也高于其他应用程序(参见
FLAG_ACTIVITY_NEW_TASK
) - 对话框 activity 必须放在最前面,这样即使从 activity 启动它的 运行 在后台,它仍然会显示(参见
FLAG_ACTIVITY_REORDER_TO_FRONT
) - 对话框 activity 必须以某种方式显示对话框,例如通过创建一个 class 直接扩展
Dialog
class
在启动对话框的代码中 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);
在上面,baseActivity
是对应用程序主要 activity 的引用。
给对话 activity 一个 launchMode
的 singleInstance
可能会有所帮助,确保它永远不会在其任务中累积其他活动,但这可能是不必要的。 @android:style/Theme.Translucent.NoTitleBar
主题允许其下方的 activity 显示出来。
<activity
android:name=".DialogActivity"
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
</activity>
对于对话框 activity 本身,可能需要调整其 window 以确保它不会填满整个屏幕:
getWindow().setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
同样,在对话框activity的布局XML中,可能还需要:
android:layout_width="fill_parent"
android:layout_height="wrap_content"
对于对话框本身,您可以做很多事情,但一种解决方案是扩展 Dialog
class:
class DialogActivity extends Dialog { ... }
要显示来自 activity 的对话框,只需创建一个新的对话框实例并调用其 show()
方法。
我认为 Nanda Gopal 在另一个帖子中回答了这个问题。但这里没有,让我试试。
我的解决方案来自:https://blog.mindorks.com/how-to-create-a-transparent-activity-in-android
即:
<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>
但是因为我在 phone 上使用 APK Builder,它没有兼容或支持库;以下对我有用:
<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>