Android Volley RxJava - Multiple Requests - java

I have something like that:
public void function sendPhotosAndSave (ArrayList<Photo> photos) {
// Iterate through all photos
// Send a POST request using volley for each photo
// Alert when all photos sended
// ????
.subscribe(new Subscriber<Boolean>() {
#Override
public void onCompleted() {
// Save
}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(Boolean aBoolean) {
}
});
}
I need to send all photos (Multipart/POST) and then send a save request.
How do i iterate the photos requests using RxJava and known when it's done?

You can do something like this:
public void sendPhotosAndSave(List<Photo> photos) {
Observable.from(photos)
.flatMap(photo -> sendRequest(photo).subscribeOn(Schedulers.io()))
.subscribe(new Subscriber<Boolean>() {
#Override
public void onCompleted() {
// Save
}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(Boolean aBoolean) {
}
});
}
private Observable<Boolean> sendRequest(Photo photo) {
return Observable.just(/*your request logic*/);
}

Related

Firebase ML kit's QR Code Scanner Scans each QR Code Multiple Times

My scanner scans single QR Code multiple times thats why my createDialog method runs multiple time where i get the info regarding QR code and the user who is using it and the agent who posted it and store data into users node in Db and because it run multiple time my Db cant keep track of the no. of times the qr code scanned for each user..
private void setupCamera() {
startAgain.setEnabled(isDetected);
startAgain.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
isDetected = !isDetected;
}
});
cameraView.setLifecycleOwner(this);
cameraView.addFrameProcessor(new FrameProcessor() {
#Override
public void process(#NonNull Frame frame) {
processorImage((FirebaseVisionImage) getVisionImageFromFrame(frame));
}
});
options = new FirebaseVisionBarcodeDetectorOptions.Builder()
.setBarcodeFormats(FirebaseVisionBarcode.FORMAT_QR_CODE)
.build();
detector = FirebaseVision.getInstance().getVisionBarcodeDetector(options);
}
private Object getVisionImageFromFrame(Frame frame) {
byte[] data = frame.getData();
FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
.setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
.setHeight(frame.getSize().getHeight())
.setWidth(frame.getSize().getWidth())
.build();
return FirebaseVisionImage.fromByteArray(data, metadata);
}
private void processorImage(FirebaseVisionImage image) {
if (!isDetected) {
detector.detectInImage(image)
.addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionBarcode>>() {
#Override
public void onSuccess(List<FirebaseVisionBarcode> firebaseVisionBarcodes) {
processResult(firebaseVisionBarcodes);
}
}).addOnCompleteListener(new OnCompleteListener<List<FirebaseVisionBarcode>>() {
#Override
public void onComplete(#NonNull Task<List<FirebaseVisionBarcode>> task) {
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(StoreScanQR.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
private void processResult(List<FirebaseVisionBarcode> firebaseVisionBarcodes) {
if (firebaseVisionBarcodes.size() > 0) {
isDetected = true;
startAgain.setEnabled(isDetected);
for (FirebaseVisionBarcode item : firebaseVisionBarcodes) {
try {
createDialog(item.getRawValue());
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
Detection is an asynchronous call, so it may be triggered multiple times with different inputs before you can get the first result. If you only care about the first detected result, you can check your isDetected flag at the result processing side (i.e. in #onSuccess callback) rather than detection triggering side.
#Override
public void onSuccess(List<FirebaseVisionBarcode> firebaseVisionBarcodes) {
if (!isDetected) {
processResult(firebaseVisionBarcodes);
}
}

How to resume download file using PRDownloader in android?

i have a recycler view and i want to control of downloading using buttons in my card view.
i use PRDownloader library but i have issue i can't resume download after finish the app and open it again it start the download not resume it.
my code as below
holder.downloadResumeOrPlayBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
downLoadID = PRDownloader.download(remoteLink, myLocalDirectory,
fileName)
.build()
.setOnStartOrResumeListener(new OnStartOrResumeListener() {
#Override
public void onStartOrResume() {
holder.pauseDownloadBtn.setVisibility(View.VISIBLE);
holder.cancelBtn.setVisibility(View.VISIBLE);
holder.downloadResumeOrPlayBtn.setVisibility(View.GONE);
notifyDataSetChanged();
}
})
.setOnPauseListener(new OnPauseListener() {
#Override
public void onPause() {
holder.pauseDownloadBtn.setText(mContext.getResources().getString(string.resume_text_btn));
holder.downloadResumeOrPlayBtn.setVisibility(View.GONE);
holder.pauseDownloadBtn.setVisibility(View.VISIBLE);
holder.cancelBtn.setVisibility(View.GONE);
notifyDataSetChanged();
}
})
.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel() {
holder.mProgressBar.setProgress(0);
holder.downloadResumeOrPlayBtn.setText(mContext.getResources().getString(R.string.download_text));
holder.downloadResumeOrPlayBtn.setVisibility(View.VISIBLE);
holder.pauseDownloadBtn.setVisibility(View.GONE);
holder.cancelBtn.setVisibility(View.GONE);
notifyDataSetChanged();
}
})
.setOnProgressListener(new OnProgressListener() {
#Override
public void onProgress(Progress progress) {
video.setVideoProgress(progress.currentBytes * 100 / progress.totalBytes);
Log.i("videosAdapter", video.getVideoProgress() + "");
holder.mProgressBar.setProgress((int) video.getVideoProgress());
holder.mProgressBar.setVisibility(View.VISIBLE);
notifyDataSetChanged();
}
})
.start(new OnDownloadListener() {
#Override
public void onDownloadComplete() {
System.out.println("download completed");
holder.downloadResumeOrPlayBtn.setText(mContext.getResources().getString(string.play_video_text));
holder.downloadResumeOrPlayBtn.setVisibility(View.VISIBLE);
holder.pauseDownloadBtn.setVisibility(View.GONE);
holder.cancelBtn.setVisibility(View.GONE);
notifyDataSetChanged();
}
#Override
public void onError(Error error) {
holder.downloadResumeOrPlayBtn.setText(mContext.getResources().getString(string.download_text));
Toast.makeText(mContext, error.getServerErrorMessage(), Toast.LENGTH_SHORT).show();
holder.mProgressBar.setProgress(0);
}
});
}
if(holder.downloadResumeOrPlayBtn.getText().toString().equals(mContext.getResources().getString(string.resume_text_btn)))
{
PRDownloader.resume(downLoadID);
}
});
my question is how to resume the download without downloading the file from the start and if there is another library to use how can i make it.

SwipeRefresh layout progress bar is not hiding even after completion

I am using MVVM pattern in which I am using SwipeRefresh layout to refresh recycler view in my layout.When I am pulling it then it continue to refresh even after method completed successfully.
Below is my code:
MainActivity.java
refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
userRepository.getUserList();
}
});
UserRepository.java
public void getUserList(){
Retrofit retrofit = RetrofitClient.getInstance();
ApiService apiService = retrofit.create(ApiService.class);
Call<List<User>> userList = apiService.getUser();
userList.enqueue(new Callback<List<User>>() {
#Override
public void onResponse(Call<List<User>> call, final Response<List<User>> response) {
Completable.fromAction(new Action() {
#Override
public void run() throws Exception {
if(response.body() != null) {
List<User> list = response.body();
for (int i = 0; i < list.size(); i++) {
String id = list.get(i).get_id();
String names = list.get(i).getName();
String age = list.get(i).getAge();
User user = new User(id,names,age);
userDb.userDao().Insert(user);
}
}
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onComplete() {
Toast.makeText(context,"Data inserted",Toast.LENGTH_SHORT).show();
}
#Override
public void onError(Throwable e) {
Toast.makeText(context,e.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onFailure(Call<List<User>> call, Throwable t) {
Toast.makeText(context,t.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
Method fetching list is in another class UserRepository and I am calling method in another activity MainActivity.I am not getting any way how can I stop refreshing process.Someone please let me know a way to stop refreshing process.
Any help would be appreciated.
THANKS
To disable the progress dialog add this,
swipeLayout.setRefreshing(false);

How to get play and stop event callback from chromecast android

I want to get callback event and perform some function when chromecast audio change there playback mode(play/stop)
How can I get the play/stop event to the application so I will do my work on that event.
Please check below logic I have implemented.
private void setupCastListener() {
mSessionManagerListener = new SessionManagerListener<CastSession>() {
#Override
public void onSessionEnded(CastSession session, int error) {
onApplicationDisconnected();
}
#Override
public void onSessionResumed(CastSession session, boolean wasSuspended) {
onApplicationConnected(session);
}
#Override
public void onSessionResumeFailed(CastSession session, int error) {
onApplicationDisconnected();
}
#Override
public void onSessionStarted(CastSession session, String sessionId) {
onApplicationConnected(session);
}
#Override
public void onSessionStartFailed(CastSession session, int error) {
onApplicationDisconnected();
}
#Override
public void onSessionStarting(CastSession session) {
}
#Override
public void onSessionEnding(CastSession session) {
}
#Override
public void onSessionResuming(CastSession session, String sessionId) {
if(mCastSession!=null && isChromeCastConnected){
try {
if (session.isMute()) {
mStopPlayButton.setImageResource(R.drawable.ic_play);
isChromeCastPlay = false;
//mCastSession.setMute(!mCastSession.isMute());
} else {
mStopPlayButton.setImageResource(R.drawable.ic_stop);
isChromeCastPlay = true;
//mCastSession.setMute(!mCastSession.isMute());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onSessionSuspended(CastSession session, int reason) {
}
};
}
Please let me know. thanks
You need to read this documentation, and focus on RemoteMediaClient and the Listener interface there. The callback onStatusUpdated() will be called when there is a change in the playback status. Tutorials available on the first link above is very informative, so make sure you read about things there.
Finally I found the remote media play and pause mode call back by below MediaControlIntent.
Remote Playback Routes
mMediaRouter = MediaRouter.getInstance(this);
mSelector = new MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.build();

Rx Java zip completes when any subject completes

I am facing with the problem. As far as I know zip method from RxJava waits for all observables to complete.
But am I getting another behaviour.
Here is my code snippet
private PublishSubject<Void> firstSubject;
private PublishSubject<Void> secondSubject;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadData();
mDrawerHeaderView.postDelayed(new Runnable() {
#Override
public void run() {
// getSecondSubject().onNext(null);
}
}, 1000);
mDrawerHeaderView.postDelayed(new Runnable() {
#Override
public void run() {
getFirstSubject().onCompleted();
}
}, 1000);
}
protected PublishSubject<Void> createFirstSubject() {
firstSubject = PublishSubject.create();
return firstSubject;
}
protected PublishSubject<Void> createSecondSubject() {
secondSubject = PublishSubject.create();
return secondSubject;
}
protected PublishSubject<Void> getFirstSubject() {
return firstSubject;
}
protected PublishSubject<Void> getSecondSubject() {
return secondSubject;
}
private void loadData() {
Observable<Void> firstSubject = createFirstSubject();
Observable<Void> secondSubject = createSecondSubject();
Observable<Boolean> allDataTask = Observable.zip(firstSubject, secondSubject, new Func2<Void, Void, Boolean>() {
#Override
public Boolean call(Void aVoid, Void aVoid2) {
return true;
}
});
allDataTask
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Boolean>() {
#Override
public void onCompleted() {
Notifications.showSuccessMessage(getApplicationContext(), "COMPLETE");
}
#Override
public void onError(Throwable e) {
Notifications.showErrorMessage(getApplicationContext(), "ERROR");
}
#Override
public void onNext(Boolean aBoolean) {
Notifications.showSuccessMessage(getApplicationContext(), "NEXT");
}
});
}
In this case I got COMPLETE message, but I was expecting to get nothing because the second subject is not completed.
What I am doing wrong ?
Please help me to get desired behaviour.
Yes, it works as expected. It makes perfect sense to receive the onCompleted() here, because if one stream is done, as long as all the elements it emitted are "zipped", there's no way to "zip" anything more, so it's "completed". You can also play with the sequence here.

Categories