自动阻止应用程序从启动器启动

发布于 2024-10-19 19:41:21 字数 416 浏览 2 评论 0原文

有一类 Android 应用程序可以对某些用户指定的应用程序启用密码保护;例如,Android 保护器。我需要从不同的方向来解决这个问题。

是否可以创建一个应用程序来阻止所有活动启动,除非它们位于预定义的白名单上?这种方法会产生意想不到的后果吗?我熟悉 Android 基础知识,并编写了一些相当简单的应用程序,但我仍在尝试弄清楚这些“保护器”应用程序如何正确拦截启动意图。有人介意向我简要介绍一下执行此操作的正确方法吗?

基本问题是我们有一个通用的 Android 手机需要锁定,以便我们的客户(仅限内部)可以访问我们的自定义应用程序,而无法玩“极品飞车”等。我想删除运营商膨胀软件,但 root 设备似乎是一个令人头痛的维护问题。我们希望每部手机的设置都像安装一些自定义应用程序一样简单。

There are a class of Android applications that enable password protection on certain user-specified apps; for example, Android Protector. I need to approach this problem from a different direction.

Is it possible to create an application that blocks all activity launches unless they are on a predefined whitelist? Will there be unintended consequences with this approach? I am familiar with Android basics and have written a few reasonably simple apps, but I'm still trying to figure out how these "Protector" apps intercept the launch intents correctly. Would someone mind giving me a brief overview on the correct way to do this?

The basic problem is that we have a generic Android phone that needs to be locked down so that our clients (internal only) can access our custom applications without being able to play "Need for Speed", etc. I would like to remove the carrier bloatware, but rooting the device seems like it would be a maintenance headache. We want the setup for each phone to be as simple as installing a few custom applications.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

粉红×色少女 2024-10-26 19:41:21

编辑以详细说明解决方案

概述

我的简单解决方案是向我的应用程序添加新的服务和活动。该服务使用 HandlerpostDelayed< /a> 持续调度监控任务。监控任务检查当前活动是否在白名单中。获取当前正在运行的活动涉及 ActivityManager 和调用 getRunningTasks。完成检查后,监控任务会安排自己在 X 秒(在我的例子中为 1)后再次运行。

如果顶部的活动不在白名单中,我们将启动阻止活动,该活动会在当前正在运行的活动上弹出。阻止活动的关键部分是它覆盖 onBackPressed,防止用户简单地返回到“不良”活动。 (据我所知)按主页键是离开此屏幕的唯一方法。

提示

  • 在锁定屏幕中构建后门。例如,我的解决方案在长按后退键时提示输入密码。输入正确的密码后,监控服务将进入睡眠状态 5 分钟,以便我可以进行管理工作
  • 显示被阻止活动的名称
  • 在打开此服务之前收集一个好的白名单!您绝对应该将活动列入白名单:启动器、软件包安装程序、您自己的应用程序(显然)、浏览器,如果您的应用程序具有基于 Web 的组件,

我不喜欢我的服务不断在后台循环;看起来很浪费。我想找到某种方法来在启动新任务时收到通知,但我找不到方法来做到这一点。对于我的特定监控周期值和我的特定手机的电池使用量是可以接受的;尽管您在采用此方法之前绝对应该进行测试。

Edited to elaborate on the solution

Overview

My simple solution was to add a new service and activity to my application. The service uses Handler and postDelayed to continuously schedule the monitoring task. The monitoring task checks that the current activity is on the whitelist. Getting the currently running activity involves ActivityManager and a call to getRunningTasks. After finishing the check, the monitoring task schedules itself to run again after X seconds (1, in my case).

If the activity on top is not on the whitelist, we launch the blocking activity which pops up over whatever is currently running. The key part of the blocking activity is that it overrides onBackPressed, preventing the user from simply going back to the "bad" activity. Pressing the Home key is the only way (to my knowledge) to leave this screen.

Tips

  • Build a backdoor into the lock screen. For example, my solution prompts for a password on a long-press of the back key. After entering the correct password, the monitor service goes to sleep for 5 minutes so I can do my administrative work
  • Display the name of the blocked activity
  • Gather a good whitelist before turning this on! Activities you should definitely whitelist: the launcher, package installer, your own app (obviously), the browser, if your app has a web-based component

I don't like that my service is constantly looping in the background; it seems wasteful. I'd like to find some way to be notified when a new task is being launched, but I couldn't find a way to do that. The battery usage for my particular value of the monitor period and my particular phone is acceptable; though you should definitely test before adopting this yourself.

深者入戏 2024-10-26 19:41:21

一个有效的解决方案,这是作者意见的代码

public class MonitorService extends Service {

private Handler handler;
Runnable runnable;

@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();
    handler = new Handler();
    runnable = new Runnable() {
        @Override
        public void run() {
            new Thread(new Runnable() {
                @Override
                public void run() {

                    ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

                    List<ActivityManager.RunningTaskInfo> taskInfo = am
                            .getRunningTasks(1);

                    ComponentName componentInfo = taskInfo.get(0).topActivity;                      
                    String currentActivityName=componentInfo.getClassName();
                    String packageName=componentInfo.getPackageName();
                    if(whitelist.contains(currentActivityName)){

                        Intent launchIntent = new Intent();
                        launchIntent.setComponent(new ComponentName(blockActivityPackageName,
                                blockActivityName));
                        launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(launchIntent);

                    }

                }
            }).start();
            handler.postDelayed(this, 1000);
        }
    };
    handler.postDelayed(runnable, 1000);
}

@Override
public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onDestroy() {
    super.onDestroy();
    Intent intent = new Intent(this, MonitorService.class);
    startService(intent);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}

an efective solution,and here is the code from author's opinion

public class MonitorService extends Service {

private Handler handler;
Runnable runnable;

@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();
    handler = new Handler();
    runnable = new Runnable() {
        @Override
        public void run() {
            new Thread(new Runnable() {
                @Override
                public void run() {

                    ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

                    List<ActivityManager.RunningTaskInfo> taskInfo = am
                            .getRunningTasks(1);

                    ComponentName componentInfo = taskInfo.get(0).topActivity;                      
                    String currentActivityName=componentInfo.getClassName();
                    String packageName=componentInfo.getPackageName();
                    if(whitelist.contains(currentActivityName)){

                        Intent launchIntent = new Intent();
                        launchIntent.setComponent(new ComponentName(blockActivityPackageName,
                                blockActivityName));
                        launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(launchIntent);

                    }

                }
            }).start();
            handler.postDelayed(this, 1000);
        }
    };
    handler.postDelayed(runnable, 1000);
}

@Override
public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onDestroy() {
    super.onDestroy();
    Intent intent = new Intent(this, MonitorService.class);
    startService(intent);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}
可爱暴击 2024-10-26 19:41:21

正如您所建议的,编写自定义启动器可能会更干净;查看此开源启动器以供参考 http://code.google.com/p/ adw-启动器-android/

As you suggest, writing a custom launcher is probably would be cleaner; check out this open source launcher for reference http://code.google.com/p/adw-launcher-android/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文