100

我正在尝试开发一个应用程序,以防止用户在没有密码的情况下访问指定的应用程序。情节是...

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

我可以做剩下的事情,只是第 2 部分让我感到困惑,经过很多天阅读广播意图等并尝试在我的试验项目中收听“android.intent.action.MAIN”等我不能似乎检测到我以外的应用程序何时启动。

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

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

4

7 回答 7

34

我认为我们可以使用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 文件中添加它的权限。

于 2011-08-30T07:18:07.507 回答
21

一种花哨的方法是提供一个带有定时循环的服务来检查

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

您浏览该列表以查看手机上正在运行的内容。现在您可以使用 ids 和 processName 来识别它们,因此对于标准活动,这对于自定义活动来说很容易,除非您将它们全部阻止,否则很难区分......

注意:这不是屏幕上实际显示的内容的列表,只是正在运行的内容列表......可能有点让你的目标无效,但至少你会知道什么时候开始运行......它会继续存在即使在后台也可以列出。

对于密码问题,您可以在找到受保护的应用程序或其他任何内容时开始您的活动。

于 2010-11-10T20:25:37.430 回答
13
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" />
于 2014-03-10T14:48:59.340 回答
12

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

您可以做的是更换启动器。如果用户同意。

于 2010-07-20T14:33:21.227 回答
11

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

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

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

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

您正在尝试做的事情违反了 Android 安全模型。

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

于 2010-07-20T14:33:00.710 回答
8

getRunningTasks()在 Android L 中已弃用。

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

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

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

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

于 2015-09-06T14:00:54.853 回答
4

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

于 2010-07-20T14:33:07.323 回答