やりたいこと
s3にあげているzipをダウンロードしてきて、アプリ内の任意の場所に保存する。
よくあるソシャゲの最初のアセットダウンロードみたいなことをしたい。
環境
クライアント
・Android Studio v3.*
サーバ
・AWS
ライブラリ(アリシャス!!)
・AWSClient & AWS Cognito
・ZipUtil(zip解凍)
https://github.com/zeroturnaround/zt-zip
実装
アセット一覧を取得
アセットListは、DBに登録していて、それをphpで取得している。
S3に接続にアクセスして、ファイルを取得する
クライアントを生成して、指定ファイルをダウンロードしてくるメソッド
S3クライアントを生成
↓
指定ファイルのインプットストリームを生成する
// マルチパートアップロード最少サイズ
private static final String ENDPOINT = "s3-ap-northeast-1.amazonaws.com";
private static final String BUCKET_NAME = "hogehoge";
/**
* S3から対象のファイルを取得する
*
* @param bucketName 対象のバケット
* @param objectKey 対象のファイル
* @return object
*/
public InputStream getObjectContent(String bucketName, String objectKey) {
// AmazonS3Clientインスタンスを作成
AmazonS3Client cli = makeS3Client();
// エンドポイントを設定
cli.setEndpoint(ENDPOINT);
// rootDirectory(Bucket名), objectKey(オブジェクトまでの相対パス)からリクエストを作成
GetObjectRequest request = new GetObjectRequest(bucketName, objectKey);
S3Object object = cli.getObject(request);
// Objectを開いたInputStreamを返す
return object.getObjectContent();
}
S3クライアント生成
S3クライアントインスタンスを生成する。
S3への接続には "Amazon Cognito"を使用してIDをもらう(直にkey、passを書くのは🙅)。
/**
* S3接続クライアントを作成
*
* @return クライアント
*/
private AmazonS3Client makeS3Client() {
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(),
"*******************", // ID プールの ID
Regions.AP_NORTHEAST_1 // リージョン
);
// ConfigurationでTimeout時間を30秒に設定
ClientConfiguration clientConfiguration = new ClientConfiguration();
clientConfiguration.setConnectionTimeout(30000);
// AmazonS3Clientをインスタンス化
return new AmazonS3Client(credentialsProvider, clientConfiguration);
}
アセットをダウンロードし、解凍・ファイルを任意の場所に移動する
protected void assetDownload(String filename, String fileByte) {
new AsyncTask<String, Integer, String>() {
@Override
protected void onPreExecute() {
//ダイアログを表示させるなどのUIの準備
}
@Override
protected String doInBackground(String... params) {
String filename = params[0];
String fileByte = params[1];
InputStream is;
FileOutputStream fos;
try {
is = getObjectContent(BUCKET_NAME, filename);
String outPutFile = mContext.getFilesDir().getPath() + "/" + filename;
fos = new FileOutputStream(outPutFile);
byte[] buffer = new byte[1024 * 1024];
int readSize = -1;
int total_download = 0;
BigDecimal fileByteDecimal = new BigDecimal(fileByte);
while ((readSize = is.read(buffer, 0, buffer.length)) != -1) {
fos.write(buffer, 0, readSize);
total_download += readSize; // 合計ダウンロード完了byte
BigDecimal totalByteDecimal = new BigDecimal(total_download + "");
double wariai1 = totalByteDecimal.divide(fileByteDecimal, 3, BigDecimal.ROUND_HALF_UP).doubleValue();
BigDecimal a = new BigDecimal(wariai1);
BigDecimal b = new BigDecimal("100");
int wariai = a.multiply(b).intValue();
publishProgress(wariai);
}
fos.flush();
if (is != null) {
is.close();
}
if (fos != null) {
fos.close();
}
// Downloadしたzipを解凍する
File zipFile = new File(outPutFile); // unzipする対象のFile
File outputFile = new File(mContext.getFilesDir().getPath()); // 出力先のFile
ZipUtil.unpack(zipFile, outputFile);
// 中身のファイルをfilesに移動する
String DirName = filename.replace(".zip", "");
File outputDir = new File(mContext.getFilesDir().getPath() + "/" + DirName);
File[] files = outputDir.listFiles(); // ディレクトリの中身一覧
for (File file : files) {
if (file.isDirectory()) {
file.delete();
}
if (file.isFile()) {
// 移動
File moveFile = new File(mContext.getFilesDir().getPath() + "/" + file.getName()); // 出力先のFile
file.renameTo(moveFile);
}
}
// もとのZIP削除
zipFile.delete();
} catch (IOException ex) {
Logger.log(ex.getMessage());
} finally {
}
return "1";
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// ダウンロード進捗を表示。etc...
}
@Override
protected void onPostExecute(String result) {
// ファイルダウンロード完了
}
}.execute(filename, fileByte);
}