Created
November 7, 2012 06:26
-
-
Save noxi515/4029833 to your computer and use it in GitHub Desktop.
WeatherNow 天気アイコン読み込みファイル
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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