Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Android에서 지정된 URL의 이미지를 다운로드하고 저장하는 방법

이 튜토리얼에서는 Android 앱에서 지정된 URL의 이미지를 다운로드해 화면에 표시하는 방법을 단계별로 살펴봅니다. 네트워크 작업은 반드시 백그라운드에서 처리해야 하므로, 이 예제에서는 AsyncTask를 사용해 이미지를 내려받고, 다운로드가 진행되는 동안 ProgressDialog로 진행 상태를 사용자에게 보여줍니다.

1단계 — 새 프로젝트 만들기

Android Studio를 열고 File → New Project를 선택한 뒤, 새 프로젝트 생성에 필요한 모든 세부 정보를 입력합니다.

2단계 — 레이아웃 작성 (res/layout/activity_main.xml)

다음 코드를 activity_main.xml에 추가하세요. 화면 상단에는 다운로드 버튼이, 하단에는 결과 이미지를 보여줄 ImageView가 배치된 CoordinatorLayout 구조입니다.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/btnDownload"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Download Image"
        android:layout_margin="25dp"
        android:layout_gravity="top|center_horizontal" />
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:scaleType="centerCrop"
        app:layout_anchor="@id/btnDownload"
        android:layout_gravity="bottom"
        app:layout_anchorGravity="bottom"
        android:layout_margin="10dp" />
</android.support.design.widget.CoordinatorLayout>

3단계 — 메인 액티비티 작성 (src/MainActivity.java)

다음 코드를 MainActivity.java에 추가합니다. 버튼을 클릭하면 AsyncTask가 실행되어 HttpURLConnection으로 이미지 스트림을 읽어 들이고, Bitmap으로 디코딩한 후 ImageView에 표시하는 흐름입니다. 다운로드에 실패하면 Toast로 오류를 알립니다.

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.design.widget.CoordinatorLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class MainActivity extends AppCompatActivity {

    Context context;
    Activity activity;
    CoordinatorLayout coordinatorLayout;
    Button button;
    ProgressDialog mProgressDialog;
    ImageView mImageView;
    URL url;
    AsyncTask mMyTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = getApplicationContext();
        activity = MainActivity.this;
        coordinatorLayout = findViewById(R.id.coordinatorLayout);
        button = findViewById(R.id.btnDownload);
        mImageView = findViewById(R.id.imageView);

        // 다운로드 진행 상태를 표시할 다이얼로그 설정
        mProgressDialog = new ProgressDialog(activity);
        mProgressDialog.setIndeterminate(true);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        mProgressDialog.setTitle("AsyncTask");
        mProgressDialog.setMessage("Please wait, we are downloading your image file...");

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mMyTask = new DownloadTask().execute(stringToURL());
            }
        });
    }

    private class DownloadTask extends AsyncTask<URL, Void, Bitmap> {

        protected void onPreExecute() {
            mProgressDialog.show();
        }

        protected Bitmap doInBackground(URL... urls) {
            URL url = urls[0];
            HttpURLConnection connection = null;
            try {
                connection = (HttpURLConnection) url.openConnection();
                connection.connect();
                InputStream inputStream = connection.getInputStream();
                BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
                return BitmapFactory.decodeStream(bufferedInputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        // 모든 비동기 작업이 끝난 후 호출
        protected void onPostExecute(Bitmap result) {
            // 진행 다이얼로그 숨기기
            mProgressDialog.dismiss();
            if (result != null) {
                mImageView.setImageBitmap(result);
            } else {
                // 이미지 다운로드 중 오류가 발생했음을 사용자에게 알림
                Toast.makeText(MainActivity.this, "Error", Toast.LENGTH_SHORT).show();
            }
        }
    }

    protected URL stringToURL() {
        try {
            url = new URL("https://wallpapersite.com/images/pages/pic_w/6408.jpg");
            return url;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        return null;
    }
}

4단계 — 매니페스트 권한 추가 (androidManifest.xml)

인터넷 접속과 외부 저장소 접근을 위해 아래 두 가지 권한을 AndroidManifest.xml에 선언해야 합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android" package="app.com.sample">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

앱 실행 및 결과 확인

실제 Android 기기가 컴퓨터에 연결되어 있다고 가정하고 진행합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run 아이콘을 클릭하고, 옵션 목록에서 자신의 모바일 기기를 선택하세요. 그러면 기기에 앱의 기본 화면이 표시됩니다.

Android에서 지정된 URL의 이미지를 다운로드하고 저장하는 방법


Android에서 지정된 URL의 이미지를 다운로드하고 저장하는 방법

참고 사항

AsyncTask와 ProgressDialog는 최신 Android(API 30 이상)에서 공식적으로 지원 중단(deprecated)되었습니다. 실무 프로젝트에서는 Kotlin Coroutines, WorkManager 또는 Glide·Coil과 같은 이미지 로딩 라이브러리를 사용하는 것이 좋습니다. 다만 네트워크 통신과 백그라운드 처리의 기본 원리를 이해하는 데는 위 예제가 여전히 유용한 학습 자료가 됩니다.