是否有一种原生的android方法来从服务获取对当前运行的Activity的引用?
我有一个在后台运行的服务,我想在事件发生时(在服务中)更新我当前的Activity.有没有一种简单的方法(就像我上面建议的那样)?
在Android L中,Google已禁用getRunningTasks.现在它只能返回自己的应用程序任务和主启动器.我再也无法获得其他应用程序任务了.我们的应用需要该方法来确定当前的顶级应用.任何人都有另一种方法来做到这一点?
我在谷歌搜索过,除此之外没有其他相关主题:https: //code.google.com/p/android-developer-preview/issues/detail?id = 29
您可能知道,自Android 5启动以来,访问设备的最近任务(使用情况统计信息)需要用户手动启用此功能(设置 - >安全 - >使用权限).
我的应用程序检查设备是否使用Android 5,如果是,则为用户提供打开设置屏幕以启用使用权限的可能性:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivityForResult(intent, 12345);
Run Code Online (Sandbox Code Playgroud)
当我尝试在运行Android 5的三星设备中执行此操作时出现问题...当执行上面显示的行时出现此错误:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.settings.USAGE_ACCESS_SETTINGS }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1801)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1499)
at android.app.Activity.startActivityForResult(Activity.java:3913)
Run Code Online (Sandbox Code Playgroud)
似乎尚未实现Settings.ACTION_USAGE_ACCESS_SETTINGS操作,这很奇怪,因为如果您转到"设置"选项以启用应用程序以访问此使用情况统计信息是...
知道如何解决这个特定情况下的这个问题?
android usage-statistics samsung-mobile android-5.0-lollipop
我的应用程序允许在最近推出时对应用列表进行排序.
从Android"L"开始,函数getRecentTasks将返回当前应用程序已启动的应用程序列表,如文档中所述:
如果您的应用使用ActivityManager.getRecentTasks()...
通过在即将发布的版本中引入新的并发文档和活动任务功能(请参阅下面的"最近的并发文档和活动"屏幕),现在不推荐使用ActivityManager.getRecentTasks()方法来提高用户隐私.为了向后兼容,此方法仍然返回其数据的一小部分,包括调用应用程序自己的任务以及可能的一些其他非敏感任务(例如Home).如果您的应用使用此方法检索自己的任务,请使用android.app.ActivityManager.getAppTasks()来检索该信息.
使用ADT显示此功能的文档(当前在Internet上不可用)时写入相同内容:
不推荐使用此方法.从L开始,此方法不再适用于第三方应用程序:因为引入以文档为中心的最新版本意味着它可能会将个人信息泄露给调用者.为了向后兼容,它仍将返回其数据的一小部分:至少是调用者自己的任务(尽管请参阅getAppTasks()以获取正确支持的方式来检索该信息),并且可能还有一些其他任务,例如home已知的不敏感.
我不明白为什么采取这种行为,因为很容易看到用户拥有哪些应用程序,甚至没有任何许可.
事实上,这是我添加的这个功能的一大限制,所以我希望有办法克服这个问题.
目前,我只使用了一种关于最近推出了哪些应用程序的启发式方法 - 我得到了正在运行的进程列表.
我也可以使用流程的重要性值,也许还可以使用"importanceReasonComponent",但这只是所有的启发式和猜测......
有没有办法克服这个限制?我没有想到的任何解决方法?
也许这有可能与root?还是BusyBox?
我在应用程序中有一个服务,我可以从不同的应用程序中获得此服务.当尝试绑定此服务的应用程序时,我想知道哪个应用程序试图在onBind函数中绑定我的服务,但我无法在onBind函数中获取此应用程序的包名称或UID.
是否可以获取试图在onBind函数中绑定我的服务的应用程序名称或UID?
我正在尝试确定用户当前可见的应用程序.为此,我使用该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说它没有指定.有没有办法正确订购它们?
谢谢!
我有一个非常有趣的问题.
我的印象是当我的应用程序使用麦克风时,Android系统进程(如传入或传出呼叫)需要麦克风,我的应用程序无需任何考虑即可释放它.
但我想这不再是问题,因为我收到的抱怨很少,当使用应用程序并且有来电时,通话中的另一方听不到.
是否有任何方法可以确保每当系统进程请求麦克风释放时?
我目前正在开发一款适用于平板电脑的应用程序,可以在商店中展示广告.我需要为设置应用程序添加密码保护.为此,我需要检测设置应用程序是在后台服务中启动的.对于Android版本低于API 21的设备,可以使用getRunningTasks()完成此操作.不幸的是,此方法现已弃用.我尝试用这个答案实现我的目标,但事情并没有按照我的需要运作.我正在试着听,V/WindowManager( 740): Adding window Window{1f4535ef u0 com.android.settings/com.android.settings.Settings} at 9 of 16 (before Window{e14eed2 u0 Starting com.android.settings})但我不能把它当成输出.我正在使用上面引用的答案中的代码.而不是烘烤它我在logcat中打印它.
你能告诉我如何在API 21以上的Android版本中实现我的目标吗?我知道这是可能的,因为像Smart AppLock这样的应用程序可以实现.提前致谢!
如果用户伪造该位置,我将阻止用户使用我的应用.所以我isFromMockProvider用来检查位置是否是假的(按照这里).但isFromMockProvider()在某些情况下可能会为伪造的位置返回false.
public void onLocationChanged(Location location) {
textView.append("long:"+location.getLatitude()+" - lat:"+location.getLongitude()+" - isMock :"+location.isFromMockProvider() + "\n");
}
Run Code Online (Sandbox Code Playgroud)
我的情况是:我使用假冒伪劣GPS定位到一个位置然后我禁用虚假位置并转到我的应用程序.然后onLocationChanged返回假位置isFromMockProvider() = false
录像机:https://www.youtube.com/watch?v = rWVvjOCaZiI(在此视频中,我目前的位置是16.06,108.21,假位置是36.26,138.28.你可以在上一个视频中看到位置是36.26, 138.28但isFromMockProvider = false)
有没有办法检测用户在这种情况下是否使用虚假位置?任何帮助或建议将非常感谢.
DEMO项目
我使用以下代码来获取android中当前运行的活动名称.
ActivityManager am = (ActivityManager) aContext
.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> alltasks = am
.getRunningTasks(1);
ComponentName componentInfo = alltasks.get(0).topActivity;
componentInfo.getClassName();
System.out.println("Current:"+componentInfo.getClassName());
Run Code Online (Sandbox Code Playgroud)
这在android下面的所有版本中运行良好5.0.但在Android 5.0中,它总是返回启动器活动.
请任何一个帮助,因为我想在所有Android版本中运行应用程序.
我刚刚测试了我的应用程序和CM,ATM Android助手等等.所有这些都无法获得正在运行的进程列表,但它们在预操作系统版本上运行良好.那么Android M(5.1.1)会发生什么?请帮忙!
am = (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> list = am.getRunningAppProcesses();
Log.i(TAG, "LQ::examine list.size()=" + list.size());
Run Code Online (Sandbox Code Playgroud) 我试图列出所有正在运行的应用程序,但我不知道为什么我不能这样做。
当我尝试运行以下命令时,我只返回了我的应用程序。
List<ActivityManager.RunningAppProcessInfo> listProcesses = manager.getRunningAppProcesses();
Run Code Online (Sandbox Code Playgroud)
许多网站告诉使用
List<ActivityManager.RunningTaskInfo> alltasks = am.getRunningTasks(Integer.MAX_VALUE);
Run Code Online (Sandbox Code Playgroud)
但也刚退回了我的申请
没有 root 有什么可以让所有任务/进程运行的吗?
在过去,我发现了下一个杀死应用程序后台进程的方法,给出了它的包名:
public static boolean killApp(final Context context, final String packageName) {
final ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
final List<ActivityManager.RunningAppProcessInfo> pids = am.getRunningAppProcesses();
for (int i = 0; i < pids.size(); i++) {
final ActivityManager.RunningAppProcessInfo info = pids.get(i);
if (info.processName.equals(packageName)) {
android.os.Process.killProcess(info.pid);
if (new File("/system/bin/kill").exists()) {
InputStream inputStream = null;
try {
inputStream = Runtime.getRuntime().exec("kill -9 " + info.pid).getInputStream();
final byte[] buffer = new byte[100];
inputStream.read(buffer);
} catch (final IOException e) {
}
StreamsUtil.closeStream(inputStream);
}
am.killBackgroundProcesses(packageName);
return true;
}
} …Run Code Online (Sandbox Code Playgroud)