728x90

https://link2me.tistory.com/1506 에 있는 파일 다운로드 및 실행 코드와 원리는 동일한 것도 포함되어 있으니 참고하면 도움된다.

 

전체 소스코드는 GitHUB 에 올려진 것을 참조하시라.

서버 코드와 관련된 URL, AES Key는 변경해서 올렸다.

https://github.com/jsk005/JavaProjects/tree/master/pdfviewer

 

GitHub - jsk005/JavaProjects: 자바 기능 테스트

자바 기능 테스트. Contribute to jsk005/JavaProjects development by creating an account on GitHub.

github.com

 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.link2me.android.pdfviewer">
 
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission
        android:name="android.permission.REQUEST_INSTALL_PACKAGES"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
    <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"
        android:usesCleartextTraffic="true">
        <activity
            android:name=".ui.MainActivity"
            android:exported="false" />
        <activity
            android:name=".ui.SplashActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"
                tools:replace="android:resource" />
        </provider>
    </application>
 
</manifest>
 

 

 

 

package com.link2me.android.pdfviewer.ui;
 
import android.content.Context;
import android.content.Intent;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Toast;
 
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
 
import com.link2me.android.common.BackPressHandler;
import com.link2me.android.common.Utils;
import com.link2me.android.common.Value;
import com.link2me.android.pdfviewer.R;
import com.link2me.android.pdfviewer.adapter.BindPdfViewListAdapter;
import com.link2me.android.pdfviewer.databinding.ActivityMainBinding;
import com.link2me.android.pdfviewer.model.PdfResult;
import com.link2me.android.pdfviewer.model.Pdf_Item;
import com.link2me.android.pdfviewer.network.RetrofitAdapter;
import com.link2me.android.pdfviewer.network.RetrofitService;
import com.link2me.android.pdfviewer.network.RetrofitUrl;
 
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
 
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
 
public class MainActivity extends AppCompatActivity implements BindPdfViewListAdapter.OnItemClickListener {
    private final String TAG = this.getClass().getSimpleName();
    Context mContext;
 
    private ActivityMainBinding binding;
 
    private ArrayList<Pdf_Item> pdfItemList = new ArrayList<>();
    private BindPdfViewListAdapter mAdapter;
 
    DownloadPdfFromURL downloadApk;
    private File outputFile;
 
    private BackPressHandler backPressHandler;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        View view = binding.getRoot();
        setContentView(view);
 
        backPressHandler = new BackPressHandler(this); // 뒤로 가기 버튼 이벤트
        mContext = MainActivity.this;
        initView();
    }
 
    private void initView() {
        createPdfList(); // 서버 데이터 가져오기
        buildRecyclerView();
    }
 
    private void createPdfList() {
        String keyword = Value.encryptAES(Value.URLkey());
        RetrofitService service = RetrofitAdapter.getClient().create(RetrofitService.class);
        Call<PdfResult> call = service.getPdfData(keyword,"");
        call.enqueue(new Callback<PdfResult>() {
            @Override
            public void onResponse(Call<PdfResult> call, Response<PdfResult> response) {
                if(response.body().getStatus().contains("success")){
                    pdfItemList.clear(); // 서버에서 가져온 데이터 초기화
 
                    for(Pdf_Item item: response.body().getPdfinfo()){
                        pdfItemList.add(item);
                    }
 
                    // runOnUiThread()를 호출하여 실시간 갱신한다.
                    runOnUiThread(() -> {
                        // 갱신된 데이터 내역을 어댑터에 알려줌
                        mAdapter.notifyDataSetChanged();
                    });
                } else {
                    Utils.showAlert(mContext,response.body().getStatus(),response.body().getMessage());
                }
            }
 
            @Override
            public void onFailure(Call<PdfResult> call, Throwable t) {
 
            }
        });
    }
 
    private void buildRecyclerView(){
        binding.pdfListview.setHasFixedSize(true);
        LinearLayoutManager manager = new LinearLayoutManager(mContext);
        mAdapter = new BindPdfViewListAdapter(mContext,pdfItemList); // 객체 생성
 
        DividerItemDecoration decoration = new DividerItemDecoration(mContext,manager.getOrientation());
        binding.pdfListview.addItemDecoration(decoration);
        binding.pdfListview.setLayoutManager(manager);
        binding.pdfListview.setAdapter(mAdapter);
 
        mAdapter.setOnItemSelectClickListener(this);
    }
 
    @Override
    public void onItemClicked(View view, Pdf_Item item, int position) {
//        Log.d(TAG, RetrofitUrl.BASE_URL+item.getPdfurl());
        Toast.makeText(getApplicationContext(), "잠시 기다리시면 "+item.getTitle()+" PDF 파일 열람이 가능합니다", Toast.LENGTH_LONG).show();
        String PDFUrl = RetrofitUrl.BASE_URL+item.getPdfurl();
        downloadPDF(PDFUrl);
    }
 
    private void downloadPDF(String fileUrl) {
        // 백그라운드 객체를 만들어 주어야 다운로드 취소가 제대로 동작됨
        downloadApk = new DownloadPdfFromURL();
        downloadApk.execute(fileUrl);
    }
 
    class DownloadPdfFromURL extends AsyncTask<String, Integer, String> {
 
        @Override
        protected String doInBackground(String... strings) {
            int count;
            int lenghtOfFile = 0;
            InputStream input = null;
            OutputStream fos = null;
 
            File filePath = new File(Environment.getExternalStorageDirectory() + "/download");
            outputFile = new File(filePath, "tempPDF.pdf");
            if (outputFile.exists()) { // 기존 파일 존재시 삭제하고 다운로드
                outputFile.delete();
            }
 
            try {
                URL url = new URL(strings[0]);
                URLConnection connection = url.openConnection();
                connection.connect();
 
                lenghtOfFile = connection.getContentLength(); // 파일 크기를 가져옴
 
                input = new BufferedInputStream(url.openStream());
                fos = new FileOutputStream(outputFile);
                byte data[] = new byte[1024];
                long total = 0;
 
                while ((count = input.read(data)) != -1) {
                    if (isCancelled()) {
                        input.close();
                    }
                    total = total + count;
                    if (lenghtOfFile > 0) { // 파일 총 크기가 0 보다 크면
                        publishProgress((int) (total * 100 / lenghtOfFile));
                    }
                    fos.write(data, 0, count); // 파일에 데이터를 기록
                }
 
                fos.flush();
 
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (input != null) {
                    try {
                        input.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }
 
        protected void onPostExecute(String result) {
            if (result == null) {
                // 미디어 스캐닝
                MediaScannerConnection.scanFile(getApplicationContext(), new String[]{outputFile.getAbsolutePath()}, nullnew MediaScannerConnection.OnScanCompletedListener() {
                    @Override
                    public void onScanCompleted(String s, Uri uri) {
 
                    }
                });
 
                // 다운로드한 파일 실행하여 업그레이드 진행하는 코드
                if (Build.VERSION.SDK_INT >= 24) {
                    openPDF(outputFile);
                } else {
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    Uri apkUri = Uri.fromFile(outputFile);
                    intent.setDataAndType(apkUri, "application/pdf");
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    getApplicationContext().startActivity(intent);
                }
 
            } else {
                Toast.makeText(getApplicationContext(), "다운로드 에러", Toast.LENGTH_LONG).show();
            }
        }
    }
 
    void openPDF(File file) {
        Uri fileUri = FileProvider.getUriForFile(mContext, mContext.getApplicationContext().getPackageName() + ".fileprovider",file);
 
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(fileUri, "application/pdf");
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        try {
            startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    @Override
    public void onBackPressed() {
        backPressHandler.onBackPressed();
    }
}
 

 

 

728x90

'안드로이드 > Android 활용' 카테고리의 다른 글

Android APP(Java)에서 PHP Session 저장 및 사용  (0) 2023.12.23
WebView assets html 파일 읽기  (0) 2020.11.27
Android TextToSpeech  (0) 2020.09.30
Intent 이메일 전송하기  (0) 2020.09.08
Profile 이미지 처리  (0) 2020.09.01
블로그 이미지

Link2Me

,