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,這也是方法以後自己調試的方便),仔細的你肯定能發現,這裏就不直說了哈,有需要的小夥伴自己慢慢琢磨……




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