15

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

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

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

4

3 回答 3

7

编辑以详细说明解决方案

概述

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

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

尖端

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

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

于 2011-03-02T22:03:53.133 回答
4

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

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;
}
于 2013-05-14T06:19:18.880 回答
0

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

于 2011-03-14T10:52:30.410 回答