IllegalArgumentException Base64 для декодирования изображений Android

Я хочу декодировать изображение из веб-сервиса в base64 в растровое изображение и использовать его в своем приложении для Android. Это мой метод:

public Bitmap getCaptcha() throws IOException
    { 

        List<NameValuePair> params = new ArrayList<NameValuePair>();
        String json = jsonParser.getCaptcha(captchaURL, params);
        Log.i("", json);

         byte [] encodeByte=Base64.decode(json.getBytes(),Base64.DEFAULT);
         Bitmap bitmap=BitmapFactory.decodeByteArray(encodeByte, 0, encodeByte.length);
         return bitmap;

    }

Если я декодирую строку, которую я получаю из метода getCaptcha с помощью моего php-скрипта, она отображается правильно. Но когда я делаю это в своем приложении, я получаю

 FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.assignmentexpert/com.assignmentexpert.RegisterActivity}: java.lang.IllegalArgumentException: bad base-64
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:3687)
   at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
    at dalvik.system.NativeStart.main(Native Method)
   Caused by: java.lang.IllegalArgumentException: bad base-64
    at android.util.Base64.decode(Base64.java:161)
    at android.util.Base64.decode(Base64.java:136)
    at com.library.UserFunctions.getCaptcha(UserFunctions.java:97)
    at com.assignmentexpert.RegisterActivity.onCreate(RegisterActivity.java:66)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
    ... 11 more

В чем причина этого?

Я добавляю код base64, который получаю:

/9j/4AAQSkZJRgABAQAAAQABAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2NjIpLCBxdWFsaXR5ID0gMTUK/9sAQwA1JSgvKCE1LysvPDk1P1CFV1BJSVCjdXthhcGqy8i+qrq31fD//9Xi/+a3uv///////////87//////////////9sAQwE5PDxQRlCdV1ed/9y63P///////////////////////////////////////////////////////////////////8AAEQgAKAB4AwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A0mOBkUtI/T8R/OgjPcj6UADOF6nn0qjd3jqdkfynuamnfYRFCMyt39BVS8RYI0jHLH5mPrTSAmtJJHjJZyTnvVpSyjoGHqKhsRtts5wSan4bkA59qTDQY9yquqbW3N0BGKJJjEhd1+UehqnJl5VmJJHmBB9K0Nif3R+VFgsQC/hPcj6inrdRv93mla3ibqo/CqF7bpBtZCRntTCxo7nPRMfU1FPL5SFmfJ7KKisCZIzvyQOmaNQ4aEdF3f4UrBYWO6lVlFwm0N0PpVyorlQ9tID/AHSaLZ99ujHk45oAlooooAR/u/TmmTyiGMseT0A9TT3+430qO4hWZAG6A54oAii2wjdKw81+SSRxVG8ZXnJUgjHUHNX1sogP9WCfUk1UvoREylVABHamhlm0liESqWXdT7yXy4vlPztwKgtYYWiV2Q7s9RU1xA85R0YKV6ZFLqIhnTyraFSOjjn86vKyuMqQR7VnzwzfuxNLu3OBgVacx28XyjhewPNDAZJFchmaKbIJztPaqbcSf6VvzWjHOkg+Vwahvnj8kqcbu1NMCa3eJo8RYwO1Nu4PPjwDhgciqenBvNJGcYrQkkESF26Ck9GBTZ7oxGJo+oxv9qnsf+PRPx/nTJ72PyWCHLEYAqa2Qx26KeuOaYEtFFFIAIyCD0NJjLD0FFFAC0yVUcAOob0BoooAI4ljGFAFOKgnPf2oooAY0KuylsnacjJp5UEYIGKKKAIHs4X527T7UwafEDyWNFFFwLMcaRLtQYFKyhhhgCPQ0UUAMFvEGyI1z9KkwKKKACiiigD/2Q==n

Проблема в том, что когда я копирую код из браузера и жестко вставляю его в свою программу - все работает нормально. Но когда я получаю данные base64 через свою программу для Android и пытаюсь жестко закодировать base64, я получаю исключение. Код, который находится в браузере, и тот, что я получаю через Android, выглядит одинаково. Но, практически, не из-за другого результата)


person Rikki Tikki Tavi    schedule 09.08.2012    source источник


Ответы (3)


Похоже, что заполнение вашего кода Base64 не очень хорошее (неправильное количество завершающих знаков = в конце вашего кода). Например, код base64, соответствующий Hello, равен SGVsbG8=, а последний = нужен только для того, чтобы размер фрагмента данных base64 соответствовал RFC Base64. Таким образом, SGVsbG8== и SGVsbG8 оба неверны, поскольку длина фрагмента не соответствует спецификации base64, хотя они оба означают Hello, если мы придерживаемся соответствующих символов («Алфавит Base 64»).

Некоторые реализации довольно снисходительны к этому. Они просто предполагают, что фрагмент base64 неправильной длины нуждается в дополнении одним или двумя "=". Некоторые другие, включая Android, не являются разрешающими, поэтому вы сталкиваетесь с несоответствием между поведением ваших программ PHP и Android.

Это только предположение, так как я не вижу данных base64, которые вы пытаетесь декодировать. Чтобы проверить это, вы можете использовать этот онлайн-декодер base64, который сообщит вам, прокладка в порядке.

В любом случае было бы проще с образцом вашего кода base64. Вы бы добавили это в свой пост? Я обновлю свой ответ соответственно.

person Shlublu    schedule 09.08.2012
comment
В конце вашего кода есть n после завершающего =. Это делает фрагмент данных base64 недействительным. После удаления все остальное в силе, я смог расшифровать его без проблем. Возможно, проблема связана с вашим сервисом. Кажется, что символ завершения строки \n был ошибочно введен с ошибкой n в сервисном коде. - person Shlublu; 09.08.2012
comment
ЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕЕ за!!! спасибо большое!!!!!!как вы могли это определить??? Интересно - в чем причина этого? веб-служба правильно отправляет данные - потому что они правильно отображаются в браузере ... почему это не работает на стороне моего клиента? Я отправляю запрос и должен получить те же данные... но это не... очень странно... большое спасибо... - person Rikki Tikki Tavi; 09.08.2012
comment
Добро пожаловать :) Возможно, ошибка в вашем Android-клиенте, который пытается добавить \n к данным, которые он читает. В любом случае, я только догадываюсь, но дайте мне знать :) - person Shlublu; 09.08.2012
comment
проблема не в \n, а только в n... Клиент добавляет n в качестве последнего символа... исключение его из строковых данных из веб-сервиса решило проблему. Спасибо. - person Rikki Tikki Tavi; 09.08.2012
comment
Хороший! Тогда, я думаю, мы можем закрыть этот вопрос. - person Shlublu; 09.08.2012

На самом деле есть простое решение, которое удалит любые неверные данные после действительной строки base64:

String[] safe = received.split("=");
//put all chars before first base64 '=' padding char into safe[0]

try {
     byte[] recvpicbyte = Base64.decode(safe[0], Base64.NO_PADDING);
     //decode safe [0], note not in 'DEFUALT', use 'NO_PADDING' so it wont expect the '='

     //...do whatever with output
person RoninSeito    schedule 25.02.2013

Проблема заключалась в добавлении к ответу JSON символа «n» в конце строки base64 изображения. Причина его появления мистическая. Интересно, что другой ответ JSON от этого веб-сервиса приходит без символа «n». Я попытался получить эту строку изображения base64 с помощью обычного кода Java - все было хорошо - без символа "n". Так что это связано с Android-клиентом. Постарайтесь выяснить причину его появления и способы предотвращения. Спасибо Shlublu за огромную помощь!!!

person Rikki Tikki Tavi    schedule 14.08.2012