Android,检测其他应用程序何时启动

时间:2010-07-20 14:22:50

标签: android android-intent broadcastreceiver

我正在尝试开发一款可防止用户在没有密码的情况下访问指定应用的应用。场景是......

  1. 用户点击“电子邮件”应用(例如)
  2. 我的应用检测到应用的启动
  3. 我的应用确认这是“电子邮件”应用
  4. 我的应用打开顶部视图,要求输入密码
  5. 用户输入密码,如果正确,我的应用程序将消失,“电子邮件”应用程序位于顶部
  6. 我正在做剩下的事情,只是第2部分让我感到困惑,经过多天阅读Broadcast Intents等并试图在我的试验项目中听“android.intent.action.MAIN”等我似乎无法检测到我的应用程序何时启动。

    有人可以帮忙吗?我是否正确地寻找新的应用程序广播意图启动,或者我应该阅读系统日志以获取新意图,还是在本机代码中执行某些操作?

    任何指针都会有所帮助,即使你无法完全回答它,我也可以做更多的研究。非常感谢。伊恩

7 个答案:

答案 0 :(得分:33)

我认为我们可以使用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();
    }

不要忘记在Manifest文件中添加它的权限。

答案 1 :(得分:19)

一种花哨的方法是使用带有定时循环检查的服务

ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am.getRunningAppProcesses();

您将浏览该列表以查看手机上正在运行的内容。 现在你可以使用id和processName来识别它们,所以对于标准活动来说,这对于自定义活动很容易,除非你把它们全部停下来很难区别对待......

注意:这不是一个实际上在屏幕上的列表,只是一个正在运行的列表...有点无效你的目标可能但至少你会知道什么时候开始运行...即使在后台也会保持在该列表中。

对于密码,您可以在找到应用时开始活动 那是受保护的还是其他的。

答案 2 :(得分:12)

我想并希望这是不可能的。考虑恶意软件可以轻易滥用此类功能。您可以收听针对您的意图以及广播的意图,但应用程序启动不应该是广播事件。

您可以做的是replace the launcher。如果用户同意。

答案 3 :(得分:12)

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权限,因此请在Manifest中添加下一行:

<uses-permission android:name="android.permission.GET_TASKS" />

答案 4 :(得分:10)

主要问题是当Launcher(主屏幕)通常使用显式意图时,您正在尝试侦听隐式意图。

隐含的意图是当你想说“有人播放此视频”时Android会选择一个可以处理该意图的应用。

当您单击主屏幕上的“电子邮件”图标时,会出现明确的意图。它特别告诉Android通过完全限定名称(即com.android.mail或其他)打开该特定应用程序。

AFAIK无法拦截这种明确的意图。这是Android内置的安全措施,没有两个活动可以拥有相同的完全限定的包名称。这可以防止第三方克隆应用程序并伪装成该应用程序。如果你想做的事情是可能的,理论上你可以安装一个可以阻止所有竞争对手的应用程序工作的应用程序。

您要做的是违反Android安全模型。

您可以做的一件事是与特定的应用开发者合作,将意图转发到您的安全系统,但这可能不是您想要处理的事情。

答案 5 :(得分:7)

Android L中不推荐使用

getRunningTasks()

要获取应用使用情况统计信息,您可以使用UsageStats包中的android.app.usage课程。

新的应用使用情况统计API允许应用开发者收集与应用使用情况相关的统计信息。此API提供了比不推荐使用的getRecentTasks()方法更详细的使用信息。

要使用此API,您必须先在清单中声明android.permission.PACKAGE_USAGE_STATS权限。用户还必须通过Settings > Security > Apps with usage access启用此应用的访问权限。

Here是一个基本的应用示例,展示了如何使用App使用统计信息API来让用户收集与应用使用情况相关的统计信息。

答案 6 :(得分:3)

也许你需要一种服务,这种服务会不断在后台运行。比你的服务做你所说的。使用android.intent.category.LAUNCHER类别监听android.intent.action.MAIN。然后让广播接收器覆盖onReceive方法并检查以查看应用程序的名称等。