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>