我的应用程序允许在最近推出时对应用列表进行排序.
从Android"L"开始,函数getRecentTasks将返回当前应用程序已启动的应用程序列表,如文档中所述:
如果您的应用使用ActivityManager.getRecentTasks()...
通过在即将发布的版本中引入新的并发文档和活动任务功能(请参阅下面的"最近的并发文档和活动"屏幕),现在不推荐使用ActivityManager.getRecentTasks()方法来提高用户隐私.为了向后兼容,此方法仍然返回其数据的一小部分,包括调用应用程序自己的任务以及可能的一些其他非敏感任务(例如Home).如果您的应用使用此方法检索自己的任务,请使用android.app.ActivityManager.getAppTasks()来检索该信息.
使用ADT显示此功能的文档(当前在Internet上不可用)时写入相同内容:
不推荐使用此方法.从L开始,此方法不再适用于第三方应用程序:因为引入以文档为中心的最新版本意味着它可能会将个人信息泄露给调用者.为了向后兼容,它仍将返回其数据的一小部分:至少是调用者自己的任务(尽管请参阅getAppTasks()以获取正确支持的方式来检索该信息),并且可能还有一些其他任务,例如home已知的不敏感.
我不明白为什么采取这种行为,因为很容易看到用户拥有哪些应用程序,甚至没有任何许可.
事实上,这是我添加的这个功能的一大限制,所以我希望有办法克服这个问题.
目前,我只使用了一种关于最近推出了哪些应用程序的启发式方法 - 我得到了正在运行的进程列表.
我也可以使用流程的重要性值,也许还可以使用"importanceReasonComponent",但这只是所有的启发式和猜测......
有没有办法克服这个限制?我没有想到的任何解决方法?
也许这有可能与root?还是BusyBox?
单击应用程序的启动图标会发生什么?
是否始终发送新意图,或者结果有时与从最近任务恢复任务相同?
如果发送了intent,它何时被发送到新活动实例的onCreate()方法,何时通过现有活动的onNewIntent()进行路由?
让我们假设意图通过任务中现有活动的onNewIntent()进行路由.它被发送到哪个活动?最靠近顶部的那个或最靠近根的那个?它是否总是被发送到应用程序的启动活动的实例,或者它有时会被发送到与根目录具有相同亲和力的活动吗?它是否可以被发送到与根不具有相同亲和力的活动?
最后,这一切是如何受到任务中各种活动的各种启动模式(标准,单顶,单实例,单一任务)的影响?
如果有人知道这一切,请帮助我!
我正在尝试使用android Job Scheduler API,而我所要做的就是让Job Scheduler每5秒运行一次.但是当我运行它时,相应的服务每两分钟就会命中一次.我有一个日志记录每次服务时都会记录.我不确定为什么会这样.Job Scheduler是否具有最小间隔时间.我的代码很简单......
JobInfo jobInfo = new JobInfo.Builder(1, new ComponentName(this, UpdateDatabaseService.class))
.setPeriodic(5000)
.build();
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(jobInfo);
Run Code Online (Sandbox Code Playgroud)
这个问题最初是在我尝试运行日常任务时产生的,但它会在当天多次触发服务,并且不遵循时间准则.
让我知道你的想法.
我遇到了一个要求,但我无法得到正确的实施方式,因此需要你的帮助.
我想做的事? - 我想根据我得到的通知执行操作如下:
我做了什么?我已经取得了第一点和第二点.我想达到第3点.我试过以下
public static boolean isApplicationBroughtToBackground(final Activity activity) {
ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(1);
// Check the top Activity against the list of Activities contained in the Application's package.
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
try {
PackageInfo pi = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_ACTIVITIES);
for (ActivityInfo activityInfo : pi.activities) {
if(topActivity.getClassName().equals(activityInfo.name)) {
return false;
}
}
} catch( PackageManager.NameNotFoundException e) {
return false; // Never happens.
}
}
return true;
} …Run Code Online (Sandbox Code Playgroud) 在我的应用程序中,我创建了一个启动Details Activity的通知.我想将此活动添加到当前任务(或后台堆栈)的顶部.例如,我希望应用程序任务(后台堆栈)的行为如下:
但是我得到了这个:
我没有使用FLAG_ACTIVITY_CLEAR_TASK和FLAG_ACTIVITY_NEW_TASK标志.我该怎么办?
编辑:第一张图片只是一个例子.我认为问题的标题是完全明确的.我想在当前堆栈的顶部添加Details Activity,而不是从新任务开始.
这就是我创建的方式PendingIntent:
// Details activity intent
Intent intent = new Intent(context, DetailsActivity.class);
intent.putExtra(Com.KEY_ID, event.getId());
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
Run Code Online (Sandbox Code Playgroud)
这是显而易见的:
<activity
android:name=".MainActivity"
android:label="@string/app_name_system"
android:launchMode="singleTop"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".NoteActivity"
android:label="@string/app_name_system"
android:theme="@style/AppTheme.NoActionBar"
android:windowSoftInputMode="stateHidden" />
<activity
android:name=".DetailsActivity"
android:launchMode="singleTop"
android:label="@string/app_name_system"
android:theme="@style/AppTheme.NoActionBar" />
Run Code Online (Sandbox Code Playgroud) 根据文档,singleTask活动不能有多个实例.我的应用程序的唯一活动是singleTask,它同时有2个实例.
在Android Studio 3.3.1中创建一个新项目,Add No Activity,将其命名为singleTaskBug,(package com.example.singletaskbug),使用最低API级别为21的Java语言,而不支持即时应用程序.
通过编辑手动添加一个新的活动AndroidManifest.xml,然后创建一个新的Java类app⯈ java⯈ com.example.singletaskbug命名LauncherActivity.
内容AndroidManifest.xml:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".LauncherActivity"
android:excludeFromRecents="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
Run Code Online (Sandbox Code Playgroud)
内容LauncherActivity.java:
package com.example.singletaskbug;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
public class LauncherActivity extends Activity {
static int instanceCounter = 0;
final int instanceId; …Run Code Online (Sandbox Code Playgroud) 我有2个活动:活动A和活动B.活动A的启动模式是标准的,活动B的启动模式是singleTask.
<activity
android:name=".AActivity"
android:label="@string/app_name"
android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="dd"></data>
<data android:host="a"></data>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
<activity
android:name=".BActivity"
android:label="@string/app_name"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="dd"></data>
<data android:host="b"></data>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
Run Code Online (Sandbox Code Playgroud)
我启动了应用程序,启动器启动了活动A. 然后我按下主页按钮并返回到手机的主屏幕.然后我启动浏览器应用程序并输入以下内容:
dd://b
Run Code Online (Sandbox Code Playgroud)
打开活动B.系统导航到我的应用程序并在活动A之上启动活动B.此时,如果我按回按钮,活动B将弹出,我看到活动A.
这不是我所期望的,因为android文档说明:
对于singleTask活动,系统会创建新任务并在新任务的根目录下实例化活动.但是,如果活动的实例已存在于单独的任务中,则系统会通过调用其onNewIntent()方法将意图路由到现有实例,而不是创建新实例.一次只能存在一个活动实例.
我从这些句子中理解的是,在我的情况下,因为活动B的实例不存在,所以应该启动一个新任务,它应该只有活动B在它的堆栈(我的应用程序的另一个实例应该仍然存在于单独的任务,它的堆栈中应该有活动A. 然后,如果我在活动B时按回,因为它是后台堆栈中的唯一活动,它会弹出并且系统返回到浏览器.
为什么不是这样的?android系统如何知道我的应用程序是打开并导航到它并在现有应用程序堆栈上启动活动B而不是启动我的应用程序的另一个实例并让我的应用程序的两个实例拥有自己的堆栈?在新任务中实例化活动意味着什么?谁能解释一下?
谢谢.
我想阻止用户离开我的应用.我试图通过家庭启动器活动/应用程序实现这一点,我不明白android的行为.首次按HOME将始终在新任务中创建新活动,而不是将现有活动移动到前台.当第二次按HOME时,没有任何反应.见例子:
我有一个登录活动(A)和设置活动(B).B从A打开.A被设置为启动器(LAUNCHER,DEFAULT,HOME类别).
当A的launchMode是singleTop,singleTask或standard时,我得到相同的行为.使用singleInstance只有一个A,但B在T1中单独使用,我不希望这样.
为什么总会创建一个新任务?所有intents标志始终设置FLAG_ACTIVITY_NEW_TASK标志.为什么android会这样做?
这与此处或此处发布的行为相同吗?我无法使用该解决方案,因为android创建了一个新任务,因此A将永远是根.(或者我如何检查这是第二个实例?)
我不能在这里发布使用singleInstance,因为我不希望B单独使用(如果A是可见的,它也是唯一的活动和任务(登录目的)).我试图通过ActivityManager删除所有其他任务,但是对于SDK> = 21,我的min是16.getAppTasks()
我甚至无法使用此解决方案,因为我从未意识到FLAG_ACTIVITY_BROUGHT_TO_FRONT标志.始终存在FLAG_ACTIVITY_RESET_TASK_IF_NEEDED标志.
我已经尝试了很多与launchMode,clearTaskOnLaunch,noHistory的组合......但没有成功 - 总是新任务.
不知道怎么解决这个问题?在棒棒糖上运行.谢谢.
android android-intent android-launcher android-homebutton android-task
假设您有一个应用程序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 …Run Code Online (Sandbox Code Playgroud) 我正在阅读这篇关于 Android 上任务劫持的文章:https ://blog.dixitaditya.com/android-task-hijacking/
我尝试了建议的修复,但仍然可以重现该问题。我还尝试在恶意应用程序的 Android Manifest 中将 Instagram、Gmail 应用程序的包名称指定为android:taskAffinity值,并在单击 Instagram、Gmail 后将我重定向到恶意应用程序。那么,为什么 Gmail 和 Instagram 容易受到此影响,还是我在某个地方弄错了?
Android 上是否有针对此问题的正确解决方案?
android android-activity back-stack android-task android-security