connecting to xmpp server in android - android

I want to enable my app to send and recessive messages using xmpp server, i have installed and configured openfire but my app can't still send messages through xmpp server.
below is the code I am trying to connect to xmpp server with
ServerConnection
public class ServerConnection implements ConnectionListener {
private static final String TAG = "ServerConnection";
public static XMPPTCPConnection connection;
private Context mApplicationContext = null;
private String mUsername = null;
private String mPassword = null;
private String mServiceName = null;
private XMPPTCPConnection mConnection;
private BroadcastReceiver uiThreadMessageReceiver;//Receives messages from the ui thread.
private final Set<ChatMessageListener> listeners = new CopyOnWriteArraySet<>();
public ServerConnection() {
}
public static enum ConnectionState
{
CONNECTED ,AUTHENTICATED, CONNECTING ,DISCONNECTING ,DISCONNECTED;
}
public static enum LoggedInState
{
LOGGED_IN , LOGGED_OUT;
}
public ServerConnection ( Context context){
Log.d(TAG,"ServerConnection Constructor called.");
mApplicationContext = context.getApplicationContext();
String jid = PreferenceManager.getDefaultSharedPreferences(mApplicationContext)
.getString("xmpp_jid",null);
mPassword = PreferenceManager.getDefaultSharedPreferences(mApplicationContext)
.getString("xmpp_password",null);
if( jid != null)
{
mUsername = jid.split("#")[0];
mServiceName = jid.split("#")[1];
}else
{
mUsername ="";
mServiceName="192.168.8.101";
}
}
public void connect() throws IOException, XMPPException, SmackException, InterruptedException, XmppStringprepException
{
Log.d(TAG, "Connecting to server " + mServiceName);
DomainBareJid domainName = JidCreate.domainBareFrom("localhost");
XMPPTCPConnectionConfiguration conf = XMPPTCPConnectionConfiguration.builder()
.setServiceName("192.168.8.101")
.setHost("192.168.8.101")
.setResource("Roster")
//Was facing this issue
//https://discourse.igniterealtime.org/t/connection-with-ssl-fails-with-java-security-keystoreexception-jks-not-found/62566
.setKeystoreType(null) //This line seems to get rid of the problem
.setSecurityMode(ConnectionConfiguration.SecurityMode.required)
.setCompressionEnabled(true).build();
// Log.d(TAG, "Username : "+mUsername);
// Log.d(TAG, "Password : "+mPassword);
// Log.d(TAG, "Server : "+mServiceName);
//Set up the ui thread broadcast message receiver.
setupUiThreadBroadCastMessageReceiver();
// mConnection = new XMPPTCPConnection(config);
mConnection.addConnectionListener(this);
Log.d(TAG, "Calling connect() ");
mConnection.connect();
mConnection.login(mUsername,mPassword);
Log.d(TAG, " login() Called ");
org.jivesoftware.smack.chat2.ChatManager.getInstanceFor(mConnection).addIncomingListener(new IncomingChatMessageListener() {
#Override
public void newIncomingMessage(EntityBareJid entityBareJid, Message message, org.jivesoftware.smack.chat2.Chat chat) {
}
please i really need to know if my code is correct.

Related

Connect my app to my SQL Server database?

I am trying to make a login screen that when the users details are entered it will connect to the MS SQL database, the problem is it is not connecting. Am I doing it the right way or is there a better way to do this?
The error I am getting.
E/ERROR: Unknown server host name 'Unable to resolve host "myipaddresstestDatabasetestDatabase": No address associated with hostname'.
Here is my code that I tried.
public class LoginActivity extends AppCompatActivity {
private static String ip = "myip";
private static String port = "myportnum";
private static String Class = "net.sourceforge.jtds.jtbc.Driver";
private static String database = "name";
private static String username = "name";
private static String password = "password";
private static String url = "jdbc:jtds:sqlserver://"+ip+":"+port+"/"+database;
private Connection connection = null;
private EditText userNameET, passwordEt;
private Button loginBTN;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
userNameET = findViewById(R.id.userNameEditText);
passwordEt = findViewById(R.id.passEditText);
loginBTN = findViewById(R.id.loginBtn);
StrictMode.ThreadPolicy policy = null;
policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
// #android.support.annotation.RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
private class DoLoginForUser extends AsyncTask<String, Void, String> {
String emailId, password;
#Override
protected void onPreExecute() {
super.onPreExecute();
emailId = userNameET.getText().toString();
password = passwordEt.getText().toString();
// progressBar.setVisibility(View.VISIBLE);
loginBTN.setVisibility(View.GONE);
}
#Override
protected String doInBackground(String... params) {
try {
ConnectionHelper con = new ConnectionHelper();
Connection connect = ConnectionHelper.CONN();
String query = "Select * from testDatabase where UserId='" + emailId + "'";
PreparedStatement ps = connect.prepareStatement(query);
Log.e("query",query);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
String passcode = rs.getString("password");
connect.close();
rs.close();
ps.close();
if (passcode != null && !passcode.trim().equals("") && passcode.equals(password))
return "success";
else
return "Invalid Credentials";
} else
return "User does not exists.";
} catch (Exception e) {
return "Error:" + e.getMessage();
}
}
#Override
protected void onPostExecute(String result) {
//Toast.makeText(signup.this, result, Toast.LENGTH_SHORT).show();
// ShowSnackBar(result);
// progressBar.setVisibility(View.GONE);
loginBTN.setVisibility(View.VISIBLE);
if (result.equals("success")) {
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("userdetails",0);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("email",userNameET.getText().toString());
editor.commit();
Intent i = new Intent(LoginActivity.this, MainActivity.class);
startActivity(i);
} else {
//ShowSnackBar(result);
}
}
}
//public void ShowSnackBar(String message) {
// Snackbar.make(lvparent, message, Snackbar.LENGTH_LONG)
// .setAction("CLOSE", new View.OnClickListener() {
// #Override
// public void onClick(View view) {
//// }
// })
// .setActionTextColor(getResources().getColor(android.R.color.holo_red_light))
// .show();
// }
public void DoLogin(View v)
{
DoLoginForUser login = null;
login = new DoLoginForUser();
login.execute("");
}
I expected it to connect and then take me to the next screen, but the error is persistent?
The error message "Unable to resolve host" indicates that you are not putting the correct sql server hostname or ip in your connection string, or you try to reach an unreachable server (from your test device).
Is the sql server reachable for you from your dev computer? If so, you may need to connect your test device via wifi.
Make sure the device and the sql server are in the same network.

runOnUiThread is not executing

I am trying to run this code but code inside my runOnUi thread is not executing. I am using evernote-android-job.
He is the code which runs periodically:
public class TempJob extends Job {
public static final String TAG = "job_temp_mqtt";
#Override
#NonNull
protected Result onRunJob(#NonNull Params params) {
Log.d("I'm here", "Position 0");
Looper.prepare();
PubSubActivityTemp worker = new PubSubActivityTemp();
Log.d("I'm here", "Position 1");
worker.exe();
return Result.SUCCESS;
}
public static void scheduleJob() {
Set<JobRequest> jobRequests =
JobManager.instance().getAllJobRequestsForTag(TempJob.TAG);
if (!jobRequests.isEmpty()) {
Log.d("Check: ", "Job is not Empty");
// return;
}
new JobRequest.Builder(TempJob.TAG)
.setPeriodic(TimeUnit.MINUTES.toMillis(15),
TimeUnit.MINUTES.toMillis(7))
.setUpdateCurrent(true) // calls
cancelAllForTag(NoteSyncJob.TAG) for you
.setRequiredNetworkType(JobRequest.NetworkType.ANY)
.setRequirementsEnforced(true)
.build()
.schedule();
}
}
Here is the code from the activity:
public class PubSubActivityTemp extends Activity {
static final String LOG_TAG = GraphSelectType.class.getCanonicalName();
// --- Constants to modify per your configuration ---
// IoT endpoint
// AWS Iot CLI describe-endpoint call returns: XXXXXXXXXX.iot.
<region>.amazonaws.com
private static final String CUSTOMER_SPECIFIC_ENDPOINT = "*************-
ats.iot.us-east-1.amazonaws.com";
// Cognito pool ID. For this app, pool needs to be unauthenticated pool
with
// AWS IoT permissions.
private static final String COGNITO_POOL_ID = "us-east-
1:*************-75c2-4258-b663-21*********83e";
// Name of the AWS IoT policy to attach to a newly created certificate
private static final String AWS_IOT_POLICY_NAME = "PubSub******Cert";
// Region of AWS IoT
private static final Regions MY_REGION = Regions.US_EAST_1;
// Filename of KeyStore file on the filesystem
private static final String KEYSTORE_NAME = "iot_keystore";
// Password for the private key in the KeyStore
private static final String KEYSTORE_PASSWORD = "password";
// Certificate and key aliases in the KeyStore
private static final String CERTIFICATE_ID = "default";
TextView tvStatus;
// TextView tvLastMessage;
Handler mHandler;
AWSIotClient mIotAndroidClient;
AWSIotMqttManager mqttManager;
String clientId;
String keystorePath;
String keystoreName;
String keystorePassword;
KeyStore clientKeyStore = null;
String certificateId;
CognitoCachingCredentialsProvider credentialsProvider;
int tracker = 0; //0 is on, 1 is off
private String topic = "Simran*****";
private String msg0 = "on";
private String msg1 = "off";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void exe() {
Log.d("I'm here", "Position 2");
new Thread() {
public void run() {
Log.d("I'm here", "Position 3");
runOnUiThread(() -> {
Log.d("I'm here", "Position 4");
Toast.makeText(PubSubActivityTemp.this, "Storage not
available", Toast.LENGTH_SHORT).show();
});
Log.d("I'm here", "Position 5");
}
}.start();
}
public void mqtt() {
// tvStatus = (TextView) findViewById(R.id.tvStatus);
// tvLastMessage = (TextView) findViewById(R.id.tvLastMessage);
// MQTT client IDs are required to be unique per AWS IoT account.
// This UUID is "practically unique" but does not _guarantee_
// uniqueness.
clientId = UUID.randomUUID().toString();
// Initialize the AWS Cognito credentials provider
credentialsProvider = new CognitoCachingCredentialsProvider(
// getApplicationContext(), // context
TempApplication.getAppContext(),
COGNITO_POOL_ID, // Identity Pool ID
MY_REGION // Region
);
Region region = Region.getRegion(MY_REGION);
// MQTT Client
mqttManager = new AWSIotMqttManager(clientId,
CUSTOMER_SPECIFIC_ENDPOINT);
// Set keepalive to 10 seconds. Will recognize disconnects more
quickly but will also send
// MQTT pings every 10 seconds.
mqttManager.setKeepAlive(10);
// Set Last Will and Testament for MQTT. On an unclean disconnect
(loss of connection)
// AWS IoT will publish this message to alert other clients.
AWSIotMqttLastWillAndTestament lwt = new
AWSIotMqttLastWillAndTestament("my/lwt/topic",
"Android client lost connection", AWSIotMqttQos.QOS0);
mqttManager.setMqttLastWillAndTestament(lwt);
// IoT Client (for creation of certificate if needed)
mIotAndroidClient = new AWSIotClient(credentialsProvider);
mIotAndroidClient.setRegion(region);
keystorePath = getFilesDir().getPath();
keystoreName = KEYSTORE_NAME;
keystorePassword = KEYSTORE_PASSWORD;
certificateId = CERTIFICATE_ID;
// To load cert/key from keystore on filesystem
try {
if (AWSIotKeystoreHelper.isKeystorePresent(keystorePath,
keystoreName)) {
if (AWSIotKeystoreHelper.keystoreContainsAlias(certificateId,
keystorePath,
keystoreName, keystorePassword)) {
Log.i(LOG_TAG, "Certificate " + certificateId
+ " found in keystore - using for MQTT.");
// load keystore from file into memory to pass on
connection
clientKeyStore =
AWSIotKeystoreHelper.getIotKeystore(certificateId,
keystorePath, keystoreName, keystorePassword);
// btnConnect.setEnabled(true);
} else {
Log.i(LOG_TAG, "Key/cert " + certificateId + " not found
in keystore.");
}
} else {
Log.i(LOG_TAG, "Keystore " + keystorePath + "/" + keystoreName
+ " not found.");
}
} catch (Exception e) {
Log.e(LOG_TAG, "An error occurred retrieving cert/key from
keystore.", e);
}
if (clientKeyStore == null) {
Log.i(LOG_TAG, "Cert/key was not found in keystore - creating new
key and certificate.");
new Thread(new Runnable() {
#Override
public void run() {
try {
// Create a new private key and certificate. This call
// creates both on the server and returns them to the
// device.
CreateKeysAndCertificateRequest
createKeysAndCertificateRequest =
new CreateKeysAndCertificateRequest();
createKeysAndCertificateRequest.setSetAsActive(true);
final CreateKeysAndCertificateResult
createKeysAndCertificateResult;
createKeysAndCertificateResult =
mIotAndroidClient.createKeysAndCertificate
(createKeysAndCertificateRequest);
Log.i(LOG_TAG,
"Cert ID: " +
createKeysAndCertificateResult.getCertificateId() +
" created.");
// store in keystore for use in MQTT client
// saved as alias "default" so a new certificate isn't
// generated each run of this application
AWSIotKeystoreHelper.saveCertificateAndPrivateKey
(certificateId,
createKeysAndCertificateResult.getCertificatePem(),
createKeysAndCertificateResult.getKeyPair().getPrivateKey(),
keystorePath, keystoreName, keystorePassword);
// load keystore from file into memory to pass on
// connection
clientKeyStore =
AWSIotKeystoreHelper.getIotKeystore(certificateId,
keystorePath, keystoreName, keystorePassword);
// Attach a policy to the newly created certificate.
// This flow assumes the policy was already created in
// AWS IoT and we are now just attaching it to the
// certificate.
AttachPrincipalPolicyRequest policyAttachRequest =
new AttachPrincipalPolicyRequest();
policyAttachRequest.setPolicyName(AWS_IOT_POLICY_NAME);
policyAttachRequest.setPrincipal(createKeysAndCertificateResult
.getCertificateArn());
mIotAndroidClient.attachPrincipalPolicy(policyAttachRequest);
runOnUiThread(new Runnable() {
#Override
public void run() {
// btnConnect.setEnabled(true);
}
});
} catch (Exception e) {
Log.e(LOG_TAG,
"Exception occurred when generating new
private key and certificate.",
e);
}
}
}).start();
}
connect();
subscribe();
}
public void connect() {
try {
mqttManager.connect(clientKeyStore, new
AWSIotMqttClientStatusCallback() {
#Override
public void onStatusChanged(final AWSIotMqttClientStatus
status,
final Throwable throwable) {
Log.d(LOG_TAG, "Status = " + String.valueOf(status));
runOnUiThread(new Runnable() {
#Override
public void run() {
if (status == AWSIotMqttClientStatus.Connecting) {
tvStatus.setText("Connecting...");
} else if (status ==
AWSIotMqttClientStatus.Connected) {
tvStatus.setText("Connected");
} else if (status ==
AWSIotMqttClientStatus.Reconnecting) {
if (throwable != null) {
Log.e(LOG_TAG, "Connection error.",
throwable);
}
tvStatus.setText("Reconnecting");
} else if (status ==
AWSIotMqttClientStatus.ConnectionLost) {
if (throwable != null) {
Log.e(LOG_TAG, "Connection error.",
throwable);
}
tvStatus.setText("Disconnected");
} else {
tvStatus.setText("Disconnected");
}
}
});
}
});
} catch (final Exception e) {
Log.e(LOG_TAG, "Connection error.", e);
tvStatus.setText("Error! " + e.getMessage());
}
}
public void subscribe() {
try {
mqttManager.subscribeToTopic(topic, AWSIotMqttQos.QOS0,
new AWSIotMqttNewMessageCallback() {
#Override
public void onMessageArrived(final String topic, final
byte[] data) {
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
String message = new String(data,
"UTF-8");
Log.d(LOG_TAG, "Message arrived:");
Log.d(LOG_TAG, " Topic: " + topic);
Log.d(LOG_TAG, " Message: " +
message);
//
tvLastMessage.setText(message);
} catch (UnsupportedEncodingException e) {
Log.e(LOG_TAG, "Message encoding
error.", e);
}
}
});
}
});
} catch (Exception e) {
Log.e(LOG_TAG, "Subscription error.", e);
}
}
}
Here is the output from logcat. I ahve filtered out only necessary output. I am not getting any warning or errors:
09-30 11:55:23.662 5705-6268/com.simran.powermanagement D/I'm here:
Position 0
09-30 11:55:23.663 5705-6268/com.simran.powermanagement D/I'm here:
Position 1
Position 2
09-30 11:55:23.665 5705-6269/com.simran.powermanagement D/I'm here:
Position 3
09-30 11:55:23.665 5705-6269/com.simran.powermanagement D/I'm here:
Position 5
Toast needs context and when you instantiate an Activity class using new you just create a java class that it has no context.if you need some method of your activity you must send your activity or its context object to your Job class and use it for create your activity. like this :
public class PubSubActivityTemp extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
yourJob job=new yourJob (this);
}
}
in your job class :
public class TempJob extends Job {
Activity activity;
public TempJob (Activity activity){
this.activity=activity;
PubSubActivityTemp worker=(PubSubActivityTemp)activity;
}
}
if you you don't want to create your job in PubSubActivityTemp i suggest you use this way to instantiate PubSubActivityTemp :
first create a class that extends Application class :
public class Myapp extends Application{
public PubSubActivityTemp pubSubActivityTemp;
}
in AndroidManifast.xml file in <application> tag use this class for name attribute :
<application name=".Myapp ">
in your PubSubActivityTemp onCreate() methode :
public class PubSubActivityTemp extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApp myApp=(MyApp) getApplicationContext();// or getApplication();
myApp.pubSubActivityTemp=this;
}
}
in every class you need PubSubActivityTemp activity just send to it getApplicationContext as Context an in it :
public class TempJob extends Job {
Activity activity;// or use Context context;
public TempJob (Activity activity){
this.activity=activity;
MyApp myApp=(MyApp)activity.getApplicationContext();
PubSubActivityTemp worker=myApp.pubSubActivityTemp;
}
}
in another class that you need job :
public class AnotherActivity extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TempJob job=new TempJob(this);
}
}
and if you just want to find out some code working you can log it with Log.v()instead Toast

How to receive chatroom message using samck API , XMPP

I am new in android and i tried to create chat application using smack api and ejabberd.
i implement one to one chat and its work good. but i not able to receive chatroom message.
how can i do?
here is xmpp.java
public class MyXMPP {
public MyXMPP(MyService context, String serverAdress, String logiUser,
String passwordser) {
this.serverAddress = serverAdress;
this.loginUser = logiUser;
this.passwordUser = passwordser;
this.context = context;
this.applicationContext = context;
init();
}
public static MyXMPP getInstance(MyService context, String server,String user, String pass) {
if (instance == null) {
instance = new MyXMPP(context, server, user, pass);
instanceCreated = true;
}
return instance;
}
public org.jivesoftware.smack.chat.Chat Mychat;
ChatManagerListenerImpl mChatManagerListener;
MMessageListener mMessageListener;
static {
try {
Class.forName("org.jivesoftware.smack.ReconnectionManager");
} catch (ClassNotFoundException ex) {
// problem loading reconnection manager
}
}
public void init() {
gson = new Gson();
mMessageListener = new MMessageListener(context);
mChatManagerListener = new ChatManagerListenerImpl();
initialiseConnection();
}
private void initialiseConnection() {
XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration
.builder();
config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
config.setServiceName(serverAddress);
config.setHost("192.168.0.101");
config.setPort(5222);
config.setDebuggerEnabled(true);
XMPPTCPConnection.setUseStreamManagementResumptiodDefault(true);
XMPPTCPConnection.setUseStreamManagementDefault(true);
connection = new XMPPTCPConnection(config.build());
XMPPConnectionListener connectionListener = new XMPPConnectionListener();
connection.addConnectionListener(connectionListener);
}
private class ChatManagerListenerImpl implements ChatManagerListener {
#Override
public void chatCreated(final org.jivesoftware.smack.chat.Chat chat,
final boolean createdLocally) {
if (!createdLocally)
chat.addMessageListener(mMessageListener);
}
}
public void sendMessage(ChatMessage chatMessage) {
String body = gson.toJson(chatMessage);
Mychat = ChatManager.getInstanceFor(connection).createChat(
chatMessage.receiver + "#"
+ context.getString(R.string.server),
mMessageListener);
chat_created = true;
final Message message = new Message();
message.setBody(body);
message.setStanzaId(chatMessage.msgid);
message.setTo(chatMessage.receiver);
message.setFrom(chatMessage.sender);
message.setType(Message.Type.chat);
Mychat.sendMessage(chatMessage.body);
}
public void sendGroupMessage(ChatMessage chatMessage) {
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
MultiUserChat multiUserChat = manager.getMultiUserChat(chatMessage.receiver);
try {
multiUserChat.join(chatMessage.sender,"12345");
// multiUserChat.addMessageListener((MessageListener) mMessageListener);
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
}
Message message = new Message(chatMessage.receiver, Message.Type.groupchat);
message.setBody(chatMessage.body);
message.setType(Message.Type.groupchat);
message.setFrom(chatMessage.sender);
message.setTo(chatMessage.receiver);
multiUserChat.sendMessage(message);
}
/* Its work good for one to one chat */
private class MMessageListener implements ChatMessageListener {
Context context;
public MMessageListener(Context c) {
this.context = c;
}
#Override
public void processMessage(final org.jivesoftware.smack.chat.Chat chat,
final Message message) {
if (message.getType() == Message.Type.chat
&& message.getBody() != null) {
Log.d("Message received",message.getBody);
}
}
}
}
i implement all the connection xmpp connection in xmpp.java
sendGroupMessage() is used to send chat room message and its work good.
the problem is receive chat room message.
i also receive message into android log
here is the image
The Chat class that you are using is deprecated!
I recommend that you update your smack library to the latest version (4.2 presently).
Here is how you can attach an incoming message listener in Smack-4.2
XMPPTCPConnection connection; // Assuming you have the connection object
org.jivesoftware.smack.chat2.ChatManager chatManager = org.jivesoftware.smack.chat2.ChatManager.getInstanceFor(connection);
chatManager.addIncomingListener(new IncomingChatMessageListener()
{
#Override
public void newIncomingMessage(EntityBareJid from, Message message, org.jivesoftware.smack.chat2.Chat chat)
{
// Message received here
}
});

Paho Android client drops connection when a message is shown

I am trying to use the basic Eclipse Paho MQTT client version 1.1.0 to connect to a CloudAMQP RabbitMQ instance, subscribe to a topic, and receive messages (which I send from the web admin console).
It works well if the application sends all message payloads to the Log output.
If the application adds the message to a TextView, the message appears, but the connection is dropped immediately and no more message are received.
The full project is available at GitHub. A simple example is below.
There is a service-based MQTT Paho client, but I thought that for very simple applications the basic client should be able to receive and show messages in the Android app UI.
...
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttClientPersistence;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
public class MainActivity extends AppCompatActivity implements MqttCallback {
private static final String TAG = "main";
private Connection connection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
configureUI();
}
private Button buttonConnect;
private TextView messageWindow;
private void configureUI() {
buttonConnect = (Button) findViewById(R.id.buttonConnect);
messageWindow = (TextView) findViewById(R.id.messageWindow);
buttonConnect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String s = "***";
String d = "test";
String u = "***";
String p = "***";
if (connection != null && connection.isConnected()) {
connection.disconnect();
connection = null;
messageWindow.setText(String.format("Disconnected from server %s",
new Object[]{s}));
return;
}
messageWindow.setText(String.format("Connecting to server %s as user %s",
new Object[]{s, u}));
connection = new Connection(MainActivity.this, MainActivity.this, s, u, p);
connection.connect();
if (connection.isConnected()) {
messageWindow.append("\n\n");
messageWindow.append(String.format("Connected, listening for messages from topic %s",
new Object[]{d}));
connection.subscribe(d);
}
}
});
}
#Override
public void connectionLost(Throwable cause) {
Log.e(TAG, "connectionLost" + cause.getMessage());
}
#Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
String msg = new String(message.getPayload());
Log.i(TAG, "Message Arrived: " + msg);
// messageWindow.append(msg);
}
#Override
public void deliveryComplete(IMqttDeliveryToken token) {
Log.i(TAG, "Delivery Complete!");
}
class Connection {
private static final String TAG = "conn";
private static final String protocol = "tcp://";
private static final int port = 1883;
private static final int version = MqttConnectOptions.MQTT_VERSION_3_1_1;
private static final int keepAliveSeconds = 20 * 60;
private final Context context;
private MqttClient client;
private final String server;
private final String user;
private final String pass;
private final MqttConnectOptions options = new MqttConnectOptions();
public Connection(Context ctx, MqttCallback mqttCallback, String server, String user, String pass) {
this.context = ctx;
this.server = server;
this.user = user;
this.pass = pass;
MqttClientPersistence memPer = new MemoryPersistence();
try {
String url = protocol + server + ":" + port;
client = new MqttClient(url, MqttClient.generateClientId(), memPer);
client.setCallback(mqttCallback);
} catch (MqttException e) {
e.printStackTrace();
}
options.setUserName(user + ":" + user);
options.setPassword(pass.toCharArray());
options.setMqttVersion(version);
options.setKeepAliveInterval(keepAliveSeconds);
}
void connect() {
Log.i(TAG, "buttonConnect");
try {
client.connect(options);
} catch (MqttException ex) {
Log.e(TAG, "Connection attempt failed with reason code = " + ex.getReasonCode() + ":" + ex.getCause());
}
}
public boolean isConnected() {
return client.isConnected();
}
public void disconnect() {
try {
client.disconnect();
} catch (MqttException e) {
Log.e(TAG, "Disconnect failed with reason code = " + e.getReasonCode());
}
}
void subscribe(String dest) {
try {
client.subscribe(dest);
} catch (MqttException e) {
Log.e(TAG, "Subscribe failed with reason code = " + e.getReasonCode());
}
}
}
}
I would guess this is because you are trying to update the TextView from a none UI thread.
Try wrapping the messageWindow.append(msg); in a runOnUiThread call.
public void messageArrived(String topic, MqttMessage message) throws Exception {
String msg = new String(message.getPayload());
Log.i(TAG, "Message Arrived: " + msg);
runOnUiThread(new Runnable(){
public void run() {
messageWindow.append(msg);
}
});
}

Android - Autobahn web socket communication

I am working on Web socket communication with Autobahn library.
The problem I have is after connecting server, then message should be sent without connection again. But the message is sent with different connection that it connects to server every single time to send a message.
public class WebSocket_Connector extends Activity{
private static final String TAG = "ECHOCLIENT";
private static final String TAG1 = "My app";
public final WebSocketConnection mConnection = new WebSocketConnection();
private String tmpString = "";
public void connect(final String wsuri) {
Log.d(TAG, "Connecting to: " + wsuri);
try {
mConnection.connect(wsuri, new WebSocketHandler() {
#Override
public void onOpen() {
Log.d(TAG, "Status: Connected to " + wsuri );
Log.d(TAG, "Connection successful!\n");
mConnection.sendTextMessage(tmpString);
tmpString = "";
}
#Override
public void onTextMessage(String payload) {
Log.d(TAG, "Got echo: " + payload);
}
#Override
public void onClose(int code, String reason) {
Log.d(TAG, "Connection closed.");
}
});
} catch (WebSocketException e) {
Log.d(TAG, e.toString());
}
}
public void sendMessage(String message) {
if (mConnection.isConnected()) {
Log.d(TAG1, "Messeage is sent : " + message);
mConnection.sendTextMessage(message);
}
else {
tmpString = message;
connect("ws://192.168.3.100:7681");
}
}
}
This is the code I have, and...When you see "sendMessage" method, it always goes to 'else' not, if loop. Any suggestion 'experts' please..?
i don't know the package name you are dealing with for websocket. So first it has to be provided to get reliable answer to your question. But let say if it is something similar to :
https://code.google.com/p/weberknecht/source/browse/trunk/src/main/de/roderick/weberknecht/WebSocketConnection.java?r=2
note: i have not seen there isConnected() method but assume that it is added somewhere else.
you can see from source that onOpen() (line 88) is called before connected = true; on line (91). if this member var will be used as result of isConnected() then your code always will follow "else" part of the condition.
i would advice to dig into websocket api and its usage pattern further.

Categories

Resources