Created
March 20, 2013 02:16
-
-
Save TakamiChie/5201798 to your computer and use it in GitHub Desktop.
AssetInstaller ref: http://qiita.com/items/4e94e9462bea6f409372
This file contains 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
/** | |
* http://outcesticide.hatenablog.com/entries/2012/12/12 | |
* の記事を参考にしています。 | |
*/ | |
import java.io.BufferedInputStream; | |
import java.io.BufferedOutputStream; | |
import java.io.File; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.io.OutputStream; | |
import java.util.ArrayList; | |
import java.util.zip.ZipEntry; | |
import java.util.zip.ZipInputStream; | |
import android.app.Dialog; | |
import android.app.ProgressDialog; | |
import android.content.res.AssetFileDescriptor; | |
import android.os.AsyncTask; | |
import android.os.Bundle; | |
import android.support.v4.app.DialogFragment; | |
import android.support.v4.app.FragmentActivity; | |
import android.util.Log; | |
public class AssetInstaller extends AsyncTask<String, Object, Boolean> { | |
/** | |
* インストールがキャンセルされた(現時点のバージョンでは起こりえません) | |
*/ | |
public final static int CANCELLED = -1; | |
/** | |
* すでにインストールされていたため、処理をスキップした | |
*/ | |
public final static int INSTALLED = 0; | |
/** | |
* インストールが正常終了した | |
*/ | |
public final static int SUCCESSED = 1; | |
/** | |
* インストールが完了したときに呼び出されるコールバックインタフェース | |
* @author 知英 | |
*/ | |
public interface FinishedListener { | |
/** | |
* インストールが完了したときにコールバックされるメソッド。 | |
* もし指定したファイルがインストール済みであった場合、何もせずにこのメソッドを呼び出す。 | |
* @param state インストール状態。CANCELLED, INSTALLED, SUCCESSEDのいずれか。 | |
*/ | |
void installFinished(int state); | |
} | |
public final static String TAG = AssetInstaller.class.getSimpleName(); | |
private FragmentActivity mActivity; | |
private File mBaseDir; | |
private ArrayList<String> mZippedFiles; | |
private int mTotalSize; | |
private ProgressDialogFragment mDialogFragment; | |
private FinishedListener mFinishedListener; | |
private String mDialogTitle; | |
private String mDialogMessage; | |
public AssetInstaller(FragmentActivity activity, File baseDir, | |
FinishedListener finished) { | |
this.mActivity = activity; | |
this.mBaseDir = baseDir; | |
this.mFinishedListener = finished; | |
} | |
public void setProgressTitle(String title) { | |
this.mDialogTitle = title; | |
} | |
public void setProgressMessage(String message) { | |
this.mDialogMessage = message; | |
} | |
@Override | |
protected Boolean doInBackground(String... params) { | |
boolean result = false; | |
for (String param : params) { | |
Log.d(TAG, "install " + param + "?"); | |
try { | |
File dir = new File(mBaseDir, param); | |
if (checkToCopyFile(dir, param)) { | |
Log.d(TAG, "install " + param + "."); | |
result |= startCopyToFile(dir, param); | |
} else { | |
continue; | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
return result; | |
} | |
@Override | |
protected void onProgressUpdate(Object... values) { | |
Log.i(TAG, "progress update"); | |
if (values.length == 0) { | |
Log.i(TAG, "filesize:" + mTotalSize); | |
showProgress(mTotalSize); | |
} else if (values[0] instanceof Integer) { | |
updateProgress((Integer) values[0]); | |
} else if (values[0] instanceof String) { | |
updateMessage((String) values[0]); | |
} | |
} | |
@Override | |
protected void onPostExecute(Boolean result) { | |
Log.d(TAG, "executed"); | |
dismissProgress(); | |
if (mFinishedListener != null) { | |
mFinishedListener.installFinished(result ? SUCCESSED : INSTALLED); | |
} | |
} | |
@Override | |
protected void onCancelled() { | |
Log.d(TAG, "cancelled"); | |
if (mFinishedListener != null) { | |
mFinishedListener.installFinished(CANCELLED); | |
} | |
} | |
// プログレスバー処理 | |
/** | |
* プログレスダイアログを表示する | |
* | |
* @param max | |
* プログレスの最大値 | |
*/ | |
private void showProgress(int max) { | |
mDialogFragment = new ProgressDialogFragment(); | |
Bundle arguments = new Bundle(); | |
arguments.putInt(ProgressDialogFragment.PARAM_MAX, max); | |
if (mDialogTitle != null) { | |
arguments.putString(ProgressDialogFragment.PARAM_TITLE, | |
mDialogTitle); | |
} | |
mDialogFragment.setArguments(arguments); | |
mDialogFragment.show(mActivity.getSupportFragmentManager(), ""); | |
} | |
/** | |
* プログレスダイアログの値を更新する | |
* | |
* @param value | |
* 更新する値 | |
*/ | |
private void updateProgress(int value) { | |
mDialogFragment.updateProgress(value); | |
} | |
/** | |
* プログレスダイアログのメッセージを更新する。 | |
* <ul> | |
* <li>メッセージ内の%1$sは展開するアーカイブファイル名 | |
* <li>メッセージ内の%2$sは現在展開中のZipEntryファイル名 | |
* </ul> | |
* に展開される | |
* | |
* @param string | |
*/ | |
private void updateMessage(String message) { | |
mDialogFragment.updateMessage(message); | |
} | |
/** | |
* プログレスダイアログを破棄する | |
*/ | |
private void dismissProgress() { | |
if (mDialogFragment != null) { | |
mDialogFragment.dismiss(); | |
} | |
} | |
// ユーティリティメソッド | |
/** | |
* Assetフォルダ内のZIPファイルを開き、そのストリームを返す | |
* | |
* @param fileName | |
* ファイル名(拡張子抜き) | |
* @return ZIPストリーム | |
* @throws IOException | |
*/ | |
private ZipInputStream getAssetZipInputStream(String fileName) | |
throws IOException { | |
AssetFileDescriptor fd = mActivity.getResources().getAssets() | |
.openFd(fileName + ".zip"); | |
return new ZipInputStream(new BufferedInputStream( | |
fd.createInputStream())); | |
} | |
/** | |
* Assetフォルダ内のZIPファイルを展開する必要があるかどうか確認する | |
* | |
* @param dir | |
* ベースディレクトリを示す{@link File}オブジェクト | |
* @param fileName | |
* 展開対象のファイル名 | |
* @return ファイルを展開する必要がある場合、trueを返す | |
* @throws IOException | |
*/ | |
private boolean checkToCopyFile(File dir, String fileName) | |
throws IOException { | |
mZippedFiles = new ArrayList<String>(); | |
mTotalSize = 0; | |
ZipInputStream zis = null; | |
try { | |
zis = getAssetZipInputStream(fileName); | |
ZipEntry zipEntry; | |
while ((zipEntry = zis.getNextEntry()) != null) { | |
if (zipEntry.isDirectory()) { | |
zis.closeEntry(); | |
continue; | |
} | |
long zipEntrySize = zipEntry.getSize(); | |
String zipEntryName = zipEntry.getName(); | |
Log.i(TAG, "check:" + zipEntryName); | |
File unzippedFile = new File(dir, zipEntryName); | |
long unzippedFileSize = unzippedFile.length(); | |
if (zipEntrySize != unzippedFileSize) { | |
Log.i(TAG, "unzip needed"); | |
mZippedFiles.add(zipEntryName); | |
mTotalSize += zipEntrySize; | |
} | |
} | |
} finally { | |
if (zis != null) | |
zis.close(); | |
} | |
return !mZippedFiles.isEmpty(); | |
} | |
/** | |
* ZIPファイルを展開し、実フォルダに配置する | |
* | |
* @param dir | |
* ベースディレクトリを示す{@link File}オブジェクト | |
* @param fileName | |
* 展開対象のファイル名 | |
* @return ファイルが正しく展開された場合、trueを返す | |
* @throws IOException | |
*/ | |
private boolean startCopyToFile(File dir, String fileName) | |
throws IOException { | |
return copyFiles(dir, fileName); | |
} | |
/** | |
* ZIPファイルを展開し、実フォルダに配置する | |
* | |
* @param dir | |
* ベースディレクトリを示す{@link File}オブジェクト | |
* @param fileName | |
* 展開対象のファイル名 | |
* @return ファイルが正しく展開された場合、trueを返す | |
* @throws IOException | |
*/ | |
private boolean copyFiles(File dir, String fileName) throws IOException { | |
boolean result = false; | |
publishProgress(); | |
ZipInputStream zis = null; | |
int sizes = 0; | |
try { | |
zis = getAssetZipInputStream(fileName); | |
ZipEntry zipEntry; | |
while ((zipEntry = zis.getNextEntry()) != null) { | |
if (zipEntry.isDirectory()) { | |
zis.closeEntry(); | |
continue; | |
} | |
String zipEntryName = zipEntry.getName(); | |
if (mDialogMessage != null) { | |
publishProgress(String.format(mDialogMessage, fileName, | |
zipEntryName)); | |
} | |
File unzippedFile = new File(dir, zipEntryName); | |
if (!unzippedFile.getParentFile().exists()) { | |
unzippedFile.getParentFile().mkdirs(); | |
} | |
if (unzippedFile.exists()) { | |
unzippedFile.delete(); | |
} | |
OutputStream os = null; | |
try { | |
os = new BufferedOutputStream(new FileOutputStream( | |
unzippedFile)); | |
byte[] buf = new byte[1024]; | |
int len; | |
while ((len = zis.read(buf, 0, buf.length)) != -1) { | |
os.write(buf, 0, len); | |
sizes += len; | |
publishProgress(sizes); | |
} | |
os.flush(); | |
} finally { | |
if (os != null) { | |
os.close(); | |
} | |
} | |
unzippedFile.setReadable(true, false); | |
unzippedFile.setWritable(true, false); | |
zis.closeEntry(); | |
result = true; | |
} | |
} finally { | |
if (zis != null) { | |
zis.close(); | |
} | |
} | |
return result; | |
} | |
} | |
/** | |
* プログレスダイアログフラグメント | |
* @author 知英 | |
*/ | |
class ProgressDialogFragment extends DialogFragment { | |
/** | |
* プログレスバーの最大値 | |
*/ | |
public final static String PARAM_MAX = "max"; | |
/** | |
* プログレスダイアログの値 | |
*/ | |
public final static String PARAM_TITLE = "title"; | |
private int mStoredProgress = 0; | |
private String mStoredMessage = ""; | |
@Override | |
public Dialog onCreateDialog(Bundle savedInstanceState) { | |
ProgressDialog dialog = new ProgressDialog(getActivity()); | |
dialog.setIndeterminate(false); | |
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); | |
dialog.setCancelable(false); | |
dialog.incrementProgressBy(0); | |
setCancelable(false); | |
Bundle bundle = getArguments(); | |
if (bundle.containsKey(PARAM_TITLE)) { | |
dialog.setTitle(bundle.getString(PARAM_TITLE)); | |
} | |
dialog.setMessage(mStoredMessage); | |
dialog.setMax(bundle.getInt(PARAM_MAX)); | |
dialog.setProgress(mStoredProgress); | |
return dialog; | |
} | |
/** | |
* ダイアログのプログレスバー値を更新する | |
* @param progress プログレスバー値 | |
*/ | |
public void updateProgress(int progress) { | |
Dialog d = getDialog(); | |
if (d != null) { | |
((ProgressDialog) d).setProgress(progress); | |
} else { | |
mStoredProgress = progress; | |
} | |
} | |
/** | |
* ダイアログのメッセージを更新する | |
* @param message メッセージ | |
*/ | |
public void updateMessage(String message) { | |
Dialog d = getDialog(); | |
if (d != null) { | |
((ProgressDialog) d).setMessage(message); | |
} else { | |
mStoredMessage = message; | |
} | |
} | |
} |
This file contains 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
/** | |
* インストールがキャンセルされた(現時点のバージョンでは起こりえません) | |
*/ | |
public final static int CANCELLED = -1; | |
/** | |
* すでにインストールされていたため、処理をスキップした | |
*/ | |
public final static int INSTALLED = 0; | |
/** | |
* インストールが正常終了した | |
*/ | |
public final static int SUCCESSED = 1; | |
/** | |
* インストールが完了したときに呼び出されるコールバックインタフェース | |
* @author 知英 | |
*/ | |
public interface FinishedListener { | |
/** | |
* インストールが完了したときにコールバックされるメソッド。 | |
* もし指定したファイルがインストール済みであった場合、何もせずにこのメソッドを呼び出す。 | |
* @param state インストール状態。CANCELLED, INSTALLED, SUCCESSEDのいずれか。 | |
*/ | |
void installFinished(int state); | |
} | |
public final static String TAG = AssetInstaller.class.getSimpleName(); | |
private FragmentActivity mActivity; | |
private File mBaseDir; | |
private ArrayList<String> mZippedFiles; | |
private int mTotalSize; | |
private ProgressDialogFragment mDialogFragment; | |
private FinishedListener mFinishedListener; | |
private String mDialogTitle; | |
private String mDialogMessage; | |
public AssetInstaller(FragmentActivity activity, File baseDir, | |
FinishedListener finished) { | |
this.mActivity = activity; | |
this.mBaseDir = baseDir; | |
this.mFinishedListener = finished; | |
} | |
public void setProgressTitle(String title) { | |
this.mDialogTitle = title; | |
} | |
public void setProgressMessage(String message) { | |
this.mDialogMessage = message; | |
} | |
@Override | |
protected Boolean doInBackground(String... params) { | |
boolean result = false; | |
for (String param : params) { | |
Log.d(TAG, "install " + param + "?"); | |
try { | |
File dir = new File(mBaseDir, param); | |
if (checkToCopyFile(dir, param)) { | |
Log.d(TAG, "install " + param + "."); | |
result |= startCopyToFile(dir, param); | |
} else { | |
continue; | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
return result; | |
} | |
@Override | |
protected void onProgressUpdate(Object... values) { | |
Log.i(TAG, "progress update"); | |
if (values.length == 0) { | |
Log.i(TAG, "filesize:" + mTotalSize); | |
showProgress(mTotalSize); | |
} else if (values[0] instanceof Integer) { | |
updateProgress((Integer) values[0]); | |
} else if (values[0] instanceof String) { | |
updateMessage((String) values[0]); | |
} | |
} | |
@Override | |
protected void onPostExecute(Boolean result) { | |
Log.d(TAG, "executed"); | |
dismissProgress(); | |
if (mFinishedListener != null) { | |
mFinishedListener.installFinished(result ? SUCCESSED : INSTALLED); | |
} | |
} | |
@Override | |
protected void onCancelled() { | |
Log.d(TAG, "cancelled"); | |
if (mFinishedListener != null) { | |
mFinishedListener.installFinished(CANCELLED); | |
} | |
} | |
// プログレスバー処理 | |
/** | |
* プログレスダイアログを表示する | |
* | |
* @param max | |
* プログレスの最大値 | |
*/ | |
private void showProgress(int max) { | |
mDialogFragment = new ProgressDialogFragment(); | |
Bundle arguments = new Bundle(); | |
arguments.putInt(ProgressDialogFragment.PARAM_MAX, max); | |
if (mDialogTitle != null) { | |
arguments.putString(ProgressDialogFragment.PARAM_TITLE, | |
mDialogTitle); | |
} | |
mDialogFragment.setArguments(arguments); | |
mDialogFragment.show(mActivity.getSupportFragmentManager(), ""); | |
} | |
/** | |
* プログレスダイアログの値を更新する | |
* | |
* @param value | |
* 更新する値 | |
*/ | |
private void updateProgress(int value) { | |
mDialogFragment.updateProgress(value); | |
} | |
/** | |
* プログレスダイアログのメッセージを更新する。 | |
* <ul> | |
* <li>メッセージ内の%1$sは展開するアーカイブファイル名 | |
* <li>メッセージ内の%2$sは現在展開中のZipEntryファイル名 | |
* </ul> | |
* に展開される | |
* | |
* @param string | |
*/ | |
private void updateMessage(String message) { | |
mDialogFragment.updateMessage(message); | |
} | |
/** | |
* プログレスダイアログを破棄する | |
*/ | |
private void dismissProgress() { | |
if (mDialogFragment != null) { | |
mDialogFragment.dismiss(); | |
} | |
} | |
// ユーティリティメソッド | |
/** | |
* Assetフォルダ内のZIPファイルを開き、そのストリームを返す | |
* | |
* @param fileName | |
* ファイル名(拡張子抜き) | |
* @return ZIPストリーム | |
* @throws IOException | |
*/ | |
private ZipInputStream getAssetZipInputStream(String fileName) | |
throws IOException { | |
AssetFileDescriptor fd = mActivity.getResources().getAssets() | |
.openFd(fileName + ".zip"); | |
return new ZipInputStream(new BufferedInputStream( | |
fd.createInputStream())); | |
} | |
/** | |
* Assetフォルダ内のZIPファイルを展開する必要があるかどうか確認する | |
* | |
* @param dir | |
* ベースディレクトリを示す{@link File}オブジェクト | |
* @param fileName | |
* 展開対象のファイル名 | |
* @return ファイルを展開する必要がある場合、trueを返す | |
* @throws IOException | |
*/ | |
private boolean checkToCopyFile(File dir, String fileName) | |
throws IOException { | |
mZippedFiles = new ArrayList<String>(); | |
mTotalSize = 0; | |
ZipInputStream zis = null; | |
try { | |
zis = getAssetZipInputStream(fileName); | |
ZipEntry zipEntry; | |
while ((zipEntry = zis.getNextEntry()) != null) { | |
if (zipEntry.isDirectory()) { | |
zis.closeEntry(); | |
continue; | |
} | |
long zipEntrySize = zipEntry.getSize(); | |
String zipEntryName = zipEntry.getName(); | |
Log.i(TAG, "check:" + zipEntryName); | |
File unzippedFile = new File(dir, zipEntryName); | |
long unzippedFileSize = unzippedFile.length(); | |
if (zipEntrySize != unzippedFileSize) { | |
Log.i(TAG, "unzip needed"); | |
mZippedFiles.add(zipEntryName); | |
mTotalSize += zipEntrySize; | |
} | |
} | |
} finally { | |
if (zis != null) | |
zis.close(); | |
} | |
return !mZippedFiles.isEmpty(); | |
} | |
/** | |
* ZIPファイルを展開し、実フォルダに配置する | |
* | |
* @param dir | |
* ベースディレクトリを示す{@link File}オブジェクト | |
* @param fileName | |
* 展開対象のファイル名 | |
* @return ファイルが正しく展開された場合、trueを返す | |
* @throws IOException | |
*/ | |
private boolean startCopyToFile(File dir, String fileName) | |
throws IOException { | |
return copyFiles(dir, fileName); | |
} | |
/** | |
* ZIPファイルを展開し、実フォルダに配置する | |
* | |
* @param dir | |
* ベースディレクトリを示す{@link File}オブジェクト | |
* @param fileName | |
* 展開対象のファイル名 | |
* @return ファイルが正しく展開された場合、trueを返す | |
* @throws IOException | |
*/ | |
private boolean copyFiles(File dir, String fileName) throws IOException { | |
boolean result = false; | |
publishProgress(); | |
ZipInputStream zis = null; | |
int sizes = 0; | |
try { | |
zis = getAssetZipInputStream(fileName); | |
ZipEntry zipEntry; | |
while ((zipEntry = zis.getNextEntry()) != null) { | |
if (zipEntry.isDirectory()) { | |
zis.closeEntry(); | |
continue; | |
} | |
String zipEntryName = zipEntry.getName(); | |
if (mDialogMessage != null) { | |
publishProgress(String.format(mDialogMessage, fileName, | |
zipEntryName)); | |
} | |
File unzippedFile = new File(dir, zipEntryName); | |
if (!unzippedFile.getParentFile().exists()) { | |
unzippedFile.getParentFile().mkdirs(); | |
} | |
if (unzippedFile.exists()) { | |
unzippedFile.delete(); | |
} | |
OutputStream os = null; | |
try { | |
os = new BufferedOutputStream(new FileOutputStream( | |
unzippedFile)); | |
byte[] buf = new byte[1024]; | |
int len; | |
while ((len = zis.read(buf, 0, buf.length)) != -1) { | |
os.write(buf, 0, len); | |
sizes += len; | |
publishProgress(sizes); | |
} | |
os.flush(); | |
} finally { | |
if (os != null) { | |
os.close(); | |
} | |
} | |
unzippedFile.setReadable(true, false); | |
unzippedFile.setWritable(true, false); | |
zis.closeEntry(); | |
result = true; | |
} | |
} finally { | |
if (zis != null) { | |
zis.close(); | |
} | |
} | |
return result; | |
} |
This file contains 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
/** | |
* プログレスバーの最大値 | |
*/ | |
public final static String PARAM_MAX = "max"; | |
/** | |
* プログレスダイアログの値 | |
*/ | |
public final static String PARAM_TITLE = "title"; | |
private int mStoredProgress = 0; | |
private String mStoredMessage = ""; | |
@Override | |
public Dialog onCreateDialog(Bundle savedInstanceState) { | |
ProgressDialog dialog = new ProgressDialog(getActivity()); | |
dialog.setIndeterminate(false); | |
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); | |
dialog.setCancelable(false); | |
dialog.incrementProgressBy(0); | |
setCancelable(false); | |
Bundle bundle = getArguments(); | |
if (bundle.containsKey(PARAM_TITLE)) { | |
dialog.setTitle(bundle.getString(PARAM_TITLE)); | |
} | |
dialog.setMessage(mStoredMessage); | |
dialog.setMax(bundle.getInt(PARAM_MAX)); | |
dialog.setProgress(mStoredProgress); | |
return dialog; | |
} | |
/** | |
* ダイアログのプログレスバー値を更新する | |
* @param progress プログレスバー値 | |
*/ | |
public void updateProgress(int progress) { | |
Dialog d = getDialog(); | |
if (d != null) { | |
((ProgressDialog) d).setProgress(progress); | |
} else { | |
mStoredProgress = progress; | |
} | |
} | |
/** | |
* ダイアログのメッセージを更新する | |
* @param message メッセージ | |
*/ | |
public void updateMessage(String message) { | |
Dialog d = getDialog(); | |
if (d != null) { | |
((ProgressDialog) d).setMessage(message); | |
} else { | |
mStoredMessage = message; | |
} | |
} |
This file contains 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
public class MainActivity extends FragmentActivity implements AssetInstaller.FinishedListener { | |
protected void onCreate(Bundle savedInstanceState) { | |
・・・ | |
AssetInstaller installer = new AssetInstaller(this, getFilesDir(), this); | |
installer.setProgressTitle("文字解析に必要なファイルをインストールしています。"); | |
installer.setProgressMessage("%1$s.zipの%2$sを展開中"); | |
installer.execute("tessdata"); | |
} | |
・・・ | |
@Override | |
public void installFinished(int state) { | |
if (state != AssetInstaller.CANCELLED) { | |
/* インストールしたファイルの利用 */ | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment