[Android] DownloadManager로 파일 다운로드 받기

업데이트:

🌠 DownloadManager 사용하기 🌿

DownloadManager는 HTTP 다운로드를 처리하는 시스템 서비스이다.
앱은 URI를 저장될 위치와 특정 파일로 다운로드 하도록 요청할 수 있다. 또한, 앱에서 별도의 스레드를 생성할 필요 없이, 내부의 백그라운드 서비스에서 다운로드를 수행한다.
 

DownloadManager는 notification을 통해 사용자에게 다운로드 상태를 보여주며, 실시간으로 다운로드 상태를 체크할 수 있다. 다운로드가 완료되면 브로드캐스트를 통해 완료되었음을 알려준다.
다음은 DownloadManager를 사용해서 파일을 다운로드 하는 과정이다.
 


🦋 인터넷 권한 설정

  • 매니페스트 파일에 인터넷 권한과 저장소 권한 추가
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

 

🦋 기본 설정

  • 다운받은 파일이 저장될 위치 설정
private String outputFilePath = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DOWNLOADS + "/저장할 폴더 이름") + "/저장할 파일 이름.txt";
  • 브로드캐스트 리시버 등록
    • ACTION_DOWNLOAD_COMPLETE : 다운로드가 완료되었을 때 전달
@Override
public void onResume(){
    super.onResume();
    IntentFilter completeFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
    registerReceiver(downloadCompleteReceiver, completeFilter);
}

@Override
public void onPause(){
    super.onPause();
    unregisterReceiver(downloadCompleteReceiver);
}

 

🦋 다운로드 요청

DownloadManager.Request을 설정하여 DownloadManager Queue에 등록하게 되면 큐에 들어간 순서대로 다운로드가 처리된다.
DownloadManager 객체 생성하여 다운로드 대기열에 URI 객체를 넣는다.

private DownloadManager mDownloadManager;
private Long mDownloadQueueId;
...
private void URLDownloading(Uri url) {
        if (mDownloadManager == null) {
            mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        }
        File outputFile = new File(outputFilePath);
        if (!outputFile.getParentFile().exists()) {
            outputFile.getParentFile().mkdirs();
        }

        Uri downloadUri = url;
        DownloadManager.Request request = new DownloadManager.Request(downloadUri);
        List<String> pathSegmentList = downloadUri.getPathSegments();
        request.setTitle("다운로드 항목");
        request.setDestinationUri(Uri.fromFile(outputFile));
        request.setAllowedOverMetered(true);

        mDownloadQueueId = mDownloadManager.enqueue(request);
    }

Request 설정 항목

  • DownloadManager.Request : Request 객체를 생성하며 인자로 다운로드할 파일의 URI를 전달한다.

  • setTitle : notification 제목

  • setDescription : notification 설명

  • setNotificationVisibility : VISIBILITY_VISIBLE로 설정되면 notification에 보여진다.

  • setDestinationUri : 파일이 저장될 위치의 URI

  • setRequiresCharging : true일 경우, 단말이 충전중일 때만 다운로드

  • setAllowedOverMetered : true일 경우, 모바일네트워크가 연결되었을 때도 다운로드

  • setAllowedOverRoaming : true일 경우, 로밍네트워크가 연결되었을 때도 다운로드

 

🦋 다운로드 상태 조회

DownloadManager.Query 객체를 생성하고 DownloadManager.query()로 쿼리를 한다. cursor가 리턴되며 특정 칼럼을 조회하여 다운로드 상태를 가져온다.

private BroadcastReceiver downloadCompleteReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        long reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);

        if(mDownloadQueueId == reference){
            DownloadManager.Query query = new DownloadManager.Query();  // 다운로드 항목 조회에 필요한 정보 포함
            query.setFilterById(reference);
            Cursor cursor = mDownloadManager.query(query);

            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
            int columnReason = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);

            int status = cursor.getInt(columnIndex);
            int reason = cursor.getInt(columnReason);

            cursor.close();

            switch (status) {
                case DownloadManager.STATUS_SUCCESSFUL :
                    Toast.makeText(mContext, "다운로드를 완료하였습니다.", Toast.LENGTH_SHORT).show();
                    break;

                case DownloadManager.STATUS_PAUSED :
                    Toast.makeText(mContext, "다운로드가 중단되었습니다.", Toast.LENGTH_SHORT).show();
                    break;

                case DownloadManager.STATUS_FAILED :
                    Toast.makeText(mContext, "다운로드가 취소되었습니다.", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }
};
  • 브로드캐스트에서 다운로드 상태를 조회하는 코드이다. 다운로드 상태는 아래와 같은 값을 반환한다.
    • STATUS_SUCCESSFUL
    • STATUS_FAILED
    • STATUS_RUNNING
    • STATUS_PAUSED


 
이렇게 다운로드 할 때 사용자가 notification을 통해 다운로드 상황을 볼 수 있다. notification은 DownloadManager에서 구현된 부분이기 때문에 따로 noti를 구현할 필요 없다.

 
해당 프로젝트 Github 예제는 여기에 😊
sample-download-file

 
 
[참고]
https://codechacha.com/ko/android-downloadmanager/
https://developer.android.com/reference/android/app/DownloadManager