只有当应用程序不在前台时,我才需要向用户显示通知.这是我的公共类MyFirebaseMessagingService扩展
FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if(applicationInForeground()) {
Map<String, String> data = remoteMessage.getData();
sendNotification(data.get("title"), data.get("detail"));
}
}
Run Code Online (Sandbox Code Playgroud)
需要实施applicationInForeground()方法
我想在android ics(4.0.3)中记录所有toast事件,但我无法记录任何系统事件.服务还没开始!
根据这个问题: onAccessibilityEvent(AccessibilityEvent事件)没有拦截通知
MyAccessibilityService.java
package com.test.toasts2;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Notification;
import android.os.Parcelable;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.widget.Toast;
public class MyAccessibilityService extends AccessibilityService {
public static final String TAG = "volumeMaster";
@Override
public void onAccessibilityEvent(AccessibilityEvent event)
{
Log.v(TAG, "***** onAccessibilityEvent");
Toast.makeText(getApplicationContext(), "Got event from: " + event.getPackageName(), Toast.LENGTH_LONG).show();
}
@Override
public void onInterrupt()
{
Log.v(TAG, "***** onInterrupt");
}
@Override
public void onServiceConnected()
{
Log.v(TAG, "***** onServiceConnected");
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
info.notificationTimeout = 100; …Run Code Online (Sandbox Code Playgroud) android accessibility-api toast android-4.0-ice-cream-sandwich
我有一个应用程序跟踪应用程序上的用户活动,包括时间等,现在,如果用户已打开应用程序,它将启动一个会话,直到该应用程序中的用户,他的会话将继续,他可以切换到多个活动.现在他同时切换到另一个应用程序,他的会话日志记录应该停止并写入文件
我尝试了什么
我创建了一个基本活动和On resume事件,如果计数器为零,我启动会话并递增计数器和On stop事件,我减少计数器,如果计数器为零,我停止会话
但这不会计算跟踪的实际问题,因为当用户切换到另一个应用程序时,android不会停止活动.
那么有没有办法实现这样的事情.
额外:
如果我们可以在屏幕上查看应用活动是否处于活动状态,那么可以使用事件来开始或结束会话.
问题是,我如何获得当前的活动?已经在Stackoverflow和其他网站上被问了几十次,并且有很多提议的方法.然而,它们都具有某种形式的缺点.
在这篇文章中,我假设Android的API中没有为此提供解决方案,例如:Application.getTask().getRootActivity().
如果有:-)那不是很好吗?
所以,要清楚,我不是要求答案我如何获得当前的活动?
相反,我问的是没有提供这种能力的原因.假设每个正在运行的应用程序都有一个任务(假设任务没有被清空)并且每个这样的任务都有一个root活动,那么提供对该根Activity的访问似乎很容易.
在没有提供这种访问的情况下,当它非常明确地需要时,这对我来说意味着Android架构有一些我不理解的基础.
我错过了什么?为什么Android API不提供此信息?
作为背景,这里是一个概述已经提出的一些方法的部分.我发现以下两个链接特别有用(下面的每个方法都在一个或两个链接中提供).
链接
途径
ActivityManager
ActivityManager方法仅提供Activity类的名称,而不是当前的Activity实例.例如,对于Context实例c:
c.getSystemService().getActivityManager()
.getAppTasks().get(0).getTaskInfo()
.topActivity().getClassName()
反射
我最喜欢的是_AZ提出的反思,但这种方法很脆弱,因为它依赖于内部.我想从Android看到的是这种方法是通过标准API提供的,开发人员可以安全地依赖它.
静电钩
最常见的方法是使用静态挂钩来保存对当前运行的Activity的引用.钩子可以是按活动或按应用程序.通过保存/销毁钩子的值可以避免内存泄漏(例如,在onCreate()/ onDestroy(),onStart()/ onStop(),onPause()/ onResume()).但是,当涉及多个活动时(例如,由于生命周期重叠 - 见下文),可能会出现问题.
我实现了一个静态钩子方法,它执行以下操作(完全透明,我还没有实现#1 - 我目前正在使用per-Activity静态钩子,这是一个bug).
理论上,这将允许我始终知道任务的后台堆栈的完整状态 - 完整的活动集,包括根活动,以及它们的当前状态.然而,在实践中,有一个转折 - 当一个活动开始另一个活动时,它们的生命周期重叠.在此期间,在堆栈停止时偷看可能会产生意外的Activity实例.
来自:https://developer.android.com/guide/components/activities/activity-lifecycle.html#soafa,"协调活动":
以下是活动A启动活动B时发生的操作顺序:
- 活动A的onPause()方法执行.
- 活动B的onCreate(),onStart()和onResume()方法按顺序执行.(活动B现在具有用户关注点.)
- 然后,如果活动A在屏幕上不再可见,则执行onStop()方法
当然,这也可以管理.最重要的是,我们确实有一个可用于存储信息的全局上下文(应用程序),我们确实拥有有关活动生命周期转换的完整信息,因此我付出了足够的努力,我相信这种基于静态堆栈的方法可能会成为相当的子弹 - 证明.
不过最终
但最后我觉得我只是简单地重写代码,这些代码可能已经存在于内部,用于管理一个Activity后台堆栈,这就是为什么我要问(如果你忘记了):
为什么没有用于获取当前活动的Android API?
在这个更新中,我将总结我从这个主题以及我自己的实验和研究中学到的东西.希望这个摘要对其他人有用.
我将根据https://developer.android.com/guide/components/activities/activity-lifecycle.html上的活动状态定义,对"活动可见性状态"使用以下定义.
-----------------------------------
Visibility State Definition
----------------------------------- …Run Code Online (Sandbox Code Playgroud) 假设我有一个应用程序(在调试/发布版本中,由我自己制作),它具有特定视图的ID.
是否可以调用adb命令单击此视图?
我知道可以点击特定的坐标,但是可以使用ID吗?
我问这个是因为我知道"布局检查器"工具(可通过Android Studio获得)和"查看层次结构"工具(可通过"Android设备监视器"获得,以前通过DDMS使用)可以显示视图的ID(和甚至他们的坐标和边界框),所以也许它可以是一个更好的方法来模拟执行一些自动测试时的触摸.
如果需要,我可以使用root方法.
编辑:我设置了一个赏金,万一有一个比我自己的答案更容易/更好的方式,这是解析"adb shell dumpsys活动顶部"的结果.
我想知道是否可以获得屏幕上显示的视图坐标(以及当然的大小),包括关于它们的更多信息(以识别每个).这也应该可以通过设备实现.也许某些东西与"监视器"工具提供的输出数据相同:
请注意它如何获取视图的基本信息,包括文本,id和每个视图的边界.
正如我所读到的,这可能是通过AccessibilityService实现的,但遗憾的是我无法理解它是如何工作的,它的功能是什么,如何触发它,它的要求是什么等等......
我有一个带有AccessibilityService. Android 似乎一直AccessibilityService在运行,但我有时只需要运行我的。(具体来说,如果用户打开我的应用程序并将其关闭,AccessibilityService则不再需要。)
如果我AccessibilityService在不需要的时候运行,那就是在浪费设备的 RAM 和 CPU,如果可能的话,我想避免对我的用户这样做。
如何以编程方式启动和停止我的AccessibilityService?
请注意,我不是要求以编程方式启用或禁用AccessibilityServiceAndroid 的辅助功能设置;这只是在它已经启用时启动和停止它。
AccessibilityService)AccessibilityService使用以下方法禁用组件:
PackageManager.setComponentEnabledSetting(
accessibilityServiceName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
0
);
Run Code Online (Sandbox Code Playgroud)
这杀死了整个应用程序,包括AccessibilityService. 此外,重新启动手机后,AccessibilityServiceAndroid 辅助功能设置中不再可见。(似乎需要重新启用该组件,然后重新启动手机才能使其再次显示。)
AccessibilityService使用以下方法禁用组件:
PackageManager.setComponentEnabledSetting(
accessibilityServiceName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP
);
Run Code Online (Sandbox Code Playgroud)
这并没有阻止AccessibilityService.
停止AccessibilityService使用Context.stopService()和Service.stopSelf()。这些并没有停止服务,大概是因为操作系统绑定到它。
杀死AccessibilityService使用的过程Process.killProcess()。但是,该服务在重新启动并重新连接后不久,大概是因为操作系统绑定到它。
使用 取消注册可访问性事件AccessibilityService.setServiceInfo(new AccessibilityServiceInfo())。这会阻止服务获取可访问性事件,但服务仍会在后台运行。
这只是关于停止服务。我希望能够在服务停止后再次启动它。
在一种方法中,我必须知道屏幕上有哪些活动.我如何获得当前活动?
我有一个Android服务.我想在用户更改应用程序时执行某项任务.是否有广播或活动,我可以听.
如果轮询是唯一的解决方案,任何人都可以建议一些良好的轮询技术.
谢谢.
我在我的一个应用程序中使用getRunningTask API来查找Foreground应用程序.自Lollipop以来,该API已被弃用.在此弃用之后,我更喜欢getRunningAppProcess API以及Importance_Foreground.我还从这个列表中排除了REASON_SERVICE和REASON_PROVIDER.我基于一个完美的逻辑过滤掉了系统应用程序.问题是,如果应用程序A在前台,我将应用程序B作为峰值.所以,这种方法目前值得怀疑.getRunningTask API还有其他替代方案吗?或者我在当前的方法中遗漏了任何简单的事情.请帮帮我们
在我的应用程序中有一个Service和一个AccessibilityService.现在Service受可访问性服务的约束,以便接收信息.
我会Service定期检查是否AccessibilityService已启用,如果未启用,则会向用户发送通知,表明它必须启用它.
启用后,即可AccessibilityService开始工作.首先,它绑定到我Service,之后,它开始发送信息.
问题是如果AccessibilityService崩溃了.它仍然启用但没有正在运行的实例.所以我Service发现它已启用,但实际上AccessibilityService它没有运行.
怎么检查 AccessibilityService
public boolean checkAccesibilityService()
{
int accessibilityEnabled = 0;
boolean accessibilityFound = false;
try {
accessibilityEnabled = Settings.Secure.getInt(
mContext.getApplicationContext().getContentResolver(),
android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);
//Log.v(TAG, "accessibilityEnabled = " + accessibilityEnabled);
} catch (Settings.SettingNotFoundException e) {
Log.e(TAG, "Error finding setting, default accessibility to not found: "
+ e.getMessage());
}
if (accessibilityEnabled == 1) {
//Log.v(TAG, "***ACCESSIBILIY IS ENABLED*** -----------------");
String …Run Code Online (Sandbox Code Playgroud) 请建议我如何获得当前打开的应用程序名称,即使设备上有主屏幕,我也会发现"主屏幕已打开".
android ×11
adb ×1
android-4.0-ice-cream-sandwich ×1
android-view ×1
binding ×1
service ×1
toast ×1