Locally call RESTful Web Service generated by NetBeans IDE from Android? - java

so the NetBeans IDE can generate RESTful Web Service from database (the table has been packed into an entity class). I followed this tutorial and the RESTful Web Service has been generated successfully.
Now, I would like to call from my Android app, but no luck so far. I used "Android Asynchronous Http Client
A Callback-Based Http Client Library for Android"
So here is my code snippet:
customActionBarView.findViewById(R.id.actionbar_done).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
// "Done"
String id = generateId();
EditText number = (EditText) findViewById(R.id.caller_phone_number);
EditText information = (EditText) findViewById(R.id.caller_information);
checkAvailability(id, number.getText().toString(), information.getText().toString());
finish();
}
});
and this:
public void processWebServices(RequestParams params) {
AsyncHttpClient client = new AsyncHttpClient();
client.post("http://localhost:8080/AndroidRESTful/com.erikchenmelbourne.entities.caller/create", params, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
try {
JSONObject obj = new JSONObject(response.toString());
if (obj.getBoolean("status")) {
setDefaultValues();
Toast.makeText(getApplicationContext(), "Information has been sent!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), obj.getString("error_msg"), Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "Error Occured [Server's JSON response is invalid]!", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
#Override
public void onFailure(int i, Header[] headers, byte[] bytes, Throwable throwable) {
if (i == 404) {
Toast.makeText(getApplicationContext(), "Requested resource not found", Toast.LENGTH_LONG).show();
} else if (i == 500) {
Toast.makeText(getApplicationContext(), "Something went wrong at server end", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Unexpected Error occcured! [Most common Error: Device might not be connected to Internet or remote server is not up and running]", Toast.LENGTH_LONG).show();
}
}
});
}
and here is NetBeans IDE generated POST method:
#Path("/create")
#POST
#Consumes({"application/xml", "application/json"})
public void create(#QueryParam("id") int id, #QueryParam("number") String number, #QueryParam("information") String information) {
Caller entity = new Caller (id, number, information);
super.create(entity);
}
I added the #Path("/create") annotation and modified the method a bit.
Please shed some light, I am fairly new to this so I don't have a clue. I know it is due to some very silly mistakes but please help. The program stops at
"Unexpected Error occcured! [Most common Error: Device might not be
connected to Internet or remote server is not up and running]"
. So obvious I couldn't connect the two programs well.

Your HTTP URL is "http://localhost:8080/..." i.e. it expects to reach a server running on the Android device. If your IDE/service is running on your workstation then:
If you're running the app on the Genymotion emulator use 10.0.3.2 instead of localhost
If you're running the app on the SDK emulator use 10.0.2.2 instead of localhost
If you're running the app on a real device then substitute the IP
address of your workstation and make sure the device and workstation are on the same network.
References:
How to access localhost from a Genymotion android emulator
Emulator Networking

Related

Android java - Trying to show snackbar in new thread

Ive been trying to make my bluetooth connection thread be able to send messages to the user through snackbars, but they never appear on the screen.
In main method:
//listener for connect button
try {
Button btn_connect = findViewById(R.id.btn_connect);
btn_connect.setOnClickListener(view -> {
if(bluetoothService.isStarted()){
snackbarMsg(findViewById(R.id.btn_connect), "Bluetooth connection already established");
} else{
new Thread(() -> {
try {
Log.i(TAG, "New thread started");
bluetoothService.run(MainActivity.this);
Log.i(TAG,"Bluetooth service started");
snackbarMsg(findViewById(R.id.btn_connect), "Bluetooth service started");
} catch (Exception e) {
Log.e(TAG, "Bluetooth service failed", e);
}
}).start();
}
});
} catch (Exception exception){
Log.e(TAG, "Bluetooth service failed");
}
in BluetoothService class:
public void snackbarMsg (View view, String msg){
try {
Snackbar snackbar = Snackbar.make(view, msg, BaseTransientBottomBar.LENGTH_SHORT);
snackbar.show();
} catch (Exception exception){
Log.e(TAG, "Could not show snackbar", exception);
}
}
The view i send with the method is always of something on the main screen, so for example using "snackbarMsg(findViewById(R.id.button_send),"Failed to find bluetooth server");"
where button_send is on the screen i want to show the snackbar.
ive tried using runnables and extends thread and whatnot. But since i already have extensions on bluetoothservice class that didnt work, and runnable proved troublesome because i need to send context when starting the run method, and that context seemingly cant be sent at an earlier state, meaning i cant send that info when i create and object fom bluetoothservice at the beginning of the program.
Secondly: im not sure i even need a second thread, since my bluetooth connection is only sending data, not receiving, am i just doing useless work?
You need to run it on the UI/Main thread.
Use runOnUiThread(action: Runnable)
runOnUiThread(() -> snackbarMsg(view, "insert message"));

Can't connect to local socketIO nodejs server on android

I have made a basic nodejs server that console logs when a user connects to the server. i am using socket io for this because i wanna make a chat application. On my android side im trying to create a connection to this local server but i never get the console log when i try and socket.connected stays on false. also never get a error or something when trying to connect
I have tried some examples from the internet. i got 1 example working deleted everything that i didnt use and it still works. i copy paste from that example to my own project and still didn't work.
This is the example i used.
Here is the code of my project
Node JS:
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Android:
public class MainActivity extends Activity {
private Socket socket;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ChatApplication app = (ChatApplication) getApplication();
socket = app.getSocket();
socket.connect();
}
}
ChatApplication class:
public class ChatApplication extends Application {
private Socket mSocket;
{
try {
mSocket = IO.socket("http://192.168.0.109:3000");
} catch (Exception e) {
Log.e("Error", e.toString());
}
}
public Socket getSocket() {
return mSocket;
}
}
Android Studio emulator usually prevents localhost connections, I'm not sure if this happened in your case, but it has happened to me. Try popping out your Logcat in Android Studio and see if you can find something that indicates that the localhost connection got denied.
Not sure if this is it, but you should check.

Openfire does not respond to Smack login()

I am using Smack API trying to connect and login to the Openfire XMPP server which is setup on my laptop (localhost).
XMPPTCPConnectionConfiguration conf = XMPPTCPConnectionConfiguration.builder()
.setServiceName("win10-xps15")
.setHost("192.168.1.100")
.setPort(5222)
.setCompressionEnabled(false)
.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
.build();
XMPPTCPConnection connection = new XMPPTCPConnection(conf);
connection.connect();
connection.login("admin", "password");
The connect() method is successful but the login() method fails with a NoResponse (timeout) exception.
Exception in thread "main" org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 5000ms (~5s). Used filter: No filter used or filter was 'null'.
at org.jivesoftware.smack.SmackException$NoResponseException.newWith(SmackException.java:106)
at org.jivesoftware.smack.SmackException$NoResponseException.newWith(SmackException.java:85)
at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:250)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.loginNonAnonymously(XMPPTCPConnection.java:374)
at org.jivesoftware.smack.AbstractXMPPConnection.login(AbstractXMPPConnection.java:456)
at org.jivesoftware.smack.AbstractXMPPConnection.login(AbstractXMPPConnection.java:431)
at MyConnector.main(MyConnector.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Apr 13, 2016 11:45:42 AM org.jivesoftware.smack.AbstractXMPPConnection callConnectionClosedOnErrorListener
WARNING: Connection closed with error
java.lang.NullPointerException
at org.jivesoftware.smack.util.stringencoder.Base64.decode(Base64.java:86)
at org.jivesoftware.smack.sasl.SASLMechanism.challengeReceived(SASLMechanism.java:233)
at org.jivesoftware.smack.SASLAuthentication.challengeReceived(SASLAuthentication.java:328)
at org.jivesoftware.smack.SASLAuthentication.challengeReceived(SASLAuthentication.java:313)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1051)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:948)
at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:963)
at java.lang.Thread.run(Thread.java:745)
I am running Openfire 3.9.3 on my Windows laptop and the local IP is 192.168.1.100. The version of the smack library is 4.1.6.
Since it is the login() method that fails, I wonder if there is any Openfire server settings related to login/user that I should be aware of?
In addition, I tried to login with the Spark IM client and it could login the local server without problems.
Regards.
More info added below.
I just tried an old version (3.4.1) of smack obtained from the Spark IM github repo with the following code:
ConnectionConfiguration conf =
new ConnectionConfiguration("192.168.1.100", 5222);
XMPPConnection connection = new XMPPConnection(conf);
connection.connect();
connection.login("admin", "password");
Now the code works fine. Both connect() and login() are OK.
But I really want to know why the lastet version of smack does not work as I expect. Because I am considering using smack on Android while the old version does not support Android natively.
Lets start with step by step
1) add dependencies
compile 'org.igniterealtime.smack:smack-tcp:4.1.0'
compile 'org.igniterealtime.smack:smack-android-extensions:4.1.0'
compile 'org.igniterealtime.smack:smack-im:4.1.0'
2) async task for connect or login to server
//connect or login to server
private class MyOpenfireLoginTask extends AsyncTask<String, String, String> {
private Context mContext;
String username, password;
ProgressDialog dialog;
public MyOpenfireLoginTask(Context context) {
mContext = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(mContext);
dialog.setMessage("Loading...");
dialog.setCanceledOnTouchOutside(false);
dialog.show();
}
#Override
protected String doInBackground(String... params) {
username = params[0];
password = params[1];
Log.e("Login using ", username + " , " + password);
Config.config = XMPPTCPConnectionConfiguration.builder()
.setUsernameAndPassword(username, password)
.setHost("your host ex- wec.com")
.setResource("Android")
.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
.setServiceName("domain name(#) ex- secureserver.net")
.setPort("5222")
.setDebuggerEnabled(true)
.build();
Config.conn1 = new XMPPTCPConnection(Config.config);
Config.conn1.setPacketReplyTimeout(5000);
try {
Config.conn1.connect();
if (Config.conn1.isConnected()) {
Log.w("app", "conn done");
}
Config.conn1.login();
if (Config.conn1.isAuthenticated()) {
Log.w("app", "Auth done");
} else {
Log.e("User Not Authenticated", "Needs to Update Password");
}
} catch (Exception e) {
Log.w("app", e.toString());
}
return "";
}
#Override
protected void onPostExecute(String result) {
dialog.dismiss();
if (Config.conn1.isAuthenticated()) {
//success
} else {
Log.e(TAG, "username password wrong");
}
}
}
3)execute above class
if (username.length() > 0 && password.length() > 0) {
MyOpenfireLoginTask task = new MyOpenfireLoginTask(activity);
task.execute(username, password);
}
I have do it and works for me. Here is my config
conf.setCompressionEnabled(false)
.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)

GCM sendRegistrationIdToBackend is undefined

I am trying to set up GCM but my project doesn't recognize certain methods. I followed the advice of many other links which was to import GCM and google play services but I am still getting no such luck. Thanks for looking.
Edit: I've cleaned a million times and rebuilt.
I'm not sure where you got the code of the demo app from, but there are several things wrong with it.
First of all, the method you are missing is not implemented in the Demo. It has an empty body :
/**
* Sends the registration ID to your server over HTTP, so it can use GCM/HTTP or CCS to send
* messages to your app. Not needed for this demo since the device sends upstream messages
* to a server that echoes back the message using the 'from' address in the message.
*/
private void sendRegistrationIdToBackend() {
// Your implementation here.
}
It's your responsibility to implement it, since its implementation depends on your server implementation.
Another error (you'd get an exception after you fix the compilation error) is calling gcm.register() from the main thread. You must call it in the background :
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mDisplay = (TextView) findViewById(R.id.display);
context = getApplicationContext();
// Check device for Play Services APK. If check succeeds, proceed with GCM registration.
if (checkPlayServices()) {
gcm = GoogleCloudMessaging.getInstance(this);
regid = getRegistrationId(context);
if (regid.isEmpty()) {
registerInBackground();
}
} else {
Log.i(TAG, "No valid Google Play Services APK found.");
}
}
/**
* Registers the application with GCM servers asynchronously.
* <p>
* Stores the registration ID and the app versionCode in the application's
* shared preferences.
*/
private void registerInBackground() {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regid = gcm.register(SENDER_ID);
msg = "Device registered, registration ID=" + regid;
// You should send the registration ID to your server over HTTP, so it
// can use GCM/HTTP or CCS to send messages to your app.
sendRegistrationIdToBackend();
// For this demo: we don't need to send it because the device will send
// upstream messages to a server that echo back the message using the
// 'from' address in the message.
// Persist the regID - no need to register again.
storeRegistrationId(context, regid);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
// If there is an error, don't just keep trying to register.
// Require the user to click a button again, or perform
// exponential back-off.
}
return msg;
}
#Override
protected void onPostExecute(String msg) {
mDisplay.append(msg + "\n");
}
}.execute(null, null, null);
}
All code samples are taken from the official GCM Demo app.

gcm returns service not available

I have this code. I enter the project key from the Google console as the snederId and get an error:
service not available.
which steps would you recommend for me to double check in setting up the registration key?
private void registerInBackground() {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regId = gcm.register(SENDER_ID);
msg = "Device registered, registration ID=" + regId;
// You should send the registration ID to your server over
// HTTP, so it
// can use GCM/HTTP or CCS to send messages to your app.
sendRegistrationIdToBackend();
saveRegIdToDb();
// For this demo: we don't need to send it because the
// device will send
// upstream messages to a server that echo back the message
// using the
// 'from' address in the message.
// Persist the regID - no need to register again.
storeRegistrationId(context, regId);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
// If there is an error, don't just keep trying to register.
// Require the user to click a button again, or perform
// exponential back-off.
}
return msg;
}
#Override
protected void onPostExecute(String msg) {
// mDisplay.append(msg + "\n");
}
}.execute(null, null, null);
}
Some basic checks:
Was your project whitelisted by Google?
Do you use the correct sender_id (project number)?
Is network connection up?
Are Google Play Services installed and up to date?
One of the above checks should not be OK.
check sender id, it is project number
and turn on "APIs & auth" -> "Google Cloud Messaging for Android"

Categories