show notification after completable future succeed - java

I've got a method called showNotification that shows notification
public static void showNotification(UI ui, String notificationMessage) {
Notification notification = new Notification(notificationMessage);
notification.setStyleName("custom-notification");
notification.show(ui.getPage());
}
And I've got a service that returns CompletableFuture.
In my controller I created method
#Override
public CompletableFuture<?> startProcessing() {
return processorService.start();
}
And on button click I want to show notification if start was successful.
My buttonClick event looks like this
event -> {
controller.startProcessing()
.thenAccept(aVoid -> UI.getCurrent().access(() -> {
showNotification(getUI(), "Started processing");
})
).handle((aVoid, throwable) -> {
showNotification(getUI(), "Failed to start processing");
return aVoid;
});
}
The problem is that until I invoke another event - like for example click on another button - it doesn't show notification.
What is the problem?

You need to add #Push to your UI subclass to make the browser open a two-directional connection with the server. Without that, only the browser can initiate communication, and it only does that when there's some new event to send to the server.

Related

Google ad click is not opening the external web browser

I am trying to implement the ad in my app with Custom Native Ad Format - https://developers.google.com/ad-manager/mobile-ads-sdk/android/native/custom-formats#java_1
So, according to the documentation I am going with the approach described there and creating the ad
...
private void setListeners() {
...
imageView.setOnClickListener(v -> {
nativeCustomFormatAd.performClick("IMAGE");
});
...
}
private NativeCustomFormatAd nativeCustomFormatAd;
AdLoader adLoader = new AdLoader.Builder(context, "/6499/example/native")
.forCustomFormatAd("10063170",
new NativeCustomFormatAd.OnCustomFormatAdLoadedListener() {
#Override
public void onCustomFormatAdLoaded(NativeCustomFormatAd ad) {
// Show the custom format and record an impression.
nativeCustomFormatAd = ad;
Drawable drawable = vm.nativeCustomFormatAd.getImage("IMAGE").getDrawable();
imageView.setDrawable(drawable);
}
},
new NativeCustomFormatAd.OnCustomClickListener() {
#Override
public void onCustomClick(NativeCustomFormatAd ad, String s) {
// Handle the click action
}
})
.withAdListener( ... )
.withNativeAdOptions( ... )
.build();
#SuppressLint("VisibleForTests")
AdManagerAdRequest adManagerAdRequest = new AdManagerAdRequest.Builder().build();
adLoader.loadAd(adManagerAdRequest);
...
So, it looks pretty simple I try to make a request for the ad then I got (in a callback) NativeCustomFormatAd, save it as a class member, and along with it get drawable and set it to the imageView (to present it in the UI). Once a user clicks on the imageView I get an event in the click listener and invoke nativeCustomFormatAd.performClick("IMAGE");.
The problem is that I expect that once I transfer the ad click to the SDK (by nativeCustomFormatAd.performClick("IMAGE");) SDK is supposed to open the external browser, but instead nothing happens.
P.S. I am sure that nativeCustomFormatAd.performClick("IMAGE"); getting invoked and also I see that SDK gets the click as I got a callback event here:
...
new NativeCustomFormatAd.OnCustomClickListener() {
#Override
public void onCustomClick(NativeCustomFormatAd ad, String s) {
// Handle the click action
}
})
...
What am I missing here?
According to the docs you linked:
When a click is performed on a custom format ad, there are three possible responses from the SDK, attempted in this order:
Invoke the OnCustomClickListener from AdLoader, if one was provided.
For each of the ad's deep link URLs, attempt to locate a content resolver and start the first one that resolves.
Open a browser and navigate to the ad's traditional Destination URL.
Also:
If you pass a listener object in, the SDK instead invokes its onCustomClick method and takes no further action.
Therefore, it seems you have to pass a null OnCustomClickListener.

Is there a way to handle button clicks from Backendless push notification in code and how to do it?

I'm building android application with push notifications using Backendless as backend. I encountered a problem with handling buttons. I know that I can push notification with template(from Backendless Console) and there is an option to handle clicks, but I wonder if there is an option to do it all in code, not with template?
I have also searched for similar questions but everything I found was old and deprecated.
I use this function to push notification but I don't know how to set buttons and how to handle button clicks.
public static void sendPushNotification(String channel, String message, String header,
List<String> devices) {
DeliveryOptions deliveryOptions = new DeliveryOptions();
deliveryOptions.setPushSinglecast(devices);
PublishOptions publishOptions = new PublishOptions();
publishOptions.putHeader("android-ticker-text", header);
publishOptions.putHeader("android-content-title", header);
publishOptions.putHeader("android-content-text", message);
Backendless.Messaging.publish(channel, message, publishOptions, deliveryOptions,
new AsyncCallback<MessageStatus>() {
#Override
public void handleResponse(MessageStatus response) {
}
#Override
public void handleFault(BackendlessFault fault) {
}
});
}
Solution :
https://support.backendless.com/t/customise-push-notification/10863/20
I finally found answer, if you had similar problem please go here and check:
https://support.backendless.com/t/customise-push-notification/10863/20

How to manage push notification for chat app using FCM

I'm building a chat app that pushes notification like facebook, Instagram.
when a user sends message notification will show automatically. The problem is I don't know how to handle background service.
For example, when the same user sends the message, a notification will append the message like this:
But when FCM send notification this is what happened:
I need to be able to handle background service
Here is my code
public class FirebaseInstaceService extends FirebaseMessagingService {
FirebaseToken firebaseToken = new FirebaseToken();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
#Override
public void onNewToken(String s) {
super.onNewToken(s);
Log.d("NewToken","New token: " +s);
if (user != null){
firebaseToken.sendToken(s, new OncompleteCallback() {
#Override
public void callback() {
Log.d("NewToken","Send complete");
}
});
}
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
try {
Log.d("CloudMessage",remoteMessage.getNotification().getBody());
}catch (Exception e){
Log.d("CloudMessage",e.toString());
throw e;
}
}
}
If I understand your question correctly, you need to do work on the non UI thread when a push notification is received. In that case, you're in luck - as explained here, onReceive() is called on a non-UI thread.
You just create and show Notifications as you see fit, storing the notification ID uniquely to allow user->notification mapping. That way, you can access the notification shown when the same user sends another message.

How I can control flow of execution in GWT?

If you have ever used Window.alert("msg"); API in GWT to show popup, I am not sure but the call to this API pauses the code execution until a user action is taken (cliking the ok button), Simillar to that i have created a custom popup, when it is shown i don't want the code to execute further till any user input in received on the popup, How can i pause the code execution further?
Assume :-
//Some Code
MY Popup (Here i want to wait till a user action is received.)
//Some code
I read somewhere to use Synchronized key word but that didn't work either,Do you have answer to this. How GWT compiler sees "Synchronized" keyword does it ignores the keyword?
Create something like a ConfirmCallBack that you fire when the "OK" button (or whatever) is clicked in the popuppanel.
//method in your own popup class
public static void confirm(String message, ConfirmCallBack confirmCallBack)
{
Button confirmButton = new Button(confirmButtonText, event ->
{
confirmCallBack.callback(true);
//hide popup
});
}
Than also have the ConfirmCallBack interface like
public interface ConfirmCallBack
{
void callback(boolean result);
}
Then call your own popup like
MyPopup.confirm("Hello world", result ->
{
if (result)
{
//my code to be executed after clicking the ok button
}
}

Does my Retrofit/ReactiveX method actually retrieve data asynchronously?

swipeRefreshLayout.setOnRefreshListener(() -> {
swipeRefreshLayout.setRefreshing(true);
retrieveData(mCardAdapter, db);
});
For some reason the following method is blocking my main UI thread, but it should be running in the background. For example, the refresh indicator hangs when I run retrieveData(). If I initialize a progress dialog before running, it also hangs and I can't scroll through my RecyclerView. Am I fundamentally misunderstanding something here?
public void retrieveData(final CardAdapter mCardAdapter, SQLiteHelper db) {
CausticRetrofitService service = ServiceFactory.createRetrofitService(CausticRetrofitService.class, CausticRetrofitService.SERVICE_ENDPOINT);
service.getMedia()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber < MediaResponse > () {
#Override
public final void onCompleted() {
Log.e("CausticRetrofitService", "Caustic Request Completed!");
/* Cancel all progress indicators after data retrieval complete */
setRefreshingFalse();
// TODO: Add media to local data store and then display them one-by-one in real-time
mCardAdapter.addData(db.getAllMediaImages()); // Add all media images to card views
Log.d(getClass().toString(), "Added to local database: " + db.getAllMediaImages());
mCardAdapter.notifyDataSetChanged();
}
#Override
public final void onError(Throwable e) {
/* Cancel all progress indicators on data retrieval error */
setRefreshingFalse();
Toast.makeText(getApplicationContext(), "Cannot retrieve data. Please try again later.", Toast.LENGTH_SHORT).show();
Log.e("CausticRetrofitService", e.getMessage());
}
#Override
public final void onNext(MediaResponse mediaResponse) {
if (mediaResponse != null) {
Log.e("CausticRetrofitService", "Returned objects: " + mediaResponse.getResults());
for (String mediaId: mediaResponse.getResults()) {
Log.e("CausticRetrofitService", mediaId);
}
List < String > mediaIds = mediaResponse.getResults();
Log.d(getClass().toString(), "All Media IDs: " + mediaIds);
if (mediaIds.isEmpty()) {
Toast.makeText(getApplicationContext(), "Cannot retrieve data. Please try again later.", Toast.LENGTH_SHORT).show();
}
mCardAdapter.clear();
mCardAdapter.notifyDataSetChanged();
/* Store objects from remote web service to local database */
for (String mediaId: mediaIds) {
// TODO: Why are these null?
Log.d(getClass().toString(), "Media Id: " + mediaId);
MediaImage newMediaImage = new MediaImage();
newMediaImage.setTitle(mediaId);
db.addMediaImage(newMediaImage); // Add media image to local database
}
} else {
Log.e("CausticRetrofitService", "Object returned is null.");
}
}
});
}
I'm thinking that adding the remote data to the local data store in the onNext() method might be the thing that's blocking, although I'm not certain.
Your network call is done in a new thread as you specified, but the Subscriber methods onNext() and onComplete() runs on the observing Scheduler, which is the main thread.
You seem to be doing some database operations on those, try to offload the caching also to the background thread using a doOnNext() operator.
What doOnNext() will do, is that it is called for each emission in your stream.
It can go something like that
service.getMedia()
.doOnNext(data -> cacheData(data))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
Where cacheData() is a method that does all your DB calls. And the only things left in your onNext() and onComplete() would be updating the UI only.

Categories

Resources