6

假设您有一个应用程序 A 打开另一个应用程序 B(例如地图),它不受您控制(即它是一个预先存在的应用程序)。所以现在应用程序 A 在后台。假设发生了一个事件,A 想要在应用 B 的 UI 上显示一个浮动对话框(同时让应用 B 的活动在其后面可见)。这可能吗?

(对此的通常答案是显示通知,但这不是大众市场应用程序,我们正试图非常直接地引起用户的注意。)

目前,我正在尝试做这样的事情:

// 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 活动和后台堆栈上的应用程序 B 活动之间插入对话框。

4

3 回答 3

9

为了让对话活动显示在另一个应用程序上,必须做一些事情:

  • 对话活动必须有一个半透明的主题,以允许其他应用程序出现在它后面(参见 参考资料@android:style/Theme.Translucent.NoTitleBar
  • 出于同样的原因,对话框活动不得填满屏幕(请参阅Window.setLayout
  • 对话活动必须是与基础活动分开的任务的一部分,这样当它显示在其他应用程序上方时,它不会将基础活动也拉到其他应用程序上方(请参阅 参考资料FLAG_ACTIVITY_NEW_TASK
  • 对话框活动必须放在最前面,以便在启动它的活动在后台运行时仍会显示它(请参阅 参考资料FLAG_ACTIVITY_REORDER_TO_FRONT
  • 对话活动必须以某种方式显示对话,例如通过创建一个Dialog直接扩展该类的类

在启动对话活动的代码中:

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是对应用程序的主要活动的引用。

给对话活动 a 可能会有所帮助launchModesingleInstance确保它不会在其任务中累积其他活动,但这可能是不必要的。@android:style/Theme.Translucent.NoTitleBar主题允许其下方的活动显示出来。

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

对于对话框活动本身,可能需要调整其窗口以确保它不会填满整个屏幕:

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

同样,在对话框活动的布局 XML 中,也可能需要:

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

对于对话框本身,您可以做很多事情,但一种解决方案是扩展Dialog类:

class DialogActivity extends Dialog { ... }

要显示活动中的对话框,只需创建 Dialog 的新实例并调用其show()方法。

于 2016-09-25T20:10:27.877 回答
0

我认为 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>

但是由于我在没有 Compat 或 Support 库的手机上使用 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>
于 2019-12-04T17:40:07.470 回答
-1

对的,这是可能的。您需要实现自定义操作和广播接收器来注册您的自定义事件。

您的应用程序 A 触发自定义操作,而您的应用程序 B 中编写并注册到该操作的广播接收器可以检测到事件。然后你需要在你的接收器中显示对话框。

这可能很棘手。祝你好运

于 2016-09-13T21:53:55.667 回答