用户单击“电子邮件”应用程序(例如)
我的应用程序检测到应用程序的启动
我的应用程序确认它是“电子邮件”应用程序
我的应用程序在顶部打开一个视图,要求输入密码
用户输入密码,如果正确,我的应用程序消失,将“电子邮件”应用程序放在顶部
我可以做其余的事情,只是第2部分让我感到困惑,并且经过很多天阅读了Broadcast Intent等,并尝试在我的试用项目中收听“ android.intent.action.MAIN”等似乎无法检测到我的应用程序何时启动。
谁能帮忙?我是否正在寻找正确的方法,寻找新的应用程序来广播启动意图,还是应该在系统日志中读取新的意图,还是用本机代码执行某些操作?
任何指针都会有所帮助,即使您不能完全回答,我也可以做更多研究。非常感谢。伊恩
#1 楼
我认为我们可以使用logcat
并分析其输出。在所有类似的程序中,我均已获得此权限:
android.permission.READ_LOGS
这意味着所有他们使用它,但是似乎程序启动了,然后我们的程序(应用保护程序)就会启动并显示出来。
使用下面的代码:
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();
}
不要忘记在清单文件中添加它的权限。
评论
请把我们的代码放在哪里?在服务中?在onStartCommand()中?
– Haythem souissi
2012年5月30日在1:22
在JellyBean及更高版本中将无法使用。 READ_LOGS权限现在仅保留给系统应用程序。
–冉
2012年7月14日13:18
您对此绝对确定吗?因为即使在JB设备上,Smart AppLock似乎也可以做到这一点。是因为应用程序将自身提升为设备管理员状态吗? play.google.com/store/apps/…
– Karthik Balakrishnan
13年5月16日在18:48
@Torcellite,该应用程序具有“获取正在运行的任务”权限,因此它可能正在使用该技术。
–山姆
15年4月27日在9:30
@Ran现在该怎么做...现在有解决方案可以解决问题中所述的问题,因为我需要在软心豆豆之上...请尽快提供您的反馈...
– Shreyan Mehta
17年4月24日在14:46
#2 楼
一个花哨的方法是使用具有定时循环的服务来检查ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am.getRunningAppProcesses();
您遍历该列表以查看电话上正在运行的内容。
现在您可以使用id和processName来标识它们,因此对于标准活动而言,自定义对象很容易实现,除非您停止将它们难以区分的所有内容...
注意:这不是一个屏幕上实际上是什么列表,只是正在运行的列表...可能会使您的目标无效,但至少您会知道什么东西开始运行...即使在后台,它也将一直位于该列表中不过。
对于密码,您可以在找到受保护的应用后启动活动。
评论
是否可以获取启动/恢复应用的时间?
– 0LLiena
2014年7月17日在20:44
在Android L中,请改用android.app.usage包。 developer.android.com/reference/android/app/usage/…
– Plo_Koon
2015年9月6日下午13:37
#3 楼
我认为并希望这不可能。考虑恶意软件滥用此类功能的难易程度。您可以听取针对您的意图以及广播的意图,但是启动应用程序不应是广播事件。您可能要做的就是更换发射器。如果用户同意。
评论
为什么不可能呢?这是我的设备,我决定在其上运行什么。与我们通常授予的其他权限相比,这有什么问题呢?替代启动器将无法捕获仅由其直接启动的所有应用程序的启动。关于这一点以及关于SO的类似主题有很多评论,声称能够简单地查看意图的通过将是一个巨大的问题,但是没有人解释这个问题是什么,以及为什么它应该被视为如此讨厌以至于现有特权系统无法解决用于向用户清楚说明正在发生的事情。
–凯文·怀特富特(Kevin Whitefoot)
2014年12月1日19:42
随着预期权限的发展,这真是个傻瓜。建立安全模型的目的是启用大多数合法的用例,同时防止大多数(理想情况下)所有利用。不仅需要保护的您(大概是知识渊博的用户),还需要天真的安装应用程序的用户,以及不必考虑其他攻击媒介的应用程序编写者。所有安全性都是权衡:在这种情况下,是在公用事业和电力之间,还是在大规模利用之间。如果您确实想要自己的自由度,则可以克隆Android堆栈并为自己的系统编写代码。
–Pontus Gagge
15年1月4日在19:44
#4 楼
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();
}
}
您可以当前运行
Activity
并检查此Activity
是否对应于Email
应用程序。 在
CheckRunningActivity
启动(或在设备启动)上运行Thread
Application
。new CheckRunningActivity().start();
更新:
此类需要
android.permission.GET_TASKS
权限,因此,将下一行添加到清单中:<uses-permission android:name="android.permission.GET_TASKS" />
评论
我正在使用这种方法,但是由于循环的原因,它会一次又一次地打开“ //在PACKAGE_NAME.ACTIVITY_NAME上显示您的活动”。有什么解决方法吗?
– Anuj Sharma
2014年7月18日在9:08
获得所需结果时停止CheckRunningActivity线程
–Vaaceslav Gaidarji
2014年7月18日在9:14
感谢您的答复,然后如何/何时重新启动此线程?我正在使用即时贴服务。
– Anuj Sharma
2014年7月18日在9:17
根据问题的具体情况,请更详细地描述您想要获得什么。
–Vaaceslav Gaidarji
2014年7月18日在9:21
在这里的代码中,由于while(true)循环从未完成,因此Looper.loop()语句似乎永远不会执行。这是一个错误吗?
–山姆
2014年10月31日上午10:07
#5 楼
主要问题是,当启动器(主屏幕)通常使用显式意图时,您尝试侦听隐式意图。隐式意图是当您想说“有人播放此视频”,而Android会选择可以处理该意图的应用。
显性意图是当您点击主屏幕上的“电子邮件”图标。具体是告诉Android使用完全限定的名称(即com.android.mail或其他名称)打开该特定应用。
AFAIK无法拦截此类明确的意图。这是Android内置的一项安全措施,任何两个Activity都不能具有相同的完全合格的程序包名称。这样可以防止第三方克隆该应用程序并伪装成该应用程序。如果您想做的事情可行,那么从理论上讲,您可以安装一个应用程序,该应用程序可以阻止您所有竞争对手的应用程序正常工作。
您尝试做的事情与Android安全模型背道而驰。
您可以做的一件事是与特定的应用程序开发人员合作,以将意图转发到您的安全系统,但这可能不是您要处理的事情。
#6 楼
在Android L中已弃用getRunningTasks()
。要获取应用使用情况统计信息,您可以使用android.app.usage包中的UsageStats类。
新的应用使用情况统计信息API允许应用程序开发人员收集与应用程序。与不推荐使用的getRecentTasks()方法相比,此API提供了更详细的用法信息。
要使用此API,必须首先在清单中声明
android.permission.PACKAGE_USAGE_STATS
权限。用户还必须通过Settings > Security > Apps with usage access
启用对此应用的访问权限。这是一个基本的应用示例,显示了如何使用应用使用情况统计信息API来让用户收集与应用程序使用情况有关的统计信息。
评论
使用情况统计信息如何帮助您了解哪个应用程序处于前台?
–阿贾伊
15年10月16日在11:01
#7 楼
也许您需要一项服务,而这些服务将在后台不断运行。比起您所说的服务。还使用类别android.intent.category.LAUNCHER监听android.intent.action.MAIN。然后让该广播接收器重写onReceive方法,并进行检查以查看应用程序的名称等。评论
这听起来似乎只是我正在考虑的方法,但是我正在努力使用基本的BroadcastReceiver来接收MAIN(目录发射器)广播。以前有人设法做到这一点吗?在这个阶段,我只是想检测一个应用程序已启动或恢复。然后,我可以将包名称与包含我要查找的名称的字符串进行比较。
–伊恩
2010年7月21日在13:47
评论
我不确定他们是如何做到的,但是诸如App Protector之类的应用程序确实可以满足您的要求,因此从技术上来说确实可行。@lan您如何解决您的问题,请您分享您的知识
嗨,你有解决方案吗?