Skip to content

Instantly share code, notes, and snippets.

@noxi515
Created November 7, 2012 06:26
Show Gist options
  • Save noxi515/4029833 to your computer and use it in GitHub Desktop.
Save noxi515/4029833 to your computer and use it in GitHub Desktop.
WeatherNow 天気アイコン読み込みファイル
package jp.co.noxi.weathernow.app;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import jp.co.noxi.weathernow.R;
import jp.co.noxi.weathernow.preference.MyPreferenceManager;
import jp.co.noxi.weathernow.style.ApplicationStyle;
import jp.co.noxi.weathernow.style.StyleManager;
import jp.co.noxi.weathernow.style.WeatherIcon;
import jp.co.noxi.weathernow.style.ZipManager;
import jp.co.noxi.weathernow.util.Common;
import jp.co.noxi.weathernow.util.LruCache;
import org.apache.commons.lang3.RandomStringUtils;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.widget.ImageView;
/**
* 天気アイコン管理クラス
*/
public final class AppWeatherIcon implements Closeable {
private static final String TAG = AppWeatherIcon.class.getSimpleName();
private static final String LARGE_ICON_PACKAGE = "jp.co.noxi.weathernow.largeicon";
private Resources mDefaultResources;
private Resources mResources;
private TypedArray mLargeIcons;
private TypedArray mSmallIcons;
private WeatherIcon mCustomIcon;
private LruCache<String> mImageCache;
private ZipManager mZipManager;
private ExecutorService mExecutorService;
public AppWeatherIcon(Context context, LruCache<String> imageCache) {
this(context, imageCache, false);
}
public AppWeatherIcon(Context context, LruCache<String> imageCache, boolean translucent) {
mImageCache = imageCache;
mDefaultResources = context.getResources();
mExecutorService = Executors.newFixedThreadPool(2);
try {
PackageInfo info = context.getPackageManager()
.getPackageInfo(LARGE_ICON_PACKAGE, 0);
mResources = Common.getSharedContext(context, LARGE_ICON_PACKAGE).getResources();
// SmallIcon未対応
if (info.versionCode < 4) {
mLargeIcons = mResources.obtainTypedArray(mResources.getIdentifier(
"iconLargeImage", "array", LARGE_ICON_PACKAGE));
mSmallIcons = context.getResources()
.obtainTypedArray(R.array.weathericon_small);
} else {
mLargeIcons = mResources.obtainTypedArray(mResources.getIdentifier(
"weathericon_large", "array", LARGE_ICON_PACKAGE));
mSmallIcons = mResources.obtainTypedArray(mResources.getIdentifier(
"weathericon_small", "array", LARGE_ICON_PACKAGE));
}
}
// LargeIconPackageが入っていない場合
catch (NameNotFoundException e) {
mResources = context.getResources();
mLargeIcons = context.getResources().obtainTypedArray(R.array.weathericon_small);
mSmallIcons = context.getResources().obtainTypedArray(R.array.weathericon_small);
}
final SharedPreferences pref =
MyPreferenceManager.getDefaultSharedPreferences(context);
final String key = translucent ?
StyleManager.STYLE_ID_TRANSLUCENT : StyleManager.STYLE_ID_CURRENT;
final String styleId = pref.getString(key, StyleManager.STYLE_ID_DEFAULT);
if (styleId != null && !StyleManager.STYLE_ID_DEFAULT.equals(styleId)) {
final File iconFile = ApplicationStyle.getWeatherIconFile(context, translucent);
if (iconFile.exists()) {
try {
mCustomIcon = new WeatherIcon(iconFile);
mZipManager = new ZipManager(styleId);
} catch (IOException e) {
if (Common.DEBUG) {
e.printStackTrace();
}
if (mCustomIcon != null) {
mCustomIcon.clear();
mCustomIcon = null;
}
if (mZipManager != null) {
mZipManager.close();
mZipManager = null;
}
}
}
}
}
/**
* 大天気アイコンを取得する
*/
public Drawable getLargeIcon(int number) {
try {
return mResources.getDrawable(mLargeIcons.getResourceId(number, 0));
} catch (Exception e) {
return mDefaultResources.getDrawable(R.drawable.empty);
}
}
/**
* 標準天気アイコンを取得する
*/
public Drawable getSmallIcon(int number) {
try {
return mResources.getDrawable(mSmallIcons.getResourceId(number, 0));
} catch (Exception e) {
return mDefaultResources.getDrawable(R.drawable.empty);
}
}
/**
* 天気アイコンを設定する。要MainThread動作。
*
* @param view
* 天気アイコンを表示するImageView
* @param number
* 天気アイコン番号
* @param large
* 大アイコンフラグ
*/
public void setImage(ImageView view, int number, boolean large) {
if (number < 0 || 43 < number) {
view.setImageResource(R.drawable.empty);
return;
}
if (mCustomIcon != null && mCustomIcon.getIcon(number) != null) {
final Bitmap bitmap = mImageCache.get(getIconKey(number));
if (bitmap != null) {
view.setImageBitmap(bitmap);
} else {
mExecutorService.execute(new LoadCustomIcon(view, number));
}
return;
}
view.setImageDrawable(large ? getLargeIcon(number) : getSmallIcon(number));
}
private String getIconKey(int number) {
return "weathericon:" + number;
}
@Override
public void close() throws IOException {
if (mExecutorService == null || mExecutorService.isShutdown()) {
throw new IOException(AppWeatherIcon.class.getSimpleName() + " was already closed.");
}
mExecutorService.shutdown();
List<Runnable> remainTasks = mExecutorService.shutdownNow();
mExecutorService = null;
if (Common.DEBUG) {
Log.d(TAG, "RemainTask count: " + remainTasks.size());
}
mDefaultResources = null;
mResources = null;
mLargeIcons = null;
mSmallIcons = null;
if (mCustomIcon != null) {
mCustomIcon.clear();
mCustomIcon = null;
}
}
/**
* カスタム天気アイコンを読み込むクラス
*/
private class LoadCustomIcon implements Runnable {
final WeakReference<ImageView> imageView;
final int iconNumber;
final String id;
LoadCustomIcon(ImageView imageView, int iconNumber) {
id = RandomStringUtils.randomAlphanumeric(10);
imageView.setTag(id);
this.imageView = new WeakReference<ImageView>(imageView);
this.iconNumber = iconNumber;
}
@Override
public void run() {
InputStream in = null;
try {
in = mZipManager.getInputStream(mCustomIcon.getIcon(iconNumber));
if (in != null) {
final Bitmap bitmap = BitmapFactory.decodeStream(in);
if (bitmap != null) {
mImageCache.put(getIconKey(iconNumber), bitmap);
final ImageView view = imageView.get();
if (view != null && id.equals(view.getTag())) {
view.post(new Runnable() {
@Override
public void run() {
view.setImageBitmap(bitmap);
}
});
view.postInvalidate();
}
return;
}
}
} catch (IOException e) {
if (Common.DEBUG) {
e.printStackTrace();
}
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
if (Common.DEBUG) {
e.printStackTrace();
}
}
in = null;
}
}
// When error
final ImageView view = imageView.get();
if (view != null && id.equals(view.getTag())) {
view.post(new Runnable() {
@Override
public void run() {
view.setImageResource(R.drawable.empty);
}
});
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment