2

base64にあるWebサービスからビットマップに画像をデコードし、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

問題は、ブラウザからコードをコピーしてプログラムにハードコードすると、すべてが正常に機能することです。しかし、Androidプログラムを介してbase64データを取得し、base64をハードコーディングしようとすると、例外が発生します。ブラウザにあるコードとAndroid経由で取得したコードは同じように見えます。しかし、実際には、結果が異なるためではありません)

4

3 に答える 3

7

実際には、これに対する簡単な解決策があり、有効な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
于 2013-02-25T19:01:12.280 に答える
2

Base64コードのパディングが適切ではないようです(コードの最後に間違った数の末尾の=記号があります)。たとえば、に対応するbase64コードはです。最後Helloは、base64データチャンクのサイズをBase64RFCに準拠させるためのものです。したがって、チャンクの長さがbase64仕様に準拠していないため、どちらも正しくありません。どちらも、関連する文字( "Base 64アルファベット")に固執することを意味します。SGVsbG8==SGVsbG8==SGVsbG8Hello

いくつかの実装はそれについてかなり寛容です。彼らは、間違った長さのbase64チャンクには、1つまたは2つの「=」のパディングが必要であると想定しています。Androidを含む他のいくつかは許容されないので、PHPとAndroidプログラムの動作の間で直面している種類の不一致。

デコードしようとしているbase64データが表示されないため、これは単なる仮定です。これを確認するには、このオンラインbase64デコーダーを使用して、パディングに問題がないかどうかを確認できます。

とにかく、base64コードのサンプルを使用すると簡単になります。それを投稿に追加しますか?それに応じて回答を更新します。

于 2012-08-09T14:50:40.137 に答える
1

問題は、画像のbase64文字列の最後に「n」文字をJSON応答に追加することでした。その出現の理由は神秘的です。そのWebサービスからの他のJSON応答が「n」文字なしで来るのは興味深いことです。「n」文字を使用せずに、通常のJavaコード(すべてが良好)でbase64イメージの文字列を取得しようとしました。だからそれはアンドロイドクライアント側による外観です。その出現の理由とそれを防ぐ方法を調査してみてください。彼の多大な助けをくれたShlubluに感謝します!!!

于 2012-08-14T07:57:07.247 に答える