[英]Android, Detect when other apps are launched
I'm trying to develop an app that prevents a user from getting to a specified app without a password. 我正在尝试开发一个阻止用户在没有密码的情况下进入指定应用程序的应用程序。 The scenario is...
情况是...
I'm ok doing the rest of it, just part 2 is puzzling me, and after many days reading up on Broadcast Intents etc and trying to listen for "android.intent.action.MAIN" etc in my trial projects I can't seem to detect when an app other than mine is started. 我可以做其余的事情,只是第2部分让我感到困惑,并且经过许多天阅读了《广播意图》等并尝试在我的试用项目中收听“ android.intent.action.MAIN”等之后,似乎可以检测到我的应用以外的其他应用何时启动。
Can anyone help? 有人可以帮忙吗? Am I going about it the right way, in looking for new apps broadcasting an intent to start, or should I be reading the system log for new intents, or doing something in native code?
我是否正在寻找正确的方式,寻找新的应用程序来广播启动意图,还是应该在系统日志中读取新的意图,还是应该使用本机代码执行某些操作?
Any pointers would help, even if you can't answer it fully I'll be able to do some more research. 任何指点都会有所帮助,即使您无法完全回答,我也可以做更多研究。 Thanks a lot.
非常感谢。 Ian
伊恩
I think we can use logcat
and analyze it's output. 我认为我们可以使用
logcat
并分析其输出。
In all similar programs I have found this permission : 在所有类似的程序中,我都已获得此许可:
android.permission.READ_LOGS
It means all of them use it but it seems the program starts and after that our program (app protector) will start and bring front. 这意味着他们所有人都在使用它,但是似乎程序启动了,之后我们的程序(应用保护程序)将启动并取得领先。
Use below code : 使用以下代码:
try
{
Process mLogcatProc = null;
BufferedReader reader = null;
mLogcatProc = Runtime.getRuntime().exec(new String[]{"logcat", "-d"});
reader = new BufferedReader(new InputStreamReader(mLogcatProc.getInputStream()));
String line;
final StringBuilder log = new StringBuilder();
String separator = System.getProperty("line.separator");
while ((line = reader.readLine()) != null)
{
log.append(line);
log.append(separator);
}
String w = log.toString();
Toast.makeText(getApplicationContext(),w, Toast.LENGTH_LONG).show();
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
And do not forget to add it's permission in Manifest file. 并且不要忘记在清单文件中添加它的权限。
A gimmicky way to do it is have a service with a timed loop that checks 一个花哨的方法是通过定时循环检查服务
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am.getRunningAppProcesses();
You run through that list to look at what is running on the phone. 您遍历该列表以查看电话上正在运行的内容。 Now you can identify them with ids and processName, so for standard activity this is easy for custom ones well unless you stop them all its hard to discriminate...
现在您可以使用id和processName来标识它们,因此对于标准活动而言,这对于自定义对象很容易实现,除非您停止将它们全部加以区分...
Note: this isnt a list of whats is actually on the screen, just a list of whats is running...kinda nullifying your goal maybe but at least you will know when something is starting to run... it will keep being in that list even when in background though. 注意:这并不是屏幕上实际存在的内容的列表,只是正在运行的内容的列表...可能会使目标无效,但至少您会知道什么时候开始运行...它将一直存在即使在后台也列出。
For the password thing you can just start your activity when you found an app thats protected or whatever. 对于密码,您可以在发现一个受保护的应用或其他应用后立即开始活动。
class CheckRunningActivity extends Thread{
ActivityManager am = null;
Context context = null;
public CheckRunningActivity(Context con){
context = con;
am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
}
public void run(){
Looper.prepare();
while(true){
// Return a list of the tasks that are currently running,
// with the most recent being first and older ones after in order.
// Taken 1 inside getRunningTasks method means want to take only
// top activity from stack and forgot the olders.
List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);
String currentRunningActivityName = taskInfo.get(0).topActivity.getClassName();
if (currentRunningActivityName.equals("PACKAGE_NAME.ACTIVITY_NAME")) {
// show your activity here on top of PACKAGE_NAME.ACTIVITY_NAME
}
}
Looper.loop();
}
}
You can get current running Activity
and check if this Activity
corresponds to Email
application. 您可以获取当前正在运行的
Activity
并检查该Activity
对应于Email
应用程序。
Run CheckRunningActivity
Thread
on Application
start (or on device boot). 在
Application
启动时(或在设备启动时)运行CheckRunningActivity
Thread
。
new CheckRunningActivity().start();
Update: This class need android.permission.GET_TASKS
permission, so add next line to the Manifest: 更新:此类需要
android.permission.GET_TASKS
权限,因此将下一行添加到清单中:
<uses-permission android:name="android.permission.GET_TASKS" />
I think and hope this is not possible. 我认为并希望这不可能。 Consider how easily such functionality could be abused by malicious software.
考虑一下恶意软件滥用此类功能的难易程度。 You can listen to intents directed at you, and those that are broadcast, but application launching should not be a broadcast event.
您可以听取针对您的意图以及广播的意图,但是启动应用程序不应是广播事件。
What you may be able to do is replace the launcher . 您可能能够做的就是更换发射器 。 If the user agrees to it.
如果用户同意。
The main issue is you are trying to listen for implicit intents when the Launcher (home screen) is typically using explicit intents. 主要问题是,当启动器(主屏幕)通常使用显式意图时,您正在尝试侦听隐式意图。
An implicit intent is when you want to say "Somebody play this video" and Android picks an app that can handle that intent. 隐式意图是当您想说“有人播放此视频”并且Android选择可以处理该意图的应用时。
An explicit intent is what happens when you click the "Email" icon on the home screen. 当您单击主屏幕上的“电子邮件”图标时,将发生明确的意图。 It is specifically telling Android to open that specific app by fully qualified name (ie com.android.mail or something).
它专门告诉Android使用完全限定的名称(即com.android.mail或其他名称)打开该特定应用。
There is no way AFAIK to intercept such explicit intents. AFAIK无法拦截此类明确的意图。 It is a security measure built into Android that no two Activities can have the same fully qualified package name.
这是Android内置的一种安全措施,任何两个Activity都不能具有相同的完全合格的程序包名称。 This prevents a third party from cloning the app and masquerading as that app.
这样可以防止第三方克隆该应用程序并伪装成该应用程序。 If what you wish to do was possible, you could theoretically install an app that could block all of your competition's apps from working.
如果您想做的事情可行,那么从理论上讲,您可以安装一个应用程序,该应用程序可能会阻止竞争对手的所有应用程序正常工作。
What you are trying to do goes against the Android security model. 您尝试执行的操作违反了Android安全模型。
One thing you could do is partner with specific app developers to forward the intents to your security system, but that's probably not something you want to deal with. 您可以做的一件事是与特定的应用程序开发人员合作,将意图转发到您的安全系统,但这可能不是您要处理的事情。
getRunningTasks()
is deprecated in Android L. 在Android L中不建议使用
getRunningTasks()
。
To obtain app usage statistics you can use UsageStats class from android.app.usage package. 要获取应用使用情况统计信息,您可以使用android.app.usage包中的UsageStats类。
The new App usage statistics API allows app developers to collect statistics related to usage of the applications. 新的App使用情况统计信息API允许应用程序开发人员收集与应用程序使用情况有关的统计信息。 This API provides more detailed usage information than the deprecated getRecentTasks() method.
与不推荐使用的getRecentTasks()方法相比,此API提供了更详细的用法信息。
To use this API, you must first declare the android.permission.PACKAGE_USAGE_STATS
permission in your manifest. 要使用此API,您必须首先在清单中声明
android.permission.PACKAGE_USAGE_STATS
权限。 The user must also enable access for this app through Settings > Security > Apps with usage access
. 用户还必须通过
Settings > Security > Apps with usage access
应用程序”来启用对此应用程序的Settings > Security > Apps with usage access
。
Here is a basic app example showing how to use App usage statistics API to let users collect statistics related to usage of the applications. 这是一个基本的应用示例,显示了如何使用应用使用情况统计信息API来让用户收集与应用程序使用情况有关的统计信息。
Perhaps you need a service, something that will run in the background constantly. 也许您需要一项服务,而这些服务将在后台不断运行。 Than have your service do what you said.
比起您所说的服务。 Listen for the android.intent.action.MAIN also with the category android.intent.category.LAUNCHER.
还使用类别android.intent.category.LAUNCHER监听android.intent.action.MAIN。 Then have that broadcast receiver override the onReceive method and do check to see the name of the application etc.
然后让该广播接收器覆盖onReceive方法,并进行检查以查看应用程序的名称等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.