Android adb “push pull”中文支持解决方案

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
简介: Android adb “push pull”中文支持解决方案      在windows底下文件(夹)命名所采用的是GBK编码,而在Android中采用的UTF-8编码,所有使用adb 的push和pull命令时就会导致由于编码方式的不同而产生的错误,解决这一问题就只有对adb工具的源代码进行修改,让adb对文件名的编码进行相应的转换。

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

相关实践学习
阿里云百炼xAnalyticDB PostgreSQL构建AIGC应用
通过该实验体验在阿里云百炼中构建企业专属知识库构建及应用全流程。同时体验使用ADB-PG向量检索引擎提供专属安全存储,保障企业数据隐私安全。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
相关文章
|
2月前
|
Shell Linux 开发工具
"开发者的救星:揭秘如何用adb神器征服Android设备,开启高效调试之旅!"
【8月更文挑战第20天】Android Debug Bridge (adb) 是 Android 开发者必备工具,用于实现计算机与 Android 设备间通讯,执行调试及命令操作。adb 提供了丰富的命令行接口,覆盖从基础设备管理到复杂系统操作的需求。本文详细介绍 adb 的安装配置流程,并列举实用命令示例,包括设备连接管理、应用安装调试、文件系统访问等基础功能,以及端口转发、日志查看等高级技巧。此外,还提供了常见问题的故障排除指南,帮助开发者快速解决问题。掌握 adb 将极大提升 Android 开发效率,助力项目顺利推进。
65 0
|
2月前
|
Android开发
【Azure 环境】记录使用Notification Hub,安卓手机收不到Push通知时的错误,Error_Code 30602 or 30608
【Azure 环境】记录使用Notification Hub,安卓手机收不到Push通知时的错误,Error_Code 30602 or 30608
|
5月前
|
Shell Android开发
ADB更改Android设备屏幕显示方向
ADB更改Android设备屏幕显示方向
310 5
|
4月前
|
Shell 开发工具 Android开发
|
19天前
|
XML 存储 Java
探索安卓开发之旅:从基础到进阶
【9月更文挑战第37天】安卓开发,一个充满无限可能的领域。它不仅关乎技术的深度与广度,更关乎开发者的成长与突破。本文将带你走进安卓开发的世界,从基础知识的学习到进阶技巧的掌握,一起感受编程的魅力与乐趣。
|
13天前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的海洋中,自定义控件是那片璀璨的星辰。它不仅让应用界面设计变得丰富多彩,还提升了用户体验。本文将带你探索自定义控件的核心概念、实现过程以及优化技巧,让你的应用在众多竞争者中脱颖而出。
|
13天前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
54 1
|
16天前
|
Android开发
Android开发表情emoji功能开发
本文介绍了一种在Android应用中实现emoji表情功能的方法,通过将图片与表情字符对应,实现在`TextView`中的正常显示。示例代码展示了如何使用自定义适配器加载emoji表情,并在编辑框中输入或删除表情。项目包含完整的源码结构,可作为开发参考。视频演示和源码详情见文章内链接。
41 4
Android开发表情emoji功能开发
|
14天前
|
Web App开发 安全 程序员
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
多年的互联网寒冬在今年尤为凛冽,坚守安卓开发愈发不易。面对是否转行或学习新技术的迷茫,安卓程序员可从三个方向进阶:1)钻研谷歌新技术,如Kotlin、Flutter、Jetpack等;2)拓展新功能应用,掌握Socket、OpenGL、WebRTC等专业领域技能;3)结合其他行业,如汽车、游戏、安全等,拓宽职业道路。这三个方向各有学习难度和保饭碗指数,助你在安卓开发领域持续成长。
42 1
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
|
12天前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件基础与进阶
【10月更文挑战第5天】在Android应用开发中,自定义控件是提升用户体验和界面个性化的重要手段。本文将通过浅显易懂的语言和实例,引导你了解自定义控件的基本概念、创建流程以及高级应用技巧,帮助你在开发过程中更好地掌握自定义控件的使用和优化。
25 10