Skip to content

Instantly share code, notes, and snippets.

@EugeneShapovalov94
Created May 30, 2017 15:33
Show Gist options
  • Save EugeneShapovalov94/b0ed9e65805e7e92216ef2619233fbd6 to your computer and use it in GitHub Desktop.
Save EugeneShapovalov94/b0ed9e65805e7e92216ef2619233fbd6 to your computer and use it in GitHub Desktop.
@Override
public Observable<UploadResponseBody> uploadFile(
@android.support.annotation.NonNull final ArrayList<UploadVaultFile> files) {
if (files.size() == 1 && files.get(0).getFilePath() == null) {
return mFileRepository.getFileUriForUpload()
.flatMap(new Function<String, ObservableSource<UploadResponseBody>>() {
@Override
public ObservableSource<UploadResponseBody> apply(@NonNull String s) throws Exception {
files.get(0).setFilePath(s);
return mUploadRepository.uploadVaultFiles(files);
}
});
} else {
return mUploadRepository.uploadVaultFiles(files);
}
}
private void uploadFile(ArrayList<UploadVaultFile> uploadList) {
mView.showLoading(true);
final Disposable disposable = mInteractor.uploadFile(uploadList)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<UploadResponseBody>() {
@Override
public void onNext(@io.reactivex.annotations.NonNull UploadResponseBody responseBody) {
// TODO remove toast
Toast.makeText(mView.context(), "Progress = " + responseBody.getProgress(), Toast.LENGTH_SHORT).show();
}
@Override
public void onError(@io.reactivex.annotations.NonNull Throwable throwable) {
mView.hideLoading(true);
mView.showErrorMessage(((DefaultException) throwable).getDetails());
updateFilesInFolder();
deleteTempFilesFromFolder();
}
@Override
public void onComplete() {
mView.hideLoading(true);
updateFilesInFolder();
deleteTempFilesFromFolder();
}
});
mCompositeDisposable.add(disposable);
}
public class UploadRepositoryImpl extends BaseHttpRepository implements UploadRepository {
private volatile UploadService mUploadService;
private volatile boolean isUploadServiceBound;
public UploadRepositoryImpl(Context context, AuthHolder authHolder, ExceptionMapper exceptionMapper) {
super(context, authHolder, exceptionMapper);
}
@Override
public Observable<UploadResponseBody> uploadVaultFiles(@NonNull final ArrayList<UploadVaultFile> files) {
for (UploadVaultFile file : files) {
file.setRelationId(mAuthHolder.getRelationshipId());
}
return Observable.create(new ObservableOnSubscribe<UploadResponseBody>() {
@Override
public void subscribe(@io.reactivex.annotations.NonNull
final ObservableEmitter<UploadResponseBody> emitter) throws Exception {
final Intent intent = new Intent(mContext, UploadService.class);
mContext.bindService(intent, mUploadConnection, Context.BIND_AUTO_CREATE);
while (!isUploadServiceBound) {
Thread.sleep(10);
}
mUploadService.setUploadFiles(files);
Observable<UploadResponseBody> observable = mUploadService.getObservable();
observable.subscribeWith(new DisposableObserver<UploadResponseBody>() {
@Override
public void onNext(@io.reactivex.annotations.NonNull UploadResponseBody responseBody) {
emitter.onNext(responseBody);
}
@Override
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
emitter.onError(e);
unbindService();
}
@Override
public void onComplete() {
emitter.onComplete();
unbindService();
}
});
}
}).onErrorResumeNext(new Function<Throwable, ObservableSource<? extends UploadResponseBody>>() {
@Override
public ObservableSource<? extends UploadResponseBody> apply(@io.reactivex.annotations.NonNull Throwable throwable) throws Exception {
return handleHttpError(throwable);
}
});
}
private void unbindService() {
if (isUploadServiceBound) {
isUploadServiceBound = false;
mContext.unbindService(mUploadConnection);
}
}
private ServiceConnection mUploadConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
UploadBinder binder = (UploadBinder) service;
mUploadService = binder.getService();
isUploadServiceBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
isUploadServiceBound = false;
}
};
}
public class UploadService extends Service {
// ===========================================================
// Constants
// ===========================================================
private static final String TAG = UploadService.class.getSimpleName();
// ===========================================================
// Fields
// ===========================================================
@Inject
UploadApi mApi;
private final IBinder mBinder;
private final CompositeDisposable mCompositeDisposable;
private final Handler mHandler;
private final HandlerThread mHandlerThread;
private ObservableEmitter<UploadResponseBody> mObservableEmitter;
private Observable<UploadResponseBody> mObservable;
// ===========================================================
// Constructors
// ===========================================================
public UploadService() {
mCompositeDisposable = new CompositeDisposable();
mHandlerThread = new HandlerThread(TAG);
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mBinder = new UploadBinder();
mObservable = Observable.create(
new ObservableOnSubscribe<UploadResponseBody>() {
@Override
public void subscribe(@NonNull ObservableEmitter<UploadResponseBody> e) throws Exception {
mObservableEmitter = e;
}
});
mObservable.subscribe();
}
// ===========================================================
// Getter & Setter
// ===========================================================
public Observable<UploadResponseBody> getObservable() {
return mObservable;
}
public void setUploadFiles(@android.support.annotation.NonNull final ArrayList<UploadVaultFile> files) {
mHandler.post(new Runnable() {
@Override
public void run() {
for (UploadVaultFile file : files) {
uploadSingleFile(file);
}
}
});
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public void onCreate() {
super.onCreate();
((AOApplication) getApplication()).getApplicationComponent()
.plusUploadComponent()
.inject(this);
}
@Nullable
@Override
public IBinder onBind(final Intent intent) {
return mBinder;
}
@Override
public void onDestroy() {
super.onDestroy();
mCompositeDisposable.clear();
mHandlerThread.quit();
}
@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
private void uploadSingleFile(UploadVaultFile file) {
final File temp = new File(file.getFilePath());
final UploadResponseBody responseBody =
new UploadResponseBody(file.getPosition(), temp.getName());
final ProgressRequestBody progressBody = new ProgressRequestBody(
createUploadObject(file, temp), responseBody, mObservableEmitter);
final Disposable disposable = mApi.uploadFile(progressBody)
.subscribeOn(Schedulers.io())
.subscribeWith(new DisposableObserver<ResponseBody>() {
@Override
public void onNext(@io.reactivex.annotations.NonNull ResponseBody responseBody) {
}
@Override
public void onError(@io.reactivex.annotations.NonNull Throwable e) {
mObservableEmitter.onError(e);
stopServiceIfNoUploads(this);
}
@Override
public void onComplete() {
responseBody.setCompleted(true);
responseBody.setProgress(100);
mObservableEmitter.onNext(responseBody);
stopServiceIfNoUploads(this);
}
});
mCompositeDisposable.add(disposable);
}
private RequestBody createUploadObject(UploadVaultFile uploadVaultFile, File file) {
final RequestBody requestFile = RequestBody.create(MediaType.parse(
MimeTypeResolver.getInstance()
.resolveMimeType(file.getName(), "F").getNativeMimeType()), file);
MultipartBody.Part body =
MultipartBody.Part.createFormData("UploadFileInd", file.getName(), requestFile);
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("AuthToken", PrefsUtils.getUserAuthToken());
builder.addFormDataPart("UserName", PrefsUtils.getSystemUserName());
builder.addFormDataPart("RelationId", uploadVaultFile.getRelationId());
if (uploadVaultFile.getFolderId() != null) {
builder.addFormDataPart("FolderId", uploadVaultFile.getFolderId());
}
builder.addPart(body);
return builder.build();
}
private void stopServiceIfNoUploads(Disposable dispose) {
mCompositeDisposable.remove(dispose);
if (mCompositeDisposable.size() == 0) {
mObservableEmitter.onComplete();
stopSelf();
}
}
public class UploadBinder extends Binder {
public UploadService getService() {
return UploadService.this;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment