=======================
=======================
=======================
출처: http://blog.naver.com/PostView.nhn?blogId=mindori17&logNo=120196766106
안드로이드 어플 내에서 어플의 res나 다른 폴더에 있는 zip 파일의 압축을 다른 폴더로 푸는 방식에 대해서
제가 구글링을 통해 알게 된 내용을 말씀드리겠습니다.
먼저 참조한 곳은 아래와 같습니다.
설명이 매우 쉽게 되어 있어서 보시면 금방 동작 원리를 알 수 있으실 것 같습니다.
http://www.jondev.net/articles/Unzipping_Files_with_Android_%28Programmatically%29
저는 두 가지 경우에 대하여 말씀드리겠는데요.
zip 파일이 phone 내부의 폴더 내에 있을 때와 해당 application의 res 안에 있을 경우 입니다.
1) 해당 zip파일이 phone의 내부 폴더에 있을 때
먼저 Decompress 라는 class를 아래와 같이 선언 합니다.
****************************
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class Decompress {
private String _zipFile; //저장된 zip 파일 위치
private String _location; //압출을 풀 위치
public Decompress(String zipFile, String location) {
_zipFile = zipFile;
_location = location;
_dirChecker(""); //폴더를 만들기 위한 함수로 아래에 정의 되어 있습니다.
}
public void unzip() {
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
Log.v("Decompress", "Unzipping " + ze.getName()); //압축이 풀리면서 logcat으로 zip 안에 있던 파일 if(ze.isDirectory()) { 들을 볼 수 있습니다.
_dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(_location + ze.getName());
BufferedInputStream in = new BufferedInputStream(zin); //이렇게 지정하지 않고 unzip을
BufferedOutputStream out = new BufferedOutputStream(fout); 수행하면 속도가 매우 느려
byte b[] = new byte[1024]; 집니다.
int n;
while ((n = in.read(b,0,1024)) >= 0) {
out.write(b,0,n);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
} catch(Exception e) {
Log.e("Decompress", "unzip", e);
}
}
//변수 location에 저장된 directory의 폴더를 만듭니다.
private void _dirChecker(String dir) {
File f = new File(_location + dir);
if(!f.isDirectory()) {
f.mkdirs();
}
}
}
********************************************
이제 압축 풀기를 실행하고 싶은 부분에 다음과 같은 코드를 삽입하여 정의한 class를 실행하여 unzip을 수행합니다.
zipFile과 unzipLocation만 각자 상황에 맞게 수정하시면 될 것 같습니다.
1)-1 외부 메모리에 압축 해제 (rooting을 하지 않아도 폴더를 볼 수 있음)
***********************************************************************************************
String zipFile = Environment.getExternalStorageDirectory() + "/files.zip"; //zip 파일이 있는 위치 정의
String unzipLocation = Environment.getExternalStorageDirectory() + "/unzipped/"; //unzip 하고자 하는 위치
Decompress d = new Decompress(zipFile, unzipLocation);
d.unzip();
***********************************************************************************************
1)-2 해당 application의 폴더 내에 압축 해제 (rooting을 하지 않으면 폴더에 접근할 수 없지만 해당 application 안에서는 접근 가능)
일단적으로 application은 smart phone 내부의 /data/app/ 의 경로에 설치 되는 데요.
이 /data안의 내용은 rooting을 하지 않으면 볼 수 없습니다. (탐색시 빈 폴더로 표기 됩니다.)
또한 다른 application에서 보안상의 이유로 접근을 할 수 도 없습니다.
그러나 해당 application으로는 접근과 사용이 가능하기 때문에 현재 동작하는 application에서 자신의 폴더 안에 unzip이 가능합니다.
그 방법은 위와 동일하며 지금 실행되는 application의 설치 위치를 얻기 위한 부분과 예외 처리 부분만 달라집니다.
먼저 unzip을 수행하고자 하는 부분에 아래와 같은 코드를 삽입하여 unzip을 수행합니다.
***********************************************************************************************
String apploc=Environment.getExternalStorageDirectory()+"/"; //우선 path를 외부 메모리의 path로 설정
try {
apploc=getDataDir()+"/"; //현재 실행되는 app의 설치 경로를 얻음
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String unzipLocation = apploc+ "unzipped/"; //현재 실행되는 app 내부의 unzipped라는 폴더로
Decompress d = new Decompress(unzipLocation); 설치경로 지정
d.unzip(); //unzip 수행
String fulldir=apploc+ "unzipped"; //이후엔 unzip이 제대로 수행했는지 확인하기 위하여 unziped폴더
File fileList = new File(fulldir); 안의 파일 이름을 log cat에 출력
File[] filenames = fileList.listFiles();
for (File tmpf : filenames){
Log.d("Existing File :",fulldir+"/"+tmpf.getName() );
***********************************************************************************************
위에서 사용한 getDataDir()은 아래와 같이 정의 해 줍니다.
***********************************************************************************************
public String getDataDir() throws Exception
{ Log.d("*****************", getApplicationContext().getPackageManager().getPackageInfo(getPackageName(), 0).applicationInfo.dataDir);
return getApplicationContext().getPackageManager().getPackageInfo(getPackageName(), 0).applicationInfo.dataDir;
}
***********************************************************************************************
2) zip파일이 해당 application의 res 폴더 안에 있을 때
소스가 거의 동일해서 또 올리기 민망하지만 긁어 붙이기의 편의를 위해 올리겠습니다.
zip 파일은 다음 그림과 같이 res/raw에 있을 때의 경우 입니다.
****************************
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class Decompress {
private String _location; //압출을 풀 위치
public Decompress(String location) {
_location = location;
_dirChecker(""); //폴더를 만들기 위한 함수로 아래에 정의 되어 있습니다.
}
public void unzip() {
try {
final ZipInputStream zin = new ZipInputStream(getResources().openRawResource(R.raw.haa));
//이 부분을 바꿔어 주셔야 합니다. 저의 경우 zip 파일이 res/raw 폴더 안의 haa.zip 이었습니다.
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
Log.v("Decompress", "Unzipping " + ze.getName()); //압축이 풀리면서 logcat으로 zip 안에 있던 파일 if(ze.isDirectory()) { 들을 볼 수 있습니다.
_dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(_location + ze.getName());
BufferedInputStream in = new BufferedInputStream(zin);
BufferedOutputStream out = new BufferedOutputStream(fout);
byte b[] = new byte[1024];
int n;
while ((n = in.read(b,0,1024)) >= 0) {
out.write(b,0,n);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
} catch(Exception e) {
Log.e("Decompress", "unzip", e);
}
}
//변수 location에 저장된 directory의 폴더를 만듭니다.
private void _dirChecker(String dir) {
File f = new File(_location + dir);
if(!f.isDirectory()) {
f.mkdirs();
}
}
}
********************************************
이제 unzip 수행을 명령하고 싶은 곳에 다음과 같이 정의한 class를 실행 시켜 줍니다.
위와 다른 점은 Decompress 안에서 대상이 되는 zip 파일 위치를 정의 하였기 때문에 압축을 풀 곳만 지정해 주시면 됩니다.
***********************************************************************************************
String unzipLocation = Environment.getExternalStorageDirectory() + "/unzipped/"; //unzip 하고자 하는 위치
Decompress d = new Decompress(unzipLocation);
d.unzip();
***********************************************************************************************
[출처] [Tip] android에서 zip 파일 압축 해제(unzip)|작성자 minho
=======================
=======================
=======================
출처: https://blog.naver.com/llloveshin/221550313475
여기 나와있는 소스대로 사용하면 압축이 잘 풀리지만, 중간에 outputStream이 flush 되지 않아 파일이 잘리는 현상이 있다.
같은 내용의 소스가 국내외 많은 사이트에서 소개되고 있기 때문에, 다른 부분에서 문제가 있는줄 알고 한참을 삽질했다.
BufferedOutputStream out = new BufferedOutputStream(fout);
이녀석이 flush 되지 않고 있다.
out.close(); <- 이 한줄을 추가하니 문제없이 unzip된다.
zin.closeEntry();
fout.close();
참고로 위 링크에 있는 소스는 byte 단위로 처리하기 때문에, 파일명이 한글인 경우 정상적으로 압축이 풀리지 않는다.
따라서 char 단위로 처리하는 reader 클래스를 사용하는 소스로 바꾸거나, 파일명에 한글이 없도록 해야 한다.
[출처] Android Studio Unzip|작성자 셀이다
=======================
=======================
=======================
'스마트기기개발관련 > 안드로이드 개발' 카테고리의 다른 글
안드로이드 개발 패키지정보를 가져와보자 (0) | 2014.04.24 |
---|---|
[안드로이드/안드로이드 개발]Intent filter 를 이용한 실행가능 app 목록 얻어오기(Intent.createChooser) (0) | 2014.04.24 |
android 안드로이드 개발 다운로드 관련 (0) | 2014.02.27 |
android webview apk download to sdcard from webview webview 를 통해 안드로이드 파일 다운로드, apk 다운로드 설치 관련 (0) | 2014.02.27 |
안드로이드 flash 플래시 플레이어 apk 다운로드 관련 (0) | 2014.02.18 |