0

私は、AndroidクライアントでREST APIからファイルの添付ファイルをダウンロードする例を見つけようとして、Webを精査してきました。これは、SpringforAndroidを通じて提供される残りのテンプレートを使用しています。

役に立つものは何も見つかりませんでした。サーバーは、image/jpegまたはimage/pngのいずれかのコンテンツタイプを持つエンティティを返します。返されるヘッダーには、次のようなコンテンツ処理ヘッダーが含まれます。

コンテンツ-処分:添付ファイル; filename = examplename

ファイル拡張子はクライアント側でネゴシエートし、Androidが画像を管理する方法に従って処理するため、使用しません。これがSpringforAndroidフレームワークで可能かどうか、または独自に構築する必要があるかどうかを理解しようとしていると思います。

4

1 に答える 1

0

Spring を使い始める前に、自分で Web イメージ ローダーを実装していました。画像や認証 (後者は追加可能) に Spring が必要ないと仮定すると、私が使用する次のクラスに似たものが機能するはずです。SimpleBitmapCacheクラスは LruCache (サポート パッケージで利用可能) の単なるラッパーであり、キャッチして処理するためgetBitmapSafelyのラッパーであることに注意してください(特定のポイントまで再帰的に増加し、最終的にはあきらめます)。BitmapFactory.decodeStream()OutOfMemoryErrorinSampleSize

import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;

@Singleton
public class WebImageLoader {
    private static final String TAG = WebImageLoader.class.getSimpleName();
    protected SimpleBitmapCache simpleBitmapCache;
    protected Pattern cachedImagePattern;

    @Inject
    public WebImageLoader(SimpleBitmapCache simpleBitmapCache) {
        this.simpleBitmapCache = simpleBitmapCache;
    }

    public void fetchImageForImageView(ImageView imageView, URL url,
                                       int maxWidth, int maxHeight, ImageView.ScaleType scaleType) {
        // Sanity check: Does the request make sense?
        if (imageView == null)
            Log.w(TAG, "imageView doesn't exist!", new Exception());
        if (url == null)
            Log.w(TAG, "No URL to load!", new Exception());
        if (imageView == null || url == null)
            return;

        // Set a tag so the downloader will set the image automatically, and so that only the correct picture is shown.
        imageView.setTag(url);
        // We only need to start the Downloader if the Bitmap isn't cached
        if (!isBitmapCached(url)) {
            new Downloader(imageView, url, scaleType).execute();
        } else {
            imageView.setScaleType(scaleType);
            imageView.setImageBitmap(getBitmapFromCache(url));
        }
    }

    public void clearCache() {
        simpleBitmapCache.clear();
    }

    private boolean isBitmapCached(URL url) {
        return (simpleBitmapCache != null) && (simpleBitmapCache.contains(url));
    }

    private Bitmap getBitmapFromCache(URL url) {
        return (Bitmap) simpleBitmapCache.get(url);
    }

    private void setBitmapIntoCache(Bitmap bitmap, URL url) {
        if (simpleBitmapCache != null) {
            simpleBitmapCache.put(url, bitmap);
        }
    }

    private class Downloader extends AsyncTask<Void, Void, Bitmap> {
        protected final static int DEFAULT_ATTEMPTS = 3;
        protected final static long SLEEP_TIME = 3000;
        private final static String TAG = Downloader.class.getSimpleName();
        protected WeakReference<ImageView> imageViewRef;
        protected ImageView.ScaleType finalScaleType;
        protected URL url;

        public Downloader(final ImageView imageView, URL url, ImageView.ScaleType scaleType) {
            this.imageViewRef = new WeakReference<ImageView>(imageView);
            this.url = url;
            if (scaleType == null)
                this.finalScaleType = ImageView.ScaleType.FIT_CENTER;
            else
                this.finalScaleType = scaleType;

            // Set a download animation
            imageView.setScaleType(ImageView.ScaleType.CENTER);
            imageView.setImageResource(android.R.drawable.stat_sys_download);
            AnimationDrawable animation = (AnimationDrawable)imageView.getDrawable();
            imageView.post(animation);
        }

        @Override
        protected Bitmap doInBackground(Void... params) {
            return downloadBitmap(url);
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            // Update the cache
            setBitmapIntoCache(bitmap, url);

            ImageView imageView = imageViewRef.get();

            if (imageView != null) {
                // Let's verify if that ImageView wasn't recycled
                if (imageView.getTag() != null && imageView.getTag().equals(url)) {
                    imageView.setScaleType(finalScaleType);
                    imageView.setImageBitmap(bitmap);
                    imageView.setTag(null); // because it WILL be recycled later
                }
            }
        }

        protected Bitmap downloadBitmap(URL url) {
            return downloadBitmap(url, DEFAULT_ATTEMPTS);
        }
        protected Bitmap downloadBitmap(URL url, int attemptsLeft) {
            Bitmap bitmap = null;
            InputStream is = null;
            HttpURLConnection connection = null;
            int responseCode = -1;
            attemptsLeft--;

            //Log.v(TAG, "Downloading "+url);
            try {
                connection = (HttpURLConnection) url.openConnection();
            } catch (IOException e) {
                Log.e(TAG, "Failed to open HttpConnection for "+url.getPath(), e);
            }

            if (connection != null) {
                try {
                    responseCode = connection.getResponseCode();
                } catch (IOException e) {
                    Log.e(TAG, "Failed to get response code for "+connection.getURL(), e);
                }

                if (200 == responseCode) {
                    try {
                        is = connection.getInputStream();
                    } catch (IOException e) {
                        Log.e(TAG, "Failed to open InputStream for "+connection.getURL(), e);
                    }

                    // Finally create the bitmap from the InputStream
                    if (is != null) {
                        try {
                            bitmap = ImageUtil.getBitmapSafely(is, 1);
                        } catch (ImageUtil.BitmapTooLargeException e) {
                            Log.e(TAG, "Giving up on decoding "+connection.getURL());
                        }
                    }
                } else if (responseCode != -1) {
                    if (responseCode == 404)
                        Log.d(TAG, "Image not found: "+url.toString());
                    else
                        Log.e(TAG, "Unexpected response code "+responseCode+" for "+connection.getURL());
                }
            }

            if (bitmap == null && responseCode == -1 && attemptsLeft > 0) {
                try {
                    Thread.sleep(SLEEP_TIME);
                } catch (InterruptedException e) {
                    Log.w(TAG, "Download interrupted: "+url.getPath(), e);
                    return bitmap;
                }
                Log.d(TAG, "Retrying download of "+url.getPath());
                return downloadBitmap(url, attemptsLeft);
            }

            return bitmap;
        }
    }
}
于 2012-12-06T16:36:52.287 に答える