我目前做的一个应用为了保护用户隐私,不允许在setting中将service停掉,也不允许通过第三方应用将应用kill掉,如果说service被停掉,或是应用被kill掉,则立即重启service,请问有什么方法或是思路实现么?ps:如果在杀掉应用 或是停掉service的时候,能截获到这个操作么?

解决方案 »

  1.   

    你可以在frameworks\base\services\java\com\android\server\am\ActivityManagerService.java这个类的forceStopPackage中加一个条件
    public void forceStopPackage(final String packageName) {
            if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
                    != PackageManager.PERMISSION_GRANTED) {
                String msg = "Permission Denial: forceStopPackage() from pid="
                        + Binder.getCallingPid()
                        + ", uid=" + Binder.getCallingUid()
                        + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
                Slog.w(TAG, msg);
                throw new SecurityException(msg);
            }
            
            long callingId = Binder.clearCallingIdentity();
            try {
                IPackageManager pm = ActivityThread.getPackageManager();
                int pkgUid = -1;
                synchronized(this) {
                    try {
                        pkgUid = pm.getPackageUid(packageName);
                    } catch (RemoteException e) {
                    }
                    if (pkgUid == -1) {
                        Slog.w(TAG, "Invalid packageName: " + packageName);
                        return;
                    }
                    //begin:加入一个判断条件
                    if (packageName.equals("你的进程名")) {
                     return;
                    }
                    //end: 加入一个判断条件                                forceStopPackageLocked(packageName, pkgUid);
                }
            } finally {
                Binder.restoreCallingIdentity(callingId);
            }
        }
                    };这样的话在任务管理器里可以保证KISS不掉的;
    还有在这个方法上还有个方法clearApplicationUserData中保证如果是该进程就不让调用forceStopPackage()方法;
      

  2.   


    如果修改framework的话,的确可以通过对包名的过滤来实现。居于应用层开发,有什么实现方法或是思路么?
    比如在kill的时候,会不会触发某一个广播?
      

  3.   

    明确的说,不改framework不可能完美实现。
      

  4.   


    这个貌似必须改framework层,如果在应用层进行处理的话,除非单独起一个线程,不停的检测该service的运行状况,如果被kill掉了就另起一个。
    这个需求最蛋疼的地方在于如果从DDMS里面直接kill掉这个service的话是不会触发service对应停止事件的。
      

  5.   


    虽然不是很完美,但从应用层的角度,这个问题总算解决了。
    碰到这么蛋疼的问题,解决方案也真够蛋疼的,谁有什么好的解决方案,欢迎交流,如果目前的解决方案中有什么问题,欢迎批评指正哈。2.1版本
    对于Taskkiller等第三方应用,在kill应用的时候,通过<action android:name="android.intent.action.PACKAGE_RESTARTED">捕捉广播,如果是自己的应用被kill掉,则重启service。
    对于settings对运行的service进行stop操作,会触发onDestroy方法,在这里进行service的重启2.3.3版本
    对于Taskkiller等第三方应用,在kill应用的时候,service居然TMD自己会重启(真TM蛋疼,反编译的代码,研究了老久也TMD没找到是怎么回事,最后还是通过版本对比才得出的结论)
    对于settings当然还是采用以上方案啦
      

  6.   

    楼主,我实践过了,现在告诉你,100%可以做到不被kill的,做法如下:1,首先在你的service的onDestory方法里面写上启动你自己的代码,为什么要写这个?因为如果用户是在设置->应用程序->正在运行服务这里面杀掉你service的话会调用到onDestory方法的,这里就可以启动了,2:监听屏幕关闭广播,屏幕已关闭,就启动服务。3:监听屏幕解锁广播,一样的道理,这样,基本上,你的service就达到永不停止了。对用户来说有点变态,但很多软件都这样。
      

  7.   

    娘的 手机里的搜狐新闻就是这样 关掉又自动重启 搞得我火了把rom刷了
      

  8.   


    我之所以说不可能完美,是因为android系统的low memory killer 会“误杀” 应用层的一切为重启service作出的努力的。但是几率不是100% .
      

  9.   

    很简单的方法,你用一个alarmmanager嘛,定时发送广播,在广播里面调用启动service的代码,即使service存在了,也只是走一遍onstart,不会产生多个实例的
      

  10.   

    版主乃真高手也!为了避免自己的软件被杀,我提高了service的优先级,这样除非在极特殊情况下(memory极低)能杀掉外,应该是不会被杀掉的!而且那些个所谓的任务管理软件,是干不掉了,直接提示失败。
      

  11.   


    你这个貌似不行吧???
    屏幕的关闭/解锁  和 杀掉app/service有关系么?
      

  12.   

    http://topic.csdn.net/u/20111202/11/847ff783-0c8d-4097-813d-ec71d7eb6e2e.html
      

  13.   

     在onDestroy 里面重启  骷髅王的大有没有!带了复活盾有木有!
      

  14.   

    监听这个<action android:name="android.intent.action.PACKAGE_RESTARTED"> 真的可以吗?
    为啥我一直监听不到呢,文档上说:Note that the restarted package does not receive this broadcast.
    被重启的包不能监听自己是否重启吧
      

  15.   


    ...参考PC中的进程互锁, 两个service相互监控, 这个关了那个开.
      

  16.   

    被kill的应用不能监听到自己被kill,但可以监听到其它应用
      

  17.   


    你如果要该framework的话,至少需要从restartPackage和forceStopPackage两个方法分析,因为不同的操作,调用的是不同的入口。