Android (안드로이드)

[Android] DownloadManager / HTTP 통신으로 파일 다운로드하기

Oscar:) 2025. 1. 10. 21:00
728x90

 

 

 

DownloadManager 클래스를 활용하여 인터넷 상의 파일을 앱에서 다운로드해 본다.

 

 

 

 


 

 

✅ DownloadManager ?

 

DownloadManager는 HTTP 다운로드를 처리하는 시스템 서비스다.

엄밀히 말하면 장기적인 HTTP 다운로드를 처리한다.

 

클라이언트는 다운로드할 파일의 경로, 즉 URI만 알고 있다면 다운로드를 요청할 수 있다.

 

DownloadManager는 기본적으로 백그라운드에서 작업을 수행하도록 설계되어 있어서,

개발자가 별도로 백그라운드 작업 처리를 해주지 않아도 된다.

 

또한, 다운로드가 진행 중일 때는 알림 드로어에 진행 상황이 자동으로 표시된다.

 

 

 

 

 

 

✅ 샘플 파일 경로

 

먼저, 다운로드해 볼 파일의 경로는 다음과 같다.

// 이미지
"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg"

// 동영상
"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"

 

구글 클라우드 스토리지에 저장되어 있는 샘플 파일이다.

이러한 샘플 파일은 다운로드 기능이나 미디어 플레이어 등을 테스트할 때 유용하다.

 

구글에서는 위 파일을 제외하고도 다양한 샘플 파일을 제공하지만,

그 중에서도 가장 대표적으로 꼽히는 빅벅버니를 다운로드 해보자.

 

대충 이렇게 생긴 토끼녀석.

 

처음에는 진짜 별로인 비주얼이었는데,,,

요즘 테스트가 잦아서 이래저래 자주 보다 보니 정들었다.

 

 

 

 

 

 

✅ Manifest 파일 세팅

 

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />

<application
  ...
  android:usesCleartextTraffic="true"
  >

 

HTTP 통신으로 다운로드를 진행하기 때문에 인터넷 권한이 필요하고,

저장소에 파일을 저장할 것이기 때문에 저장소 접근 권한이 필요하다.

 

그리고 다운로드 테스트를 진행해 볼 파일의 경로가 HTTPS가 아닌 HTTP이기 때문에

usesCleartextTraffic="true" 작성해주자.

 

 

 

 

 

 

✅ DownloadManager - 이미지 다운로드

 

저장소 접근 권한 요청이 필요하기 때문에,

오늘도 역시 TedPermission 라이브러리 활용하여 간편하게 진행해준다.

TedPermission.create()
  .setPermissionListener(object : PermissionListener {
    override fun onPermissionGranted() {
      downloadImage()
    }
    override fun onPermissionDenied(deniedPermissions: List<String>) {
      Log.d(TAG, "onPermissionDenied: 권한 거부됨")
    }
  })
  .setDeniedMessage("권한을 허용해 주셔야\n사용 가능합니다.")
  .setPermissions(android.Manifest.permission.READ_MEDIA_IMAGES)
  .check()

 

권한이 허용되면 downloadImage() 함수를 호출한다.

 

 

 

fun downloadImage() {
  // 위에서 언급했던 토끼 이미지의 경로
  val uri = Uri.parse("http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg")
  
  // Request 객체 초기화 및 옵션 세팅
  val request = DownloadManager.Request(uri).apply {
    setTitle("BigBuckBunny.jpg")
    setMimeType("image/*")
    setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES, "빅벅버니.jpg")
  }
  
  // 다운로드 매니저 객체 초기화
  val manager = this@DownloadActivity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
  
  // 다운로드 요청 전송
  manager.enqueue(request)
}

 

코드마다 간단히 주석을 작성했으니 확인하기 바란다.

 

setDestinationInExternalPublicDir() 함수의 파라미터만 간단히 설명하자면

① 다운로드할 폴더(경로)를 지정한다.

② 다운로드할 파일의 이름을 지정한다. (세부 경로라고 할 수도 있다)

 

 

 

 

 

 

✅ 결과

 

다운로드가 완료된 후 갤러리 앱에 들어가보면

 

 

위 처럼 요망한 토끼를 만나볼 수 있다.

 

 

 

그리고 이미지 파일의 상세 정보를 눌러보면

 

 

위 코드에서 작성해준 파일 이름도 잘 지정된 것을 확인할 수 있다.

 

 

 

 

 

 

✅ DownloadManager - 동영상 다운로드

 

이미지 다운로드와 동일한 과정을 진행해주면 된다.

fun downloadVideo() {
  val uri = Uri.parse("http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
  
  val request = DownloadManager.Request(uri).apply {
    setTitle("BigBuckBunny.mp4")
    setMimeType("video/*")
    setDestinationInExternalPublicDir(Environment.DIRECTORY_MOVIES, "빅벅버니.mp4")
  }
  
  val manager = this@DownloadActivity.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
  manager.enqueue(request)
}

 

변경해줘야 하는 부분만 설명하자면,

 

● setMimeType() 값 변경 : "image/*" → "video/*"

● 다운로드 지정 폴더 변경 : DIRECTORY_PICTURES → DIRECTORY_MOVIES

○ URI 변경

○ setTitle() 값 변경 (알림 드로어에 표시되는 목적일 뿐)
○ 파일 이름 변경 (확장자만 변경)

 

 (● 중요 / ○ 기타)

 

 

 

 

 

 

✅ 결과

 

다운로드가 진행 중일 때 Notification은 별도로 동작하지 않지만,

알림 드로어 창에서는 다운로드 진행 상황을 확인할 수 있다.

 

 

Request.setTitle()에 세팅한 값이 제목으로 표시되는 모습이다.

 

 

 

 

다운로드 완료 후, 갤러리에서 동영상을 확인해볼 수 있다.

 

 

 

 

 

 


 

 

 

 

인터넷 상의 파일을 다운로드 하는 방법을 알아보았다.

 

다운로드 요청을 세세하게 구현하지 않아도 되었고, (HTTP 통신 등)

Noti를 표시하는 동작 등이 모두 구현되어 있어서 상당히 편리했다.

 

 

 

 

728x90