本帖最后由 flying_vip_521 于 2011-09-07 13:50:41 编辑

解决方案 »

  1.   

    您是想要root下的锁还是非root下的锁 是要隐藏用户图标还是要在用户启动某个程序的时候加密码?
      

  2.   

    应该是非root下的吧,如果应用“AAA”被保护的话,在启动“AAA”的时候,先呈现给用户的是密码验证界面,密码验证通过后解锁,如果通过home键或其他键访问到其他应用(如:lanch),则再启动该应用(AAA)的时候需要再次进行密码验证。
      

  3.   

    逻辑上应该是修改apk启动器或delvik虚拟机或ActivityManager或类似的东东,在调用onStart和onResume回调之前进行处理,类似于HOOK
      

  4.   

    可以试下设置intent-filter的优先级
    http://yangguangfu.iteye.com/blog/1063732
      

  5.   

    解决不了,坚决不让帖子沉,求高手指点:如何阻止点击应用的启动,直接进入密码验证界面(目前效果:应用主界面闪过后出现密码验证界面)service代码片段public String getTopPackage() {
    return ((ActivityManager.RunningTaskInfo) this.mActivityManager.getRunningTasks(1).get(0)).topActivity
    .getPackageName();
    }
    public class ProtectorRunnable implements Runnable {
    @Override
    public void run() {
    Log.e(TAG, "--------run-------------");
    Handler handler_ = ProtectorService.this.handler;
    Runnable runnable_ = ProtectorService.this.runnbale;
    String packageName = getTopPackage();
    String className = getTopClass();
    Log.e(TAG, "packageName=" + packageName + "----className=" + className);
    if (!packageName.equals(lastPkgName)) {
    MyApplication.appStatus.remove(lastPkgName);
    // Log.e(TAG, "appSt=atus");
    }
    int id = mActivityManager.getRunningAppProcesses().get(0).pid;
    if (packageName.equals("com.android.settings") && !MyApplication.isPass(packageName)) {
    System.out.println(getTopIntent());
    // mActivityManager.restartPackage(packageName);// 关闭应用,这样就保证了每次打开应用都是重新启动的一个实例
    System.out.println("id="+id);
    android.os.Process.killProcess(id); 

    Intent intent1 = new Intent();
    intent1.setClass(ProtectorService.this, PasswordLock.class);
    intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    lastPkgName = "";
    startActivity(intent1);
    }
    handler_.post(runnable_);
    }
    }
      

  6.   

    需求是什么,防止私人信息被偷看?
    看下activity的相关接口和生命周期,看能否在启动之前被截获
      

  7.   

    反编译过了,只是里边的代码比较乱,有些关键的地方,看不明白。目前的问题是,当我启动应用的时候,这个应用首先启动,主界面启动后,才弹出密码验证界面,体验太差,求解。service中启动一个线程,时时监听log输出情况,当检测到有应用程序启动时,则启动密码验证界面Thread thread = new Thread(new Runnable() {
    public void run() {
    while (flag) {
    System.out.println("////////////////////////////////////////////////////");
    String str1;// log
    String str2;// 类名
    String str3;// 包名
    try {
    // Log.e(TAG, "=========================");
    Runtime localRuntime1 = Runtime.getRuntime();
    String[] arrayOfString1 = new String[2];
    arrayOfString1[0] = "logcat";
    arrayOfString1[1] = "-c";
    Process localProcess1 = localRuntime1.exec(arrayOfString1);
    int i = localProcess1.waitFor(); Runtime localRuntime2 = Runtime.getRuntime();
    String[] arrayOfString2 = new String[2];
    arrayOfString2[0] = "logcat";
    arrayOfString2[1] = "ActivityManager:I *:S"; Process localProcess2 = localRuntime2.exec(arrayOfString2);
    InputStream localInputStream = localProcess2.getInputStream();
    InputStreamReader reader = new InputStreamReader(localInputStream);
    BufferedReader localBufferedReader = new BufferedReader(reader); str1 = localBufferedReader.readLine();//获取log
    am = (ActivityManager) ProtectorService.this.getSystemService("activity");
    ComponentName componentName = ((ActivityManager.RunningTaskInfo) ProtectorService.this.am
    .getRunningTasks(1).get(0)).topActivity;
    str2 = componentName.getClassName();
    str3 = componentName.getPackageName();
    //是否为启动一个应用
    boolean start = str1.contains("android.intent.category.LAUNCHER");
    //是否被保护/密码锁应用
    boolean protector = mRunProList.contains(str3) || str3.equals("com.innofidei.protector");
    System.out.println("ispass==" + !isPass+";start="+start+";protector="+protector);

    //如果应用被保护,且没有通过密码验证,则进入密码验证界面
        //isPass标志应用是否通过密码验证
    if (start && protector && !isPass) {
    System.out.println("----------in------------>");
    // 如果是地址薄和拨号应用,则通过log来确定访问的是哪个tab页
    if (str3.equals("com.android.contacts")) {
    Intent intent = new Intent();
    intent.addCategory("android.intent.category.LAUNCHER");
    intent.setAction("android.intent.action.MAIN");
    if (str1.contains("DialtactsContactsEntryActivity")) {
    str2 = "com.android.contacts.DialtactsContactsEntryActivity";
    } else if (str1.contains("DialtactsActivity")) {
    str2 = "com.android.contacts.DialtactsActivity";
    }
    intent.setComponent(new ComponentName(str3, str2));
    MyApplication.intent = intent;
    } else {
    MyApplication.intent = am.getRecentTasks(1, 0).get(0).baseIntent;//设置密码验证后需要启动应用的intent
    }

    Intent lockIntent = new Intent(ProtectorService.this, PasswordLockActivity.class);
    lockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK).putExtra("pkg", str3)
    .putExtra("where", "service");
    startActivity(lockIntent);//启动密码验证界面
    System.out.println("----------finish------------>");
    }
    isPass = false;//标记设置为false
    } catch (Exception localException) {
    return;
    }
    }
    }
    });
      

  8.   

    Smart.App.Protector
    也是读取log的方式?
      

  9.   


    Smart.App.Protector应该不是,因为反编译的源码中没有看到读取log的代码,貌似是通过getRunningTask来监听应用程序的启动。我用过这种方法,虽然能监听到应用的启动,但是却不能阻止应用的启动,所以会造成启动的应用主界面先出现,然后才出现密码验证界面。另外,针对“地址薄”和“拨号”,他们在同一个apk,通过包名获取到的intent不能启动“地址薄”和“拨号”中的任一个,我通过读取log的方式,主要是为了解决这个问题,因为通过log我可以知道程序要启动的是那个tab页,从而自己new一个intent来启动应用。我不知道自己的问题是出在了哪里?求高手解决?
    在反编译的代码中,输入密码时的代码为  public void onClick(View paramView)
      {
        String str = "";
        switch (paramView.getId())
        {
        case 2131361831:
        case 2131361835:
        case 2131361839:
        default:
          label80: this.mPassEdit.append(str);
        case 2131361828:
        case 2131361829:
        case 2131361830:
        case 2131361832:
        case 2131361833:
        case 2131361834:
        case 2131361836:
        case 2131361837:
        case 2131361838:
        case 2131361841:
        case 2131361842:
        case 2131361840:
        }
        while (true)
        {
          return;
          str = "1";
          break label80:
          str = "2";
          break label80:
          str = "3";
          break label80:
          str = "4";
          break label80:
          str = "5";
          break label80:
          str = "6";
          break label80:
          str = "7";
          break label80:
          str = "8";
          break label80:
          str = "9";
          break label80:
          str = "0";
          break label80:
          this.mPassEdit.setText("");
          continue;
          goHome();
        }
      }
    感觉密码验证通过应该是调用的goHome()方法。
      private void goHome()
      {
        Intent localIntent1 = new Intent();
        localIntent1.setAction("android.intent.action.MAIN");
        localIntent1.addCategory("android.intent.category.HOME");
        localIntent1.addFlags(329252864);
    //这里的intent为什么没有指定是哪个activity呢?我这样写直接回到home界面的
        startActivity(localIntent1);
    //下边这些代码又是做什么用的呢?看不明白呀
        Intent localIntent2 = new Intent("android.intent.action.MAIN", null);
        localIntent2.addCategory("android.intent.category.HOME");
        if (getPackageManager().queryIntentActivities(localIntent2, 0).size() > 1);
        while (true)
        {
          return;
          finish();
        }
      }
      

  10.   

    看这里
    http://www.cnblogs.com/hangxin1940/archive/2011/09/29/2196001.html
      

  11.   

    这个必须用正则表达式匹配次才能快。
    我试过了,可以。但是我的需求是要求每一次用都弹出来,正则就不行了。
    因为同一个应用每一次使用过程中都会出现很多activity重复启动,这种方式只使用于一次性加密的情况,重复加密不太好,因为back健等不会导致activitymanager重新启动一个activity