I want to make a http server in android which serve file (html/png..) also doing event based on request.
Example: If request is /maketoast android make a toast or request is /chanhetext android change a specific textview text.
Point is: I already make a server by Nanohttpd. It's serve files, but it don't make any event, like make toast or change textview text.
Here is Nanohttpd serve method
public Response serve(IHTTPSession session) {
String msg = "<html><body><h1>Hello server</h1>\n";
Map<String, String> parms = session.getParms();
if (parms.get("username") == null) {
msg += "<form action='?' method='get'>\n <p>Your name: <input type='text' name='username'></p>\n" + "</form>\n";
} else {
msg += "<p>Hello, " + parms.get("username") + "!</p><img src=max.png/>";
}
//Toast.makeText(mContext, "Helloooooo...!!!", Toast.LENGTH_SHORT).show();
return newFixedLengthResponse( msg + "</body></html>\n" );
}
When I try to make toast server going freeze and doesn't give any response. Can any one please tell me how I make this kind of thing.
Try:
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(mContext, "Helloooooo...!!!", Toast.LENGTH_SHORT).show();
}
});
Put your Nanohttpd into a service, so that you can send a LocalBroadCast to your activity to display Toast or any other UI response.
Related
I've been trying to send a POST request to a php script in order to update the value of a table in a MySQL database. I've been using RetroFit of late and have used it to send quite a few POST request for POST based operations. I don't know if my problem occurs because I am violating HTTP best practices which would recommend to use PUT for update operations but I have also tried sending a PUT request from the Client although it had the same outcome. The database values were not changed when I checked them. Here is the code where I send the HTTP Post Request from RetroFit.
final JsonDataAPI API = RetroFitClient.getInstance().getAPI();
Map<String, String> voteParams = new HashMap<String, String>();
voteParams.put("pollID", String.valueOf(pollID));
voteParams.put("optText", rb1.getTag().toString());
Call <ArrayList<PollOpt>> voteCall = API.makeVote(voteParams);
voteCall.enqueue(new Callback<ArrayList<PollOpt>>() {
#Override
public void onResponse(Call<ArrayList<PollOpt>> call, Response<ArrayList<PollOpt>> response) {
if(!response.isSuccessful()){
Toast.makeText(PollPage.this, "Vote Unsuccessful for vote 2",
Toast.LENGTH_SHORT).show();
} else{
Toast.makeText(PollPage.this, "Vote Successful for vote 2",
Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ArrayList<PollOpt>> call, Throwable t) {
Log.d("TAG", "Vote Failure: " + t.getMessage());
Log.d("TAG", "FailureURL rb2: " + call.request().url().toString());
}
});
The URL of the requests is just fine it even prints the request in the onFailure function which fires as there is no response, although I don't expect a response.
This is the part of the PHP API code the request is getting sent too Vote.php:
'
method = $_SERVER['REQUEST_METHOD'];
switch($method){
case "POST":
if(isset($_POST["optText"]) && isset($_POST["pollID"])){
$optText = $_POST["optText"];
$pollID = (int) $_POST["pollID"];
$query = "UPDATE polloption SET frequency = frequency + 1 WHERE pollID = " . $pollID . " AND optText = '". $optText ."'";
$conn = new mysqli($host, $user, $pass, $database);
if ($conn->connect_error)
die($conn->connect_error);
if(mysqli_query($conn, $query)){
echo "Updated Poll Frequency";
} else{
echo "Failed to Update Poll Frequency";
}
}
break;'
I've tested the PHP code out using AJAX scripts seeing as you can see phps echo data in the AJAX Requests response whereas in Android you are basically working in the dark when sending HTTP Requests with methods other than GET and determining errors without having to individually test each file with an AJAX Request. After testing the server with AJAX scripts multiple times with different parameters, I can't see why the frequency value doesn't update when sending POST requests through RetroFit.
Any advice on this would be much appreciated!
Dont use isset($_POST["optText"]) && isset($_POST["pollID"]) to get Values from Json based body requests just use
$post_body = file_get_contents('php://input');
for php
I'm developing an android chat app, using Node Js and redis to stock messages and user information. I'm using socket io for communication, and Room to store message in local database. When the user is offline, I want them to receive their messages once online again. My problem is, that when user A is offline, and user B send him many messages (let's say for instance 5 messages ), when user A is online again, he only receives the first message, and the last message 4 times. Here is what I'm doing, once the user receives a message, I update the message status in Redis from "Sent" to "Delivered". In the case when the user is offline, I stock their messages in Redis with the status of message "Sent", and once online again, I check their messages received for example from user B, if their status is "Sent", I deliver it to the user, and then it will be updted to "Delivered", as shown in the code below:
//On this event, we update the socket ID of the sender in Redis so they can
receive private messages from their contacts
socket.on('sender', (sender, destinat) =>{
tempId = socket.id;
senderId = sender;
users[sender] = sender;
users [destinat] = destinat;
//We also update the user status: online
client.hset(senderId, 'lastSeen', 'Now', function(reply){
console.log( senderId + reply);
});
//Stocking to the user socket id
client.hset(users[sender], 'tempId', tempId, function(){
console.log("Welcome " + sender);
console.log("Welcome " + tempId);
});
//Getting all the messages of the sender from users
//If the sender has any messages that hasn't received yet, they'll be sent
here
//the id of each message is compsed of two parts: the phone number of the
receiver, and the id of the message itself
(receiverPhoneNumber:idMessage)
client.keys(users [sender] + ':*', function(err, results) {
results.forEach(function(key) {
client.hgetall(key, function(err, reply){
if(err)
console.log(err);
else if(reply){
//Compare the message status: if not sent, deliver it to receiver once online
if('Sent'.localeCompare(reply.status) == 0 && users
[destinat].localeCompare(reply.fromUser) == 0) {
io.to(tempId).emit('message', reply);
}
}
});
});
});
});
After receiving messages from the server, I use Async to store them in Room Database and then display them to the user, as shown in the following code
And here is the AsyncTask Class:
class AddMessage extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
//Creating a user account
m = new Message();
m.setContent( message );
m.setTime( time );
m.setUrl( url );
m.setStatus( status );
m.setFromUser( fromUser );
m.setToUser( toUser );
m.setUsername( receiver.getUsername() );
//adding to database
DatabaseClient.getInstance(getContext()).getAppDatabase()
.messageDao()
.insert(m);
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText( getContext(), "Added!", Toast.LENGTH_SHORT ).show();
}
}
I've checked that messages are received from the server to the android app correctly (by re-sending the messages again to the server once delivered to the app). I believe the problem has something to do with AsyncTask, but I just can't figure it out, any help is greatly appreciated, thank you so much.
//When receving a message
socket.on("message", new Emitter.Listener() {
#Override
public void call(final Object... args) {
if(getActivity() != null){
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
JSONObject data = (JSONObject) args[0];
try {
//extract data from fired event
idMessage = data.getString( "idMessage" );
message = data.getString("message");
fromUser = data.getString( "fromUser" );
toUser = data.getString( "toUser" );
time = data.getString( "time" );
status = data.getString( "status" );
url = data.getString( "url" );
//Here we call asyncTask to Add it to Database
addMessage = new AddMessage();
addMessage.execute( );
//We emit this event to update the status of
the message to delivered
socket.emit( "sent", idMessage, userID );
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}
});
I solved the problem by switching to RxJava instead of AsyncTask. The problem had something to do with AsyncTask as it sometimes influnces the chain of data, which is not the case with RxJava, as mentioned in this link : "Another issue with AsyncTasks is if you have more than one running at once. You have no guarantee what order they’ll complete in, resulting in complex logic to check when all the tasks have completed. Even worse is the assumption that one will finish before the other, until you hit an edge case that makes the first call slower, which makes them complete in the wrong order and undesired results."
Is there any way that I could directly redirect the log message in Android to a string?
For example, I have a log message in Android.
Log.v(TAG, "First Name" + firstName);
Log.v(TAG, "Last Name" + lastName);
I have a string
String nameMessage = "Please check your credetials\n" ;
I want to concatenate the log to the message.
One way is to concatenate manually.
I am looking If we could redirect the log to message.
I'm not sure if I am understanding your question right, but technically you could just create a function that appends the log message and then actually logs it?
Example:
private StringBuilder errorMessage;
public void log(String tag, String message) {
errorMessage.append(message).append(System.getProperty("line.separator"));
Log.v(tag, message);
}
public void getErrorMessage() {
return errorMessage.toString();
}
And then, you'd just replace all your calls to Log#v with a call to #log(tag, message).
I am working on websocket connection to communicate with server.
Now, we have established a connection and able to send and receive message using Autobahn library.
Here is the code:
private void start() {
// wsuri is the url which has to be hit for connecting to the server i.e
// "ws://hostname:port "
final String wsuri = "ws://" + mHostname.getText() + ":"
+ mPort.getText();
// showing status on the UI.
mStatusline.setText("Status: Connecting to " + wsuri + " ..");
// enabling disconnect button clicking on which the connection will be
// disconnected.
setButtonDisconnect();
try {
mConnection.connect(wsuri, new WebSocketConnectionHandler() {
#Override
public void onOpen() {
// If connection is open, then status will be updated to
// "connected to..."
mStatusline.setText("Status: Connected to " + wsuri);
savePrefs();
// enabling mSendMessage button and mMessage edit Text.
mSendMessage.setEnabled(true);
mMessage.setEnabled(true);
}
#Override
public void onTextMessage(String payload) {
Log.d("ss", payload);
alert(payload);
}
#Override
public void onClose(int code, String reason) {
// If connection is lost, alert will be shown connection is
// lost and status will be set to "Ready".
alert("Connection lost.");
mStatusline.setText("Status: Ready.");
setButtonConnect();
// disabling mSendMessage button and mMessage edit Text.
mSendMessage.setEnabled(false);
mMessage.setEnabled(false);
}
});
} catch (WebSocketException e) {
Log.d(TAG, e.toString());
}
}
We just have a single method onTextMessage(String payload) to handle response from server.
and to send message to server we use mConnection.sendTextMessage(mMessage.getText().toString());
But now we are facing issue that how to hit api on that server?or lets say I want some list of devices or device_Status etc how it will happen??
Any idea how to do that?? At present I am thinking of sending some "key":"pair" value in message in form of json, by which the server will identify what request I have made...
I am still not sure whether this is the right way? Please if somebody can help me in this.
I am trying to understand GCM from the developer android site. I have implemented the client side android app following the instructions at http://developer.android.com/google/gcm/client.html. The code i used is downloaded from https://code.google.com/p/gcm/ as they have mentioned. The GCM registration function works perfectly on my phone.
Now the problem is, no where in the android app code do i see a place to mention my xmpp based app server name. So if i don't mention my server name, how will the message go to my server? i am confused as to how will my app interact with my server. The exact code that sends the message from the android app to the server is :
// Send an upstream message.
public void onClick(final View view) {
if (view == findViewById(R.id.send)) {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
String msg = "";
try {
Bundle data = new Bundle();
data.putString("my_message", "Hello World");
data.putString("my_action", "com.google.android.gcm.demo.app.ECHO_NOW");
String id = Integer.toString(msgId.incrementAndGet());
gcm.send(SENDER_ID + "#gcm.googleapis.com", id, data);
msg = "Sent message";
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
return msg;
}
#Override
protected void onPostExecute(String msg) {
mDisplay.append(msg + "\n");
}
}.execute(null, null, null);
} else if (view == findViewById(R.id.clear)) {
mDisplay.setText("");
}
}
When you send a device to cloud message from your app to your server you use the following call :
gcm.send(SENDER_ID + "#gcm.googleapis.com", id, data);
The GCM CCS server identifies your server by the SENDER_ID (since your server uses that SENDER_ID when establishing the XMPP connection with the GCM CCS server).