I am using RxAndroid ,Retrofit and SqlBrite .
POJO Classes:
Eg : file_path = "....../videos/.mp4"
public class VideoResponse {
@SerializedName("files")
@Expose
private List<VideoFiles> files = null;
.....
}
public class VideoFiles {
@SerializedName("file_path")
@Expose
private String remotePath;
private String localPath;
.....
}
Passing the list to setLocalPath
from the apiService.
@Inject
public RemoteDataSource(ApiService service,DownloadUtils downloadUtils) {
this.service = service;
this.downloadUtils = downloadUtils;
}
@Override
public Observable<List<VideoResponse>> getVideoResponse() {
return service.getVideoResponseFromServer()
.compose(RxUtils.applySchedulers())
==> .map(this::setVideoLocalPath)
.doOnSubscribe(disposable -> Timber.d("*** Video Sync Started....."))
.doOnError(throwable -> Timber.d("*** Video Sync Failed ...."))
.doOnComplete(() -> Timber.d(" *** Video Sync Complete...."));
}
Passing every remote Path to DownloadUtils and get back the altered List of VideoResponse.
private List<VideoResponse> setVideoLocalPath(List<VideoResponse> videoResponses) {
for (VideoResponse r : videoResponses) {
for (VideoFiles file : r.getFiles()) {
downloadUtils.downloadVideoFromInternet(file, service);
}
}
return videoResponses;
}
Downloading and Setting the Local Path ;
public class DownloadUtils {
public void downloadVideoFromInternet(VideoFiles video, ApiService service) {
service.downloadFileByUrl(video.getRemotePath())
.flatMap(processResponse("video", video.getFileTitle()))
.subscribe(handleVideoResult(video));
}
private Observer<? super File> handleVideoResult(VideoFiles video) {
return new Observer<File>() {
@Override
public void onSubscribe(Disposable d) {
Timber.i("*** Download File OnSubscribe ***");
}
@Override
public void onNext(File file) {
Timber.d(" $$$$ Video File Path $$$ -> %s", file.getAbsolutePath());
video.setLocalPath(file.getAbsolutePath());
}
@Override
public void onError(Throwable e) {
Timber.e(e);
}
@Override
public void onComplete() {
Timber.i("*** Download File Completed ****");
}
};
}
private Function<Response<ResponseBody>, Observable<File>> processResponse(String folderName, String fileTitle) {
return response -> saveToDisk(response, folderName, fileTitle);
}
private Observable<File> saveToDisk(Response<ResponseBody> response, String fileTitle, String folderName) {
return Observable.create(subscriber -> {
try {
File file = new File("/data/aster/" + folderName + fileTitle);
if (!file.exists()) {
file.mkdirs();
}
BufferedSink bufferedSink = Okio.buffer(Okio.sink(file));
bufferedSink.writeAll(response.body().source());
bufferedSink.close();
subscriber.onNext(file);
subscriber.onComplete();
} catch (IOException e) {
e.printStackTrace();
subscriber.onError(e);
}
});
}
}
The problem is the video files are not getting downloaded and each one stops at on subscribe.
After passing values to setLocalVideoPath
, the downloads are not getting finished and i get NetworkOnMainThreadException
and the app crashes..Is there a better way to implement this logic..!!Kindly help.