안드로이드 디바이스의 내장 메모리에 있는 파일을 가져오는 방법 첫번째를 소개한다.
-> 직접 접근하여 가져오기.
우선, 내장 메모리를 접근하기 위해서 메모리 읽기, 쓰기 권한 코드를 삽입한다.
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
메모리 읽기, 쓰기 권한은 위험으로 간주하는 권한이기 때문에, 사용자가 명시적으로 앱 액세스 권한을 부여해야 한다. 런타임에 사용자에게 해당 권한을 요청하기 위한 메시지를 표시해야하는 코드를 작성한다.
LoadingActivity.java
public class LoadActivity extends Activity {
private int permissioncheck = 1;
private String[] permissionArr = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
// 여러가지 권한 요청 시 Array에 추가한다.
// ex) Manifest.permission.ACCESS_COARSE_LOCATION
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_load);
if(!hasPermissions(this, permissionArr)){
ActivityCompat.requestPermissions(this, permissionArr, permissioncheck);
}
else{
// 메인 엑티비티 진입
}
}
public boolean hasPermissions(Context context, String...permissionArr){
if(context != null && permissionArr !=null){
for(String permission : permissionArr){
if(ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED){
return false;
}
}
}
return true;
}
private void getPermission(){
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
//Manifest.permission.ACCESS_COARSE_LOCATION
}, 1000);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(Build.VERSION.SDK_INT >= 23){
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
Log.d("permission", permissionArr[0] + "was " + grantResults[0]);
recreate();
}
else
{
Log.d("permission", "denied");
Toast.makeText(LoadActivity.this, "앱을 사용하기 위해서는 메모리 접근 권한이 필요합니다.", Toast.LENGTH_LONG).show();
getPermission();
}
}
}
}
사용자가 메모리 접근 요청을 허용하였으면, File 타입으로 직접 내장메모리에 접근한다.
나의 경우, LoadFiles라는 Thread를 생성하여 접근하였다.
LoadFiles.java
public class LoadFiles extends Thread {
private ArrayList<File> documentFiles;
private File file;
private String ExternalPath = Environment.getExternalStorageDirectory().getAbsolutePath();
private int fileCnt;
@Override
public void run() {
super.run();
documentFiles = new ArrayList<>();
DocumentPathRead(ExternalPath);
}
public int DocumentPathRead(String path)
{
int cnt = 0;
file = new File(path);
File[] files = file.listFiles();
String innerPath;
for(int i = 0; i < files.length; i++){
if(files[i].isDirectory()) {
innerPath = files[i].getAbsolutePath();
int tmp = fileCnt;
fileCnt += DocumentPathRead(innerPath);
if (fileCnt - tmp == 0) {
continue;
}
}
else
{
if(files[i].isFile()){
if(files[i].getName().endsWith(".hwp") || files[i].getName().endsWith(".doc") || files[i].getName().endsWith(".xlsx") || files[i].getName().endsWith(".pptx") || files[i].getName().endsWith(".pdf"))
{
documentFiles.add(files[i]);
cnt++;
}
}
}
}
return cnt;
}
}
Environment.getExternalStorageDirectory.getAbsoulutePath() |
위 함수를 통해 내장 메모리의 루트 부분에 있는 directory 경로를 가져와 해당 경로를 ExternalPath에 넣는다.
file = new File(path);
File[] files = file.listFiles();
String innerPath;
ExternalPath를 통해 파일을 하나 생성한 후, 해당 파일의 서브 파일들을 리스트 형태로 가져온다. 그리고 파일 안에 파일을 타고타고 들어가기 위해 String 타입의 innerPath라는 변수를 선언한다.
for(int i = 0; i < files.length; i++){
if(files[i].isDirectory()) {
innerPath = files[i].getAbsolutePath();
int tmp = fileCnt;
fileCnt += DocumentPathRead(innerPath);
if (fileCnt - tmp == 0) {
continue;
}
}
}
반복문을 통해 파일을 타고타고 들어간다. 현재 파일이 Directory인지 file인지 구분하여, Directory이면, DocumentPathRead(innerPath) 함수를 호출하여 그 디렉터리 안으로 들어가도록 한다.
else{
if(files[i].isFile()){
if(files[i].getName().endsWith(".hwp") || files[i].getName().endsWith(".doc") ||
files[i].getName().endsWith(".xlsx") || files[i].getName().endsWith(".pptx") ||
files[i].getName().endsWith(".pdf"))
{ documentFiles.add(files[i]);
cnt++; }}}
현재 파일이 디렉터리가 아니라면, 이전에 정의한 documentFiles라는 ArrayList에 그 파일을 추가한다.
files[i].getName().endswith("확장자명")
위 함수를 통해 '원하는 파일 형태만 가져오도록 조정할 수 있다.
public class LoadActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_load);
LoadFiles loadFilesThread;
loadFilesThread = new LoadFiles();
if(!hasPermissions(this, permissionArr)){
ActivityCompat.requestPermissions(this, permissionArr, permissioncheck);
}
else{
loadFilesThread.start();
while(true){
if(!loadFilesThread.isAlive()){
// 메인 엑티비티 진입
}
}
}
}
...
}
그리고 쓰레드가 끝날 때 메인 엑티비티에 진입하도록 설계하였다.
위와 같은 방법으로 파일을 가져올 수 있다. 하지만, 이렇게 가져와 비트맵 형태로 이미지와 같은 파일을 뷰에 로드할 때, 적은 수의 이미지도 시간이 꽤 걸린다는 단점이 존재하였다.
따라서, (2)편에서는 Android가 제공하는 MediaStore와 Picasso library를 사용하여 로드하는 방법을 소개하겠다.
[Android] 내장메모리 파일 가져오기 (2)
'안드로이드' 카테고리의 다른 글
[Android] Java ArrayList<DataModel> Sorting (0) | 2020.10.15 |
---|---|
[Android] Java Convert Date (0) | 2020.10.15 |
[Android] TabLayout textsize & Icon 색상 & Indicator 변경 방법 (0) | 2020.09.15 |
[Android] 내장 메모리 파일 가져오기 (2) (0) | 2020.08.10 |
[Android] TabViewPager 실행 오류 해결 (0) | 2020.08.06 |