天天看點

Android adb “push pull”中文支援解決方案

Android adb “push pull”中文支援解決方案

      在windows底下檔案(夾)命名所采用的是GBK編碼,而在Android中采用的UTF-8編碼,所有使用adb 的push和pull指令時就會導緻由于編碼方式的不同而産生的錯誤,解決這一問題就隻有對adb工具的源代碼進行修改,讓adb對檔案名的編碼進行相應的轉換。

      具體過程如下:使用ubuntu 12.04 下載下傳android的源代碼,具體過程參考網絡,ubuntu一定要使用64位機,因為最新的android源代碼隻能在64位機進行編譯。

      http://source.android.com/

      下載下傳源代碼可能需要比較長的時間,把機器挂在那,放一晚上基本就OK了。下載下傳好源代碼以後,就可以開始對adb的源碼進行相應的修改。

      adb的源碼所在的目錄是/system/core/adb

      pull和push指令進行檔案傳輸的主要的過程是位于file_sync_client.c這個檔案中,在檔案的開頭部分增加,

#ifdef USE_MINGW

    #include<windows.h>

#endif

頭檔案聲明,然後增加兩個GBK同UTF-8編碼互相轉換的函數

static int GBKToUTF8(char *lpGBKStr, char *lpUTF8Str, int nUTF8StrLen)

{

    wchar_t *lpUnicodeStr = NULL;

    int nRetLen = 0;

    if (!lpGBKStr) return 0;

    nRetLen = MultiByteToWideChar(CP_ACP, 0, (char *)lpGBKStr, -1, NULL, 0);

    lpUnicodeStr = (wchar_t *)malloc(sizeof(WCHAR) * (nRetLen + 1));

    nRetLen = MultiByteToWideChar(CP_ACP, 0, (char *)lpGBKStr, -1, lpUnicodeStr, nRetLen);

    if (!nRetLen) return 0;

    nRetLen = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, NULL, 0, NULL, 0);

    if (!lpUTF8Str)

    {

        if (lpUnicodeStr) free(lpUnicodeStr);

            return nRetLen;

    }

    if (nUTF8StrLen < nRetLen)

        if (lpUnicodeStr) free(lpUnicodeStr);  

            return 0;

    nRetLen = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, (char *)lpUTF8Str,nUTF8StrLen,                                       NULL, 0);

    if (lpUnicodeStr) free(lpUnicodeStr);

    return nRetLen;

}

static int UTF8ToGBK(char *lpGBKStr,char *lpUTF8Str, int nGBKStrLen)

    wchar_t *lpUnicodeStr=NULL;

    int nRetLen =0;

    if (!lpUTF8Str)return 0;

    nRetLen=MultiByteToWideChar(CP_UTF8,0,(char*)lpUTF8Str,-1,NULL,NULL);

    nRetLen = MultiByteToWideChar(CP_UTF8, 0, (char *)lpUTF8Str, -1, lpUnicodeStr, nRetLen);

    if (!nRetLen)return 0;

    nRetLen = WideCharToMultiByte(CP_UTF8, 0, lpUnicodeStr, -1, NULL, 0, NULL, NULL);

    if (!lpGBKStr)

    if (nGBKStrLen < nRetLen)

    nRetLen = WideCharToMultiByte(CP_ACP, 0, lpUnicodeStr, -1, (char *)lpGBKStr,nGBKStrLen,                                         NULL, NULL);

再添加了這兩個編碼的函數後,就需要修改copyinfo *mkcopyinfo這個函數,使這個函數增加對UTF8編碼的支援:

copyinfo *mkcopyinfo(const char *spath, const char *dpath,

                     const char *sname, const char *dname,int isdir)

    int slen = strlen(spath);

    int dlen = strlen(dpath);

    int snlen = strlen(sname);

    int dnlen = strlen(dname);

    int ssize = slen + snlen + 2;

    int dsize = dlen + dnlen + 2;

    copyinfo *ci = malloc(sizeof(copyinfo) + ssize + dsize);

    if(ci == 0) {

        fprintf(stderr,"out of memory\n");

        abort();

    ci->next = 0;

    ci->time = 0;

    ci->mode = 0;

    ci->size = 0;

    ci->flag = 0;

    ci->src = (const char*)(ci + 1);

    ci->dst = ci->src + ssize;

    snprintf((char*) ci->src, ssize, isdir ? "%s%s/" : "%s%s", spath, sname);

    snprintf((char*) ci->dst, dsize, isdir ? "%s%s/" : "%s%s", dpath, dname);

//    fprintf(stderr,"mkcopyinfo('%s','%s')\n", ci->src, ci->dst);

    return ci;

繼續修改函數:

local_build_list();讓該函數傳進去的參數的名稱為utf-8編碼

static int local_build_list(copyinfo **filelist,

                            const char *lpath, const char *rpath)

    DIR *d;

    struct dirent *de;

    struct stat st;

    copyinfo *dirlist = 0;

    copyinfo *ci, *next;

//    fprintf(stderr,"local_build_list('%s','%s')\n", lpath, rpath);

    d = opendir(lpath);

    if(d == 0) {

        fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno));

        return -1;

    while((de = readdir(d))) {

        char stat_path[PATH_MAX];

        char *name = de->d_name;

        if(name[0] == '.') {

            if(name[1] == 0) continue;

            if((name[1] == '.') && (name[2] == 0)) continue;

        }

char utf8name[260];

int name_len=GBKToUTF8(name,NULL,0);

name_len=GBKToUTF8(name,utf8name,name_len);

        if (strlen(lpath) + strlen(de->d_name) + 1 > sizeof(stat_path))

            continue;

        strcpy(stat_path, lpath);

        strcat(stat_path, de->d_name);

        stat(stat_path, &st);

        if (S_ISDIR(st.st_mode)) {

            ci = mkcopyinfo(lpath, rpath, name,name, 1);

   ci = mkcopyinfo(lpath,rpath,name,utf8name,1);

            ci->next = dirlist;

            dirlist = ci;

        } else {

            ci = mkcopyinfo(lpath, rpath, name, name,0);

   ci = mkcopyinfo(lpath,rpath,name,utf8name,0);

            if(lstat(ci->src, &st)) {

                fprintf(stderr,"cannot stat '%s': %s\n", ci->src, strerror(errno));

                closedir(d);

                return -1;

            }

            if(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) {

                fprintf(stderr, "skipping special file '%s'\n", ci->src);

                free(ci);

            } else {

                ci->time = st.st_mtime;

                ci->mode = st.st_mode;

                ci->size = st.st_size;

                ci->next = *filelist;

                *filelist = ci;

    closedir(d);

    for(ci = dirlist; ci != 0; ci = next) {

        next = ci->next;

        local_build_list(filelist, ci->src, ci->dst);

        free(ci);

    return 0;

以及相應的一些有關于名稱編碼的函數,現将修改好的c檔案以及編譯好的adb檔案的下載下傳連結提供如下

提供的下載下傳位址為:

<a href="http://download.csdn.net/detail/shuaihj/5353463">http://download.csdn.net/detail/shuaihj/5353463</a>

繼續閱讀