I am trying to perform an asynchronous GET-request on my openHAB-project. I have done it before and reused parts of my code to create a new Android app, but it is not working.
In theory I want the state of the "GastSwitch"-item to be written into a String (gastSwitchState) to then be used as a trigger for opening a different activity. If the result of the request is "OFF" the app is supposed to keep running, but stay in the MainActivity.
When debugging it seems like the getGastSwitchState-method is jumped entirely after the enqeue-Method is called. Can someone explain to me, why my code seems to leave out half of the method?
I know that this way of doing it should work, but I can't find where I went wrong.
//connect with REST-API in openHAB :
// GET Status GastSwitch: if Switch = "ON" go to MeetingActivity
//Timer to GET the GastSwitch-status every 30 seconds:
TimerTask gastSwitchTimerTask = new TimerTask() {
public void run() {
try {
getGastSwitchState("myURLforOpenHABGastSwitchState", new Callback() {
#Override
public void getParameter(String string) {
if (gastSwitch.equals("ON")) {
Intent activityIntent = new Intent(getApplicationContext(), MeetingActivity.class);
startActivity(activityIntent);
}
}
});
} catch (IOException e) {
e.printStackTrace();
tvLog.setText(e.toString());
}
}
};
// Timer for GETting the GastSwitch-state every 30 seconds
long emergencyDelay = 1000 * 30 * 1;
Timer gastSwitchTimer = new Timer();
gastSwitchTimer.schedule(gastSwitchTimerTask, 0, emergencyDelay);
}
//Method for GETting the GastSwitch-state from REST-API:
void getGastSwitchState(String url, final Callback callback) throws IOException {
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
okhttp3.Request request = new okhttp3.Request.Builder()
.url(url)
.method("GET", null)
.addHeader("AuthToken", "")
.build();
client.newCall(request)
.enqueue(new okhttp3.Callback() {
#Override
public void onResponse(#NotNull okhttp3.Call call, #NotNull Response response) throws IOException {
if (response.isSuccessful()) {
final String res = response.body().string();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
gastSwitch = res;
tvLog.setText(gastSwitch);
callback.getParameter(gastSwitch);
}
});
}
}
#Override
public void onFailure(#NotNull okhttp3.Call call, #NotNull IOException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
});
I was wondering if there is a way to catch an exception/throwable when producing a kafka message via the Kafka Template.
I don't see anything where it would throw a KafkaException if something fails. I need to find out if the message was committed to Kafka before I can continue with my application flow. I know the ListenableFuture would log a failure but I don't know how to capture that onFailure.
public void sendToKafkaTopic(KafkaMessage data) {
ListenableFuture<SendResult<String, KafkaMessage>> future = kafkaTemplate.send(primaryKafkaTopic, data);
future.addCallback(new ListenableFutureCallback<SendResult<String, KafkaMessage>>() {
#Override
public void onSuccess(SendResult<String, KafkaMessage> result) {
log.info("sent message='{}' with offset={}", data,
result.getRecordMetadata().offset());
}
#Override
public void onFailure(Throwable ex) {
log.error("unable to send message='{}'", data, ex);
}
});
}
I was trying to find something like this:
public void sendToKafkaTopic(KafkaMessage data) {
try {
kafkaTemplate.send(primaryKafkaTopic, data);
} catch (RuntimeException err) {
log.error("unable to send message='{}'", data, ex);
throw new CustomException(err);
}
}
}
before I can continue with my application flow
There is nothing wrong if you just do Future.get(). When an exception happens downstream, it is going to be thrown to you from this blocking get().
I've tried everything and didn't get any results. I just know that subscribeOn method switches the operation to the background thread and prevent UI thread blocking and I should expect that anything happens on the background thread should not affect the user flow.
Now I'm not sure that did I get the wrong info about the subscribeOn() method or do I have a bug in my code?
String profileUrl = BuildConfig.BASEURL + "pharma/patient/profile?username=" + caregiverNo;
try {
Observable.just(OkhttpClientManager.getInstance(APP_NAME, APP_VERSION).getRequest(profileUrl))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
#Override
public void onSubscribe(Disposable d) {
callback.getDisposable(d);
}
#Override
public void onNext(String s) {
CaregiverUserResponse response = new Gson().fromJson(s, CaregiverUserResponse.class);
if (response.getResult().equals(Constants.API_CALL_SUCCESS)) {
updateCaregiverCache(response);
getUserData(callback, patientNo, authToken);
} else {
callback.onError(new NetworkError(new Throwable(response.getError())));
}
}
#Override
public void onError(Throwable e) {
callback.onError(new NetworkError(e));
}
#Override
public void onComplete() {
}
});
} catch (Exception e) {
Log.e(TAG, "getCaregiverProfile: ", e);
}
This is my code in which getRequest() function returns the response as String.
and I'm getting this error NetworkOnMainThreadException and I know that subscribeOn(Schedulers.io()) performs the operation on the background thread.
Error:
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1565)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:389)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
at java.net.Socket.connect(Socket.java:621)
at okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.java:73)
at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:246)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:166)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
at okhttp3.RealCall.execute(RealCall.java:92)
at com.healthapp.myadhero.network.OkhttpClientManager.getRequest(OkhttpClientManager.java:64)
at com.healthapp.myadhero.network.Service.getCaregiverProfile(Service.java:81)
at com.healthapp.myadhero.network.Service.access$200(Service.java:68)
at com.healthapp.myadhero.network.Service$2.onNext(Service.java:154)
at com.healthapp.myadhero.network.Service$2.onNext(Service.java:131)
at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:201)
at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:255)
at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:124)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Thanks in advance.
You are calling that getRequest before RxJava is even involved, then you hand the result value to RxJava. Using just near network call is often wrong and you should be using fromCallable.
String profileUrl = BuildConfig.BASEURL + "pharma/patient/profile?username=" + caregiverNo;
Observable.fromCallable(() ->
OkhttpClientManager
.getInstance(APP_NAME, APP_VERSION)
.getRequest(profileUrl)
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
#Override
public void onSubscribe(Disposable d) {
callback.getDisposable(d);
}
#Override
public void onNext(String s) {
CaregiverUserResponse response = new Gson().fromJson(s, CaregiverUserResponse.class);
if (response.getResult().equals(Constants.API_CALL_SUCCESS)) {
updateCaregiverCache(response);
getUserData(callback, patientNo, authToken);
} else {
callback.onError(new NetworkError(new Throwable(response.getError())));
}
}
#Override
public void onError(Throwable e) {
callback.onError(new NetworkError(e));
}
#Override
public void onComplete() {
}
});
I am developing chat application by using Openfire XMPP server. I can text chat between two user. But i want to know Typing status when some one is typing message. So i created a class :-
public class typingStatus implements ChatStateListener {
#Override
public void processMessage(Chat arg0, Message arg1) {
// TODO Auto-generated method stub
}
#Override
public void stateChanged(Chat arg0, ChatState arg1) {
// TODO Auto-generated method stub
System.out.println(arg0.getParticipant() + " is " + arg1.name());
}
}
But i am confuse so that How will it work? I know that i need a packet where i can it in Listener. But i am unable to find that packet.
Please any one suggest, How will it work?
and also what is difference between Smack and asmack?
Thank you!
To enable ChatStateListener you need to create a custom MessageListener Class
public class MessageListenerImpl implements MessageListener,ChatStateListener {
#Override
public void processMessage(Chat arg0, Message arg1) {
System.out.println("Received message: " + arg1);
}
#Override
public void stateChanged(Chat arg0, ChatState arg1) {
if (ChatState.composing.equals(arg1)) {
Log.d("Chat State",arg0.getParticipant() + " is typing..");
} else if (ChatState.gone.equals(arg1)) {
Log.d("Chat State",arg0.getParticipant() + " has left the conversation.");
} else {
Log.d("Chat State",arg0.getParticipant() + ": " + arg1.name());
}
}
}
Then you create MessageListener object
MessageListener messageListener = new MessageListenerImpl();
And then pass this in the create chat method
Chat newChat = chatmanager.createChat(jabber_id_of_friend, messageListener);
what is difference between Smack and asmack? <-- Check This
finally I got the solution. I need to use chat listener along with chat manager and also I need to use in built sendcomposingnotification function. No need to use Messageeventrequestlistener interface or any other custom class for this. I added the following lines,,
connection.getChatManager().addChatListener(new ChatManagerListener() {
#Override
public void chatCreated(final Chat arg0, final boolean arg1) {
// TODO Auto-generated method stub
arg0.addMessageListener(new MessageListener()
{
#Override
public void processMessage(Chat arg0, Message arg1)
{
// TODO Auto-generated method stub
Log.d("TYpe Stat",title[0] + " is typing......");
Toast.makeText(getApplicationContext(),title[0] + " is typing......",Toast.LENGTH_SHORT).show();
}
}
});
}
});
and also need to send notification like this..
mem.sendComposingNotification(etRecipient.getText().toString(), message.getPacketID());
System.out.println("Sending notification");
where mem is type of MessageEventManger.
Ref: http://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smackx/MessageEventManager.html
ChatManager chatManager = ChatManager.getInstanceFor(connection);
Chat chat= chatManager.createChat(to, new ChatStateListener() {
#Override
public void stateChanged(Chat chat, ChatState state) {
switch (state){
case active:
Log.d("state","active");
break;
case composing:
Log.d("state","composing");
break;
case paused:
Log.d("state","paused");
break;
case inactive:
Log.d("state","inactive");
break;
case gone:
Log.d("state","gone");
break;
}
}
#Override
public void processMessage(Chat chat, Message message) {
Log.d("processMessage","processMessage");
}
});
use this code.hope so will work
i am using chat state listener :
Chat chat = chatManager.createChat(jid,
new ChatStateChangedListener());
bind the chatstatelistener with each jid like above , then :
public class ChatStateChangedListener implements ChatStateListener {
public ChatStateChangedListener() {
printLog("Chat State Changed Listner Constructor");
}
#Override
public void processMessage(Chat arg0, Message arg1) {
}
#Override
public void stateChanged(Chat chat, ChatState state) {
if (state.toString().equals(ChatState.composing.toString())) {
tvLastSeen.setText("Typing...");
} else if (state.toString().equals(ChatState.paused.toString())) {
tvLastSeen.setText("paused...");
} else {
tvLastSeen.setText("nothing");
}
}
}
}
Create On Class MMessageListener to listen incoming messages
private class MMessageListener implements MessageListener, ChatStateListener {
public MMessageListener(Context contxt) {
}
#Override
public void stateChanged(Chat chat, ChatState chatState) {
mStatus = "Online";
if (ChatState.composing.equals(chatState)) {
mStatus = chat.getParticipant() + " is typing..";
Log.d("Chat State", chat.getParticipant() + " is typing..");
} else if (ChatState.gone.equals(chatState)) {
Log.d("Chat State", chat.getParticipant() + " has left the conversation.");
mStatus = chat.getParticipant() + " has left the conversation.";
} else if (ChatState.paused.equals(chatState)){
Log.d("Chat State", chat.getParticipant() + ": " + chatState.name());
mStatus = "Paused";
}else if (ChatState.active.equals(chatState)){
mStatus = "Online";
}
// do whatever you want to do once you receive status
}
#Override
public void processMessage(Message message) {
}
#Override
public void processMessage(Chat chat, Message message) {
}
}
Add Listener to your chat object
Chat Mychat = ChatManager.getInstanceFor(connection).createChat(
"user2#localhost"),
mMessageListener);
Send status to receiving user on edittext text change
ChatStateManager.getInstance(connection).setCurrentState(ChatState.composing, Mychat);
This works fine for me.
Your or another xmpp client which you use, should sending chat state for You can catch the state.
Like This;
try {
ChatStateManager.getInstance(GlobalVariables.xmppManager.connection).setCurrentState(ChatState.composing, chat);
} catch (XMPPException e) {
e.printStackTrace();
}
or
try {
ChatStateManager.getInstance(GlobalVariables.xmppManager.connection).setCurrentState(ChatState.gone, chat);
} catch (XMPPException e) {
e.printStackTrace();
}
However you can get it from ProcessPacket also.
there you will get a Message object, after you can extract xml portion from there and handle them its contain specific chatstate or not.
Message message = (Message) packet;
String msg_xml = message.toXML().toString();
if (msg_xml.contains(ChatState.composing.toString())) {
//handle is-typing, probably some indication on screen
} else if (msg_xml.contains(ChatState.paused.toString())) {
// handle "stopped typing"
} else {
// normal msg
}
now handle as per your requirement.
Just add ChatStateManager after ChatManager intalization:
chatManager = ChatManager.getInstanceFor(getXmpptcpConnection());
ChatStateManager.getInstance(getXmpptcpConnection());
Then you need to add ChatStateListener during createChat(to,chatMesageListener):
chatManager.createChat(message.getTo(), chatMessageListener).sendMessage(message);
private ChatStateListener chatMessageListener = new ChatStateListener() {
#Override
public void stateChanged(Chat chat, ChatState state) {
//State Change composing,active,paused,gone,etc
Log.d(TAG, "ChatStateListener:::stateChanged -> " + chat.toString() + " \n -> " + state.toString());
}
#Override
public void processMessage(Chat chat, Message message) {
//Incoming Message
Log.d(TAG, "ChatStateListener:::processMessage -> " + chat.toString() + " \n -> " + message.toString());
}
};
I'm running an issue with gwt-oauth and Google contacts API.
I use gwt-oauth to login and everything works fine.
While running the RPC for retrieving the contacts I get
WARNING: Authentication error: Unable to respond to any of these challenges: {}
java.lang.NullPointerException: No authentication header information
Here is the code in Client
Button button = new Button("Authenticate with Google");
button.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
final AuthRequest req = new AuthRequest(K.GOOGLE_AUTH_URL, K.GOOGLE_CLIENT_ID).withScopes(K.CONTACTS_SCOPE, K.AUTH_SCOPE);
AUTH.expiresIn(req);
AUTH.login(req, new Callback<String, Throwable>() {
#Override
public void onSuccess(final String token) {
greetingService.loginDetails(token, new AsyncCallback<LoginInfo>() {
#Override
public void onSuccess(LoginInfo result) {
greetingService.getContactList(token, new AsyncCallback<Boolean>() {
#Override
public void onSuccess(Boolean result) {
Window.alert("oh");
}
#Override
public void onFailure(Throwable caught) {
Window.alert("Error:\n" + caught.getMessage());
}
});
}
#Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
});
}
#Override
public void onFailure(Throwable caught) {
Window.alert("Error:\n" + caught.getMessage());
}
});
}
});
And here the serverside for contacts:
try {
ContactsService s = new ContactsService(K.APPLICATION_NAME);
s.setProtocolVersion(ContactsService.Versions.V3);
s.setAuthSubToken(token);
s.setHeader("Authorization", "Bearer " + token);
for (ContactEntry entry : s.query(new Query(new URL(K.CONTACTS_SCOPE)), ContactFeed.class).getEntries())
System.out.println(entry.toString());
} catch (Exception e) {
e.printStackTrace();
}
return true;
This was working couple of weeks ago...
I assume is not a scope issue since loginDetails works properly...
Any idea?
Solved.
Scope for contacts in Auth was set to: https://www.google.com/m8/feeds/contacts/default/full/
Apparently this doesn't work anymore and I just set https://www.google.com/m8/feeds/ for auth
and the full url for querying in ContactService