我正在尝试编写一个应用程序,它会在经过一段时间后返回到前台时执行某些特定操作.有没有办法检测应用程序何时发送到后台或带到前台?
我在我的Android应用程序中执行状态栏通知,由c2dm触发.如果应用程序正在运行,我不想显示通知.您如何确定应用程序是否正在运行且位于前台?
我使用以下代码在变量foregroundTaskPackageName中获取前台应用程序的活动名称.它适用于4.1到4.4之间的所有操作系统版本,但在Android 5.0 Lollipop中不起作用.
任何人都可以帮助5.0 Lollipop中的变化吗?在Lollipop中 - 我为foregroundTaskPackageName获取的文本只是'Launcher3'.我正在使用Genymotion仿真器.
ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
RunningTaskInfo foregroundTaskInfo = am.getRunningTasks(1).get(0); // get
// list
// of
// running
// tasks
String foregroundTaskAppName = null;
String foregroundTaskPackageName = foregroundTaskInfo.topActivity
.getPackageName();
Run Code Online (Sandbox Code Playgroud) 我正在尝试确定用户当前可见的应用程序.为此,我使用该activityManager.getRunningAppProcesses()
方法.
我知道Android 5.1.1不支持该方法 - 这没关系.
一开始它就像魅力一样,我正在迭代RunningAppProcessInfos列表并检查重要性.
tl; dr获取当前前台进程和防止错误postives的正确方法是什么?如何完成列表的顺序 - API说它没有指定.有没有办法正确订购它们?
我做了什么:
不幸的是,ActivityManager返回的列表在每个设备上都是不同的.某些设备返回具有重要性100(即FOREGROUND)的多个信息,即使该过程当前不可见.
这引起了我有很多误报的问题.例如,我每次用facebook测试它并创建一个吐司,每次facebook都在前台.我切换到Home,所以我的启动器应该是前台进程.这是10秒之后,在那之后,facebook又重新出现在列表中的FOREGROUND(它不是开放也不可见)而且我得到了误报.
我认识到有些设备按照最近的流程排序列表.所以我决定尝试以下方法:
ActivityManager.RunningAppProcessInfo appProcess = appProcesses.get(0);
final String processName = appProcess.processName;
final String packageName = removeProcessSuffix(processName);
if (appProcess.importance == FOREGROUND || appProcess.importance == VISIBLE){
//do something, like the toast
}
Run Code Online (Sandbox Code Playgroud)
使用appProcesses.get(0); 我只检查第一个元素,然后bug就消失了.再也没有误报了.
但是,现在在某些设备上,我根本不再获得前台进程.因为他们没有以任何方式订购列表.例如,一些4.2索尼智能手机是一些候选人.我得到了列表,但当前可见的进程是索引11左右.
我不知道该怎么做,以获得当前的前台进程,没有误报.
获取当前前台进程并防止错误假设的正确方法是什么?如何完成列表的顺序 - API说它没有指定.有没有办法正确订购它们?
谢谢!
只有当应用程序不在前台时,我才需要向用户显示通知.这是我的公共类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()
方法
目前,我需要执行一些操作
因此,到目前为止,以下代码片段对我很有帮助.我从CommonWare中学到了这样的技巧 - https://commonsware.com/AndroidArch/previews/other-lifecycle-owners和https://proandroiddev.com/react-to-app-foreground-and-background-events-with-processlifecycleowner -96278e5816fa
public class WeNoteApplication extends Application {
public static class AppLifecycleObserver implements DefaultLifecycleObserver {
@Override
public void onResume(LifecycleOwner owner) {
// Do something when the application launched.
// But not during activity recreation, configuration change, ...
}
@Override
public void onPause(LifecycleOwner owner) {
// Do something when the application quit.
// But not during activity recreation, configuration change, ...
}
}
private static final AppLifecycleObserver appLifecycleObserver = new AppLifecycleObserver();
@Override …
Run Code Online (Sandbox Code Playgroud) 在Android 6.0 Marshmallow中,我使用以下代码查询前台应用程序但是传入通知存在问题,因为它向发送通知的应用程序显示了前台应用程序.问题仅存在于Marshmallow中(5.X正常工作).
// API 21 and above
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static String getProcessNew(UsageStatsManager mUsageStatsManager, Context c) throws Exception {
String st = null;
try {
long endTime = System.currentTimeMillis();
long beginTime = endTime - 1000 * 10;
// We get usage stats for the last minute
List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, beginTime,
endTime);
// Sort the stats by the last time used
if (stats != null) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : stats) {
mySortedMap.put(usageStats.getLastTimeUsed(), …
Run Code Online (Sandbox Code Playgroud) android package foreground usagestatsmanager android-6.0-marshmallow
如何检测Android应用程序何时进入后台?onPause() 或 onUserLeaveHint() 有效,但也会在方向更改或呈现其他活动时调用。