【问题标题】:How do I get active window that is on foreground?如何获得前台的活动窗口?
【发布时间】:2014-06-23 15:05:15
【问题描述】:

我的 Q 很简单。

我无法从我的服务中修改当前活动窗口的属性。 我在堆栈上看到了一些线程,也在其他地方,但没有一个真正回答。 前台(活动)活动可以是任何东西。我无权访问它。

这家伙似乎问同样的 Q,没有得到 A... How to get the foreground activity instance?

提前多谢!

【问题讨论】:

  • 您需要在每个活动中单独注册一个广播接收器,以便它可以从您的服务接收更新。
  • 感谢您的回答。不幸的是,这不是我需要的。我想根据我的服务中发生的事件调暗显示。 AFAIK,我只能通过修改前台应用程序窗口的属性来做到这一点。有什么解决办法吗?
  • 是的,我无法在这些活动中注册 BCast 接收器,因为它们可以是任何东西,但不是我的 :)

标签: java android service android-activity window


【解决方案1】:

无障碍服务提供了一种与前台服务交互的方法。这有点像一种解决方法,但仍然有效。

要利用这一点,请扩展 Accessibility Service 并创建一个新类。监听 AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED 事件。每当更改前台活动时都会触发此事件。当前前台进程名称可从事件对象中获得。

AccessibilityService.java

public class AccessibilityService extends android.accessibilityservice.AccessibilityService{
    public static AccessibilityService instance;
    @Override
    public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
        // Note : This event is sometimes called more than one for a foreground service
        if (accessibilityEvent.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED){
            Log.d("Event","TYPE_WINDOW_STATE_CHANGED");
            Log.d("Pkg",accessibilityEvent.getPackageName().toString());

            // Check PackageName matching here and continue with code
            // Here we prevent whatsapp from opening
            // Each time it launches we simulate the press of back button
            if (accessibilityEvent.getPackageName().equals("com.whatsapp")){
                doAction();
            }

        }

    }

    @Override
    public void onInterrupt() {

    }

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        Log.d("Accessibility","Service Connected");
    }

    public void doAction(){
        performGlobalAction(GLOBAL_ACTION_BACK);
    }
}

在这里,我检查前台服务是否是 Whatsapp,如果是,则继续执行我的代码。

除了这个类,这个服务必须在应用程序部分的清单文件中声明,以及 res/xml 文件夹中的配置文件

<service android:name=".AccessibilityService"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
            <intent-filter>
                <action android:name="android.accessibilityservice.AccessibilityService" />
            </intent-filter>
            <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/serviceconfig"/>
</service>



服务配置.xml

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:accessibilityFlags="flagDefault"
    android:notificationTimeout="100"
    android:canRetrieveWindowContent="true"
    />


还要确保用户允许无障碍服务权限。
用于记录前台进程名称的示例应用程序的完整代码位于https://github.com/abinpaul1/Android-Snippets/tree/master/GetForegroundService

【讨论】:

    【解决方案2】:

    不幸的是Android似乎不支持这种需求,从后台运行的服务修改顶级应用的窗口。

    我发现这是迄今为止最合适的做法:

    http://developer.android.com/guide/components/services.html

    " 向用户发送通知 运行后,服务可以使用 Toast 通知或状态栏通知通知用户事件。

    toast 通知是在当前窗口表面出现片刻然后消失的消息,而状态栏通知在状态栏中提供一个带有消息的图标,用户可以选择该图标以获取操作(例如开始一项活动)。

    通常,当某些后台工作已完成(例如文件已完成下载)并且用户现在可以对其进行操作时,状态栏通知是最佳技术。当用户从展开的视图中选择通知时,通知可以启动一个活动(例如查看下载的文件)。

    有关详细信息,请参阅 Toast 通知或状态栏通知开发人员指南。”

    【讨论】:

      猜你喜欢
      • 2018-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-13
      • 2011-12-02
      • 2020-09-11
      相关资源
      最近更新 更多