본문 바로가기
안드로이드

[Android] 내장 메모리 파일 가져오기 (1)

by Banlim 2020. 5. 3.

안드로이드 디바이스의 내장 메모리에 있는 파일을 가져오는 방법 첫번째를 소개한다.

-> 직접 접근하여 가져오기.

 

우선, 내장 메모리를 접근하기 위해서 메모리 읽기, 쓰기 권한 코드를 삽입한다.

 

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)

https://it-banlim.tistory.com/6?category=384003