繁体   English   中英

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

[英]Android, Detect when other apps are launched

我正在尝试开发一个阻止用户在没有密码的情况下进入指定应用程序的应用程序。 情况是...

  1. 用户点击“电子邮件”应用程序(例如)
  2. 我的应用检测到应用启动
  3. 我的应用程序确认它是“电子邮件”应用程序
  4. 我的应用在顶部打开一个视图,要求输入密码
  5. 用户输入密码,如果正确,我的应用程序消失,将“电子邮件”应用程序放在顶部

我可以做其余的事情,只是第2部分让我感到困惑,并且经过许多天阅读了《广播意图》等并尝试在我的试用项目中收听“ android.intent.action.MAIN”等之后,似乎可以检测到我的应用以外的其他应用何时启动。

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

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

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

并且不要忘记在清单文件中添加它的权限。

一个花哨的方法是通过定时循环检查服务

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

您遍历该列表以查看电话上正在运行的内容。 现在您可以使用id和processName来标识它们,因此对于标准活动而言,这对于自定义对象很容易实现,除非您停止将它们全部加以区分...

注意:这并不是屏幕上实际存在的内容的列表,只是正在运行的内容的列表...可能会使目标无效,但至少您会知道什么时候开始运行...它将一直存在即使在后台也列出。

对于密码,您可以在发现一个受保护的应用或其他应用后立即开始活动。

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应用程序。

Application启动时(或在设备启动时)运行CheckRunningActivity Thread

new CheckRunningActivity().start();

更新:此类需要android.permission.GET_TASKS权限,因此将下一行添加到清单中:

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

我认为并希望这不可能。 考虑一下恶意软件滥用此类功能的难易程度。 您可以听取针对您的意图以及广播的意图,但是启动应用程序不应是广播事件。

您可能能够做的就是更换发射器 如果用户同意。

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

隐式意图是当您想说“有人播放此视频”并且Android选择可以处理该意图的应用时。

当您单击主屏幕上的“电子邮件”图标时,将发生明确的意图。 它专门告诉Android使用完全限定的名称(即com.android.mail或其他名称)打开该特定应用。

AFAIK无法拦截此类明确的意图。 这是Android内置的一种安全措施,任何两个Activity都不能具有相同的完全合格的程序包名称。 这样可以防止第三方克隆该应用程序并伪装成该应用程序。 如果您想做的事情可行,那么从理论上讲,您可以安装一个应用程序,该应用程序可能会阻止竞争对手的所有应用程序正常工作。

您尝试执行的操作违反了Android安全模型。

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

在Android L中不建议使用getRunningTasks()

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

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

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

是一个基本的应用示例,显示了如何使用应用使用情况统计信息API来让用户收集与应用程序使用情况有关的统计信息。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM