728x90
RxAndroid and Retrofit 를 활용하여 파일을 다운로드하고 PDF Viewer 처리하는 코드 예제이다.
build.gradle:
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" // 코틀린 혼용 사용을 위해 추가
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.4.0'
implementation 'com.squareup.okhttp3:okhttp-urlconnection:4.9.0'
// ReactiveX : Observable에서 보낸 이벤트를 Operator에서 가공하고 Subscribe에서 받는 것
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.1.5'
implementation "com.github.akarnokd:rxjava3-retrofit-adapter:3.0.0"
}
|
RetrofitService.java:
import io.reactivex.rxjava3.core.Observable;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Streaming;
import retrofit2.http.Url;
public interface RetrofitService {
// POST 방식으로 데이터를 주고 받을 때 넘기는 변수는 Field 라고 해야 한다.
@FormUrlEncoded
@POST(RetrofitUrl.PdfData)
Call<PdfResult> getPdfData(
@Field("keyword") String keyword,
@Field("search") String search
);
@Streaming
@GET
Observable<Response<ResponseBody>> downloadFile(@Url String fileUrl);
}
|
RetrofitAdapter.java:
import hu.akarnokd.rxjava3.retrofit.RxJava3CallAdapterFactory;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitAdapter {
static Retrofit retrofit = null;
static Retrofit retrofit_service = null;
public static Retrofit getClient() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(RetrofitUrl.BASE_URL)
.client(createOkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
public static OkHttpClient createOkHttpClient() {
// 네트워크 통신 로그(서버로 보내는 파라미터 및 받는 파라미터) 보기
OkHttpClient.Builder builder = new OkHttpClient.Builder();
//builder.cookieJar(new RetrofitCookieJar()); // Session 통신을 위한 기능
// 네트워크 통신 로그(서버로 보내는 파라미터 및 받는 파라미터) 보기
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(httpLoggingInterceptor);
builder.connectTimeout(15, TimeUnit.SECONDS);
builder.readTimeout(20, TimeUnit.SECONDS);
builder.writeTimeout(20, TimeUnit.SECONDS);
builder.retryOnConnectionFailure(true);
return builder.build();
}
public static <T> T createService(Class<T> serviceClass) {
// implementation "com.github.akarnokd:rxjava3-retrofit-adapter:3.0.0"
if (retrofit_service == null) {
retrofit_service = new Retrofit.Builder()
.baseUrl(RetrofitUrl.BASE_URL)
.client(createOkHttpClient())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create()).build();
}
return retrofit_service.create(serviceClass);
}
}
|
RetrofitUrl.java:
public class RetrofitUrl {
public static final String BASE_URL = "http://www.abc.com/";
public static final String PdfData = "androidSample/getPDFData.php";
}
|
MainActivity.java:
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableEmitter;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;
import okhttp3.ResponseBody;
import okio.BufferedSink;
import okio.Okio;
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;
@Override
public void onItemClicked(View view, Pdf_Item item, int position) {
Toast.makeText(getApplicationContext(), "잠시 기다리시면 "+item.getTitle()+" PDF 파일 열람이 가능합니다", Toast.LENGTH_LONG).show();
String PDFUrl = RetrofitUrl.BASE_URL+item.getPdfurl();
downloadPDFFile(item.getPdfurl());
}
public void downloadPDFFile(String fileUrl) {
RetrofitService downloadService = RetrofitAdapter.createService(RetrofitService.class);
downloadService.downloadFile(fileUrl)
.flatMap(processResponse())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(handleResult());
}
public Function<Response<ResponseBody>, Observable<File>> processResponse(){
return new Function<Response<ResponseBody>, Observable<File>>() {
@Override
public Observable<File> apply(Response<ResponseBody> responseBodyResponse) throws Exception {
return saveToDiskRx(responseBodyResponse);
}
};
}
private Observable<File> saveToDiskRx(final Response<ResponseBody> response){
return Observable.create(new ObservableOnSubscribe<File>() {
@Override
public void subscribe(@NonNull ObservableEmitter<File> subscriber) throws Throwable {
File filePath = new File(Environment.getExternalStorageDirectory() + "/download");
File outputFile = new File(filePath, "tempPDF.pdf");
if (outputFile.exists()) { // 기존 파일 존재시 삭제하고 다운로드
outputFile.delete();
}
BufferedSink bufferedSink = Okio.buffer(Okio.sink(outputFile));
bufferedSink.writeAll(response.body().source());
bufferedSink.close();
subscriber.onNext(outputFile);
subscriber.onComplete();
}
});
}
private Observer<File> handleResult() {
return new Observer<File>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.d(TAG, "OnSubscribe");
}
@Override
public void onNext(@NonNull File file) {
Log.d(TAG, "File downloaded to " + file.getAbsolutePath());
// 다운로드한 파일 실행하여 PDF 보기 진행하는 코드
if (Build.VERSION.SDK_INT >= 24) {
openPDF(file);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri apkUri = Uri.fromFile(file);
intent.setDataAndType(apkUri, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);
}
}
@Override
public void onError(@NonNull Throwable e) {
e.printStackTrace();
Log.d(TAG, "Error " + e.getMessage());
}
@Override
public void onComplete() {
Log.d(TAG, "onCompleted");
}
};
}
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();
}
}
}
|
전체 소스코드
https://github.com/jsk005/JavaProjects/tree/master/pdfviewer
참고자료
https://www.codexpedia.com/android/retrofit-2-and-rxjava-for-file-downloading-in-android/
이 자료는 참고하지 않았지만 나중에 보면 도움되는 것이 있을 수도 있겠다 싶어 URL를 적어둔다.
https://www.digitalocean.com/community/tutorials/android-rxjava-retrofit
728x90
'안드로이드 > Android Data 통신' 카테고리의 다른 글
Login with Retrofit using MVVM in Java (0) | 2022.08.08 |
---|---|
안드로이드 연동 로그인 PHP JSON 예제 (0) | 2020.09.08 |
Retrofit2 자바 -> 코틀린 변환 (0) | 2020.07.25 |
Retrofit2 ArrayList 데이터 처리 (0) | 2020.07.14 |
Volley 라이브러리 + Gson 라이브러리 변경 실습 (0) | 2020.07.12 |