안드로이드에서  MP3 파일의 id3tag 가  깨지는 이유를  찾아보았습니다.

http://www.androidpub.com/471907

framework의 버그네요.
froyo 도  그대로 버그가 있구요.


그래서  모토로이 확인해 보았더니,  깨지는 파일들 다 잘 나오네요. ㅡ.ㅡ


음  Open Source 라서 가져다  자기들은 고쳐쓰고, 
버그 리포팅은 하지 않나 보네요.

우리나라 대기업도 그렇겠지요. 



ID3Tag 깨지는 원인은   mediascanner 의  버그 인데요.


void MediaScannerClient::endFile()
{

    if (mLocaleEncoding != kEncodingNone) {
        int size = mNames->size();
        uint32_t encoding = kEncodingAll;

        // compute a bit mask containing all possible encodings
        for (int i = 0; i < mNames->size(); i++)
        {
            encoding &= possibleEncodings(mValues->getEntry(i));
        }
           
        // if the locale encoding matches, then assume we have a native encoding.
        if (encoding & mLocaleEncoding)
            convertValues(mLocaleEncoding);

        // finally, push all name/value pairs to the client
        for (int i = 0; i < mNames->size(); i++) {
            if (!handleStringTag(mNames->getEntry(i), mValues->getEntry(i)))
                break;
        }
    }
    // else addStringTag() has done all the work so we have nothing to do

    delete mNames;
    delete mValues;
    mNames = NULL;
    mValues = NULL;
}


위 소스가  버그가 있는 곳입니다.

MediaScanner  소스를 보면,  ID3tag를  파싱하면   UTF-8 이 아닌것들을   mNames가  mValues에  넣어 두었다가
endFile() 함수에서  locale 인코딩이 필요한지를 판별하여   인코딩을 하고 있답니다.

그런데,

        uint32_t encoding = kEncodingAll;

        // compute a bit mask containing all possible encodings
        for (int i = 0; i < mNames->size(); i++)
        {
            encoding &= possibleEncodings(mValues->getEntry(i));
        }

위 코드에서 보면,    우선  전부 인코딩이 가능한 상태로  encoding변수를 넣어두고,
StringArray 에 들어간 각  값들이  인코딩이 가능한 것인지 확인한 후,


인코딩이  가능한 경우라면,  

     if (encoding & mLocaleEncoding)
            convertValues(mLocaleEncoding);

이와 같이 전부 locale 인코딩을  한답니다.



이게 버그인데요.

예들 들어서,  ID3Tag 값중에서   Title 과 Artist는   한글이 있고,  Album 에는  영문만 있다거나 혹은 인코딩이 필요없는 값만 있다면,

첫번째  for 문을 돌면서,   encoding 값이  0로 바뀌게 되고,

그럼, 아래 if 문에서 locale 인코딩을 그냥 건너 뛰게 된답니다.




그러므로,   이 버그의 수정을 위해서는  possibleEncodings() 함수 호출을   mValues 의 각 값에 따라 개별적으로
비교하여   locale 인코딩을  진행하면,

깨지는 것 없이  잘 나오게 된답니다.


수고하세요!