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);
    lpUnicodeStr = (wchar_t *)malloc(sizeof(WCHAR) * (nRetLen + 1));
    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 (lpUnicodeStr) free(lpUnicodeStr);
            return nRetLen;
    }

    if (nGBKStrLen < nRetLen)
    {
        if (lpUnicodeStr) free(lpUnicodeStr);
            return 0;
    }

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

    if (lpUnicodeStr) free(lpUnicodeStr);

    return nRetLen;
}

再添加了这两个编码的函数后,就需要修改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;
        }

#ifdef USE_MINGW
char utf8name[260];
int name_len=GBKToUTF8(name,NULL,0);
name_len=GBKToUTF8(name,utf8name,name_len);
#endif
       
        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);
#ifdef USE_MINGW
   ci = mkcopyinfo(lpath,rpath,name,utf8name,1);
#endif
            ci->next = dirlist;
            dirlist = ci;
        } else {
            ci = mkcopyinfo(lpath, rpath, name, name,0);
#ifdef USE_MINGW
   ci = mkcopyinfo(lpath,rpath,name,utf8name,0);
#endif
            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文件的下载链接提供如下
提供的下载地址为:
http://download.csdn.net/detail/shuaihj/5353463

时间: 2024-10-02 06:53:06

Android adb “push pull”中文支持解决方案的相关文章

android adb push 与 adb install的比较

Android 应用程序有两种安装方法: 1. 将应用程序的apk文件push到手机中,用如下命令:    adb push xxxx.apk /system/app. 2. 用adb install xxxx.apk进行安装   二者的比较以及注意事项:   1) 用第一种方式的弊端:          a.   会将原来系统中的对应的apk覆盖掉,所以,最好先备份出来一份,用如下命令:                adb pull /system/app/xxxx.apk    /home

android-Android: adb.exe pull /mnt/sdcard/somefile.txt 不能运行

问题描述 Android: adb.exe pull /mnt/sdcard/somefile.txt 不能运行 我想使用adb command 从设备中获取一个文件: adb pull /mnt/sdcard/deviceinfo.dat C: 但是总获得下面的信息: cannot create 'c:\deviceinfo.dat': No such file or directory 文件存在于设备中: adb shell ls /mnt/sdcard/deviceinfo.dat 返回

如何使ADB在Linux下支持Android设备的udev规则配置

1.Connect Andriod device to your Linux ***. 2.Use "lsusb". Use lsusb to check the Android device ID in usb subsystem, like below (do not care "$"):   $ lsusb   Bus 001 Device 002: ID 0fce:6156 Sony Ericsson Mobile Number "0fce&quo

Android ADB开发常用命令总结

本文讲的是Android ADB开发常用命令总结,如果指定ip 连接,一般为 adb conenct 172.18.xxx.xxx ,这样每次进行连接时,发现都有重复的的命令需要敲,程序员就是要减少重复工作,所以现在就将重复的命令省掉.(以下为mac下的配置的方法): 新建.alias_bash 文件 文件中使用 alias 别名关键字重新命令 alias ac="adb connect $1"   alias ad="adb devices"   alias ak

Android ADB详细介绍及用法_Android

Android ADB 用法 adb  全称是 Android Debug Bridge, 就是起到调试桥的作用. 用来操作android设备的 阅读目录 adb 有什么用 adb 下载 adb devices adb install  (安装软件) adb uninstall (卸载软件) adb shell (登录shell) adb push (从电脑上发送文件到设备) adb pull (下载文件到电脑) adb help (显示帮助信息) adb 有什么用 借助adb工具, 我们可以管

Android ADB linux命令集合

A.用adb局域网功能连接设备      1,先用usb连接运行adb命令,将连接方式改为tcpip           adb tcpip {port}     port为端口号      2,拔掉usb线,运行adb命令连接设备           adb connect xxx.xxx.xxx.xxx(设备ip):port(刚才设置的端口号)      3,正常运行adb命令   adb的工作方式比较特殊采用监听Socket TCP 5554等端口的方式让IDE和Qemu通讯,默认情况下a

android adb常用指令

Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态. 可以通过下列几种方法加入adb: 在设备上运行shell命令 通过端口转发来管理模拟器或设备 从模拟器或设备上拷贝来或拷贝走文件 下面对adb进行了介绍并描述了常见的使用. Contents 概要 发出adb命令 查询模拟器/设备实例 给特定的模拟器/设备实例发送命令 安装软件 转发端口 从模拟器/设备中拷入或拷出文件 Adb命令列表 启动shell命令 通过远程shell端运行sqllite3连接数

Android ADB详细介绍及用法

Android ADB 用法 adb  全称是 Android Debug Bridge, 就是起到调试桥的作用. 用来操作android设备的 阅读目录 adb 有什么用 adb 下载 adb devices adb install  (安装软件) adb uninstall (卸载软件) adb shell (登录shell) adb push (从电脑上发送文件到设备) adb pull (下载文件到电脑) adb help (显示帮助信息) adb 有什么用 借助adb工具, 我们可以管

android adb实用命令小结

adb对于Android程序员来说在日常的工作中使用频率很高,现将自己工作中常用的adb命令总结一下备忘,方便查询,也供大家参考.查看应用内存占用,耗电信息,启动时间,wakelock,跑monkey的命令在之前的应用性能优化中起了不小的作用.以下adb命令的测试机器为小米3,其中package_name代表包名. 基础脚本: 1.启动adb服务 adb start-server 2.终止adb服务 adb kill-server 3.进入adb运行环境 adb shell 4.获取帮助 里面有