android下如何限制安装APP的数量


转载请注明文章出处和作者!

出处:http://blog.csdn.net/xl19862005

作者:大熊(Xandy)


由于项目的要求,需要限制用户安装APP的数量,对android app安装流程了解的都知道,核心的东西都在installd这个服务里面,我这里所做的处理也在这里面。

installd的源码位于frameworks/native/cmds/installd(android5.1),这个服务随init启来之后,通过socket和上层进行数据交互,在installd里面能处理的命令集如下(android版本不同,这些命令略有差异):

struct cmdinfo cmds[] = {
    { "ping",                 0, do_ping },
    { "install",              4, do_install },
    { "dexopt",               6, do_dexopt },
    { "markbootcomplete",     1, do_mark_boot_complete },
    { "movedex",              3, do_move_dex },
    { "rmdex",                2, do_rm_dex },
    { "remove",               2, do_remove },
    { "rename",               2, do_rename },
    { "fixuid",               3, do_fixuid },
    { "freecache",            1, do_free_cache },
    { "rmcache",              2, do_rm_cache },
    { "rmcodecache",          2, do_rm_code_cache },
    { "getsize",              7, do_get_size },
    { "rmuserdata",           2, do_rm_user_data },
    { "movefiles",            0, do_movefiles },
    { "linklib",              3, do_linklib },
    { "mkuserdata",           4, do_mk_user_data },
    { "mkuserconfig",         1, do_mk_user_config },
    { "rmuser",               1, do_rm_user },
    { "idmap",                3, do_idmap },
    { "restorecondata",       3, do_restorecon_data },
    { "patchoat",             5, do_patchoat },
};
对app限制安装只看install这个命令的处理函数,在frameworks/native/cmds/installd/commands.c这个文件中的install函数这里,我增加了如下处理代码:

int install(const char *pkgname, uid_t uid, gid_t gid, const char *seinfo)

{
………………

/****************************Xandy add for app install control***************************/

if(app_install_cnt_ctrl() < 0)

return -1;

………………

}

相关实现代码如下:

#define APP_CNT_PATH "/data/misc/installctrl/cnt"
static int app_cnt = 0;

/********从文件读取用户安装APP的数量*******/
static int get_user_install_app_cnt(void)
{
      int fd;
      char buf[10];
   
      fd = open(APP_CNT_PATH, O_RDONLY | O_NONBLOCK);
      
      if(fd < 0)
      {
             ALOGE("File:%S doesn't exist", AP_CNT_PATH);
             return 0;
      }

      if(read(fd, buf, 10) < 0)
      {
             ALOGE("Read file:%s error",APP_CNT_PATH);
            return 0;
      }

      close(fd);
      return atoi(buf);
}

/***********保存用户安装APP的数量*************/
static void save_user_install_app_cnt(void)
{
      FILE* fp = NULL;
      int fd;
      char buf[10];

      app_cnt++;//a new app install
      sprintf(buf, "%d", app_cnt);
      
      if(acces(APP_CNT_PATH, F_OK) != 0)
      {
             fp = fopen(APP_CNT_PATH, "w+");
             fputs(buf, fp);
             fclose(fp);
             fp = NULL;
       }
       else 
       {
              fd = open(APP_CNT_PATH, O_RDWR);
              if(fd >= 0)
              {
                     write(fd, buf, 10);
                     close(fd);
              }   
       }
}

/*********获取开机完成状态*********/
static int boot_animation_finish(void)
{
      char value[PROPERTY_VALUE_MAX];

      property_get("service.bootanim.exit",value, "1");
       
       return atoi(value);
}

//************************************
static int app_install_cnt_ctrl(void)
{
      char value[PROPERTY_VALUE_MAX];
      int ctrl_cnt;

      if(boot_animation_finish() == 1)
      {
             property_get("ro.ctrl.app_install_cnt", value, "0");//用户可安装的APP数量,通过ro.ctrl.app_install_cnt这个prop获取
             ctrl_cnt = atoi(value);
             app_cnt = get_user_install_app_cnt();
             if(app_cnt < ctrl_cnt)
             {
                    save_user_install_app_cnt();
                    return 0;
              }  
              else
                     return -1; 
       }
        
        return 0;
}

实现原理:

  将每次用户安装的APP数目记录到文件,当安装的数目达到由ro.ctrl.app_install_cnt这个prop设置的上限值时,直接退出install处理流程。

  上面的代码我是留了一个小后门的(在某种情况下可以安装APP,这也是方法以后自己调试的方便),仔细的你肯定能发现,这里就不直说了哈,有需要的小伙伴自己慢慢琢磨……




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章