Java Question Building a XMPP lib for chat apps

birnesoft

Active Member
Licensed User
Longtime User
Hello
I try to program a XMPP Lib.
It's my first Lib, so I need a little help.
I write a wrapper for the XMPP lib ASmack.jar
ASmack is a port for Android from Smack.

The code compiles with the "Simple Library Compiler" but when I start the app,
I get the error:
java.lang.IllegalStateException: No DNS resolver active.:confused:

so I tried to make it like in the ReadMe from ASmack with
SmackAndroid.init(context);

but I don't know how to get the context.
Any Ideas?

thanks for help
Björn

here is my code.

B4X:
package anywheresoftware.b4a.objects;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.packet.Message;
import android.content.Context;
import android.app.Application;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;
@Version(1.0f)
@Permissions(values={"android.permission.INTERNET"})
@ShortName("chatski")
@ActivityObject
public class chatt {
Connection connection;
Chat chat;
public String ConnectServer(String v) {
connection = new XMPPConnection(v);
????????????????????????????????????????????????????????????????????????????????????
/*Context context=getApplicationContext();
SmackAndroid.init(context);
AndroidConnectionConfiguration mAndroidConnectionConfiguration=new AndroidConnectionConfiguration(v, 5222);
*/
????????????????????????????????????????????????????????????????????????????????????
try{
connection.connect();
}catch(Exception e) {
  return e.getMessage();
}
return "connected";
}
public String loginUser(String u,String p){
try{
connection.login(u, p);
}catch(Exception e) {
  return e.getMessage();
}
return "login OK";
}
public void ConnectUser(String u) {
  chat = connection.getChatManager().createChat(u, new MessageListener() {
  public void processMessage(Chat chat, Message message) {
  System.out.println("Received message: " + message);
  }
  });

}
public String sendMessage(String v) {
try{
chat.sendMessage(v);
  }catch(Exception e) {
  return e.getMessage();
  }
  return "send!";
}
}
 
Last edited:

Petrovic

Member
Licensed User
Longtime User
Have you done any progress on this as I really need that lib too?
 

birnesoft

Active Member
Licensed User
Longtime User
Yes, it works great on my mobile. But now I have the problem, it works only on Android 2 and I find nobody who help me to find a solution, so I've stopped the development for the moment.

If you want I send you the code
 

ilan

Expert
Licensed User
Longtime User
could you post your code here?
i am interested too

what kind of help do you need?
 

birnesoft

Active Member
Licensed User
Longtime User
Now the
wrapper for the ASmack lib works on Android 4 :).
It need more functionality. Maybe anybody can help me to find some solutions.
I'm very new in B4aLib-development.
My problem is to call a b4a-event from the lib to recive the message.


1. Download the newest ASmack
http://asmack.freakempire.de/0.8.10/asmack-android-19-0.8.10.jar
extract and copy in the b4a projekt direcory

objects/bin/classes/
..com
..de
..org

!!! don't forget to make all these files write protected. !!!


2.
I write the wrapper lib and compile it with the simple libray compiler.
It produces the attached files:
chatty.xml / chatty.jar
copy this files in the lib foulder of b4a an refresh the liblist.

here is the code:
package anywheresoftware.b4a.objects;

import org.jivesoftware.smack.*;
import org.jivesoftware.smack.SmackAndroid;
import org.jivesoftware.smack.sasl.*;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.AbstractConnectionListener;
import org.jivesoftware.smack.filter.PacketFilter;

import android.content.Context;
import android.app.Application;
import java.util.EventListener;


import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;
import anywheresoftware.b4a.BA.Events;


@Version(1.0f)
@Permissions(values={"android.permission.INTERNET"})
@ShortName("chatski")
@Events(values={"ReceivedMessage (msg As String)"})

public class chatt {
ConnectionConfiguration mAndroidConnectionConfiguration;
Connection connection;
Chat chat;
String g="nn"; //Message text
Message xmessage;


public String ConnectUser(String u) {
chat = connection.getChatManager().createChat(u, new MessageListener() {

public void processMessage(Chat chat, Message message) {
g=message.getBody();
BA.raiseEvent2(this, false, "receiveMessage", true, new Object[] {g});
}
});
return g;
}


public String SmackAndroidInit(Context c) {

try{
SmackAndroid.init(c);
}
catch(Exception e) {
return e.getMessage();
}
return "initOK";
}


public String getg() {

return g;

}



public String AndroidConnectionConfiguration(String host) {

try{
mAndroidConnectionConfiguration=new ConnectionConfiguration(host, 5222);
}catch(Exception e) {
return e.getMessage();
}
return host;

}




public String MakeConnection() {

mAndroidConnectionConfiguration.setSASLAuthenticationEnabled(true);
mAndroidConnectionConfiguration.setCompressionEnabled(true);
mAndroidConnectionConfiguration.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);


mAndroidConnectionConfiguration.setTruststoreType("AndroidCAStore");
mAndroidConnectionConfiguration.setTruststorePassword(null);
mAndroidConnectionConfiguration.setTruststorePath(null);


//mAndroidConnectionConfiguration.setSASLAuthenticationEnabled(true);
connection = new XMPPConnection(mAndroidConnectionConfiguration);

return "made config!";

}


public String ConnectServer() {


try{

connection.connect();

}catch(Exception e) {
return e.getMessage();
}

//return connection.getConnectionID();

return connection.getHost();


}



public String loginUser(String u,String p){

try{

connection.login(u, p);

}catch(Exception e) {
return e.getMessage();
}

return "login OK";
}

public String sendMessage(String v) {

try{

chat.sendMessage(v);
}catch(Exception e) {
return e.getMessage();
}
return "send!";

}

}

3.

I've made a service modul and start the network in a thread:

Sub Process_Globals
Dim ccc As chatski
Dim th As Thread
Dim Params(1) As Object
Dim us,pw,ho,uc,tm,tr As String

End Sub

Sub Service_Create
ho="jabber.1und1.de"
us="tom"
pw="#tomtom#"
uc="mike@jabber.1und1.de"
tm="This is a test!!"
Params(0) =1
End Sub

Sub Service_Start (StartingIntent As Intent)

If th.IsInitialized =False Then th.Initialise("the")
If th.Running =False Then th.start(Null,"thread1",Params)

End Sub

Sub Service_Destroy
End Sub

Sub thread1(c As Int)

ll1=ccc.SmackAndroidInit(Main.ac)
Log(ll1)
ll2=ccc.AndroidConnectionConfiguration(ho)
Log(ll2)
ll3=ccc.MakeConnection
Log(ll3)
Try
ll4=ccc.ConnectServer
Log(ll4)
Catch
Log("no")
End Try
ll5=ccc.loginUser(us,pw)
ll6=ccc.ConnectUser(uc)
ll7=ccc.sendMessage(tm)
end sub


Sub receivedmessage(g as string)
tr=g
callsub(main,"msgTitle",g)
log(g)
End Sub

in the main activity only write

Sub Process_Globals
Dim ac As Object
End Sub

Sub Globals
Dim r As Reflector
End Sub


Sub Activity_Create(FirstTime As Boolean)
r.Target=Activity
ac=r.GetContext
startservice(chatservice)
end sub

sub msgTitle(msg as string)
activity.title=msg
end sub
 

Attachments

  • chatt.zip
    3.2 KB · Views: 532
Last edited:

NeoTechni

Well-Known Member
Licensed User
Longtime User
If you cant figure out how to call the event, just use a list that you push events on to, and let us poll it for new data
 

birnesoft

Active Member
Licensed User
Longtime User
I don't want to ask the lib for the messages, it should tell me new messages.

I've tried it with
@Events(values={"ReceivedMessage (g As String)"})

public String ConnectUser(String u) {
chat = connection.getChatManager().createChat(u, new MessageListener() {
public void processMessage(Chat chat, Message message) {
g=message.getBody();
ba.raiseEvent2(this,false,"receiveMessage",tue,(Object)null); }
});
return g;
}
public String ReceivedMessage (String g){
return g;
}

but I'm not sure what's wrong. Any ideas ?
 
Last edited:

DonManfred

Expert
Licensed User
Longtime User
I´m really not familar with java BUT

g=message.getBody();
ba.raiseEvent2(this,false,"reciveMessage",tue,(Object)null); }

You are getting the messagetext to g (string i think)
but in raiseEvent i cannot see any reference to g which you want to transport!?

Please excuse me if i´m totally wrong... I´m not familar with java.
Just wanted to give my thoughts to this

Edit: Maybe like this?
ba.raiseEvent2(this,false,"reciveMessage",tue,string g);


PS: btw, it should have named receive not recive i suppose
 

birnesoft

Active Member
Licensed User
Longtime User
aha, Manfred!! dachte ich mir :)

I tried
msg=message.getBody();
ba.raiseEvent2(this, false, "ReceivedMessage", true, new Object[] {msg});
ba.raiseEventFromDifferentThread(this, null, 0, "ReceivedMessage", false, null);
and
ba.raiseEvent(this, "ReceivedMessage");

but I don't get an event in b4a.

I don't find any good example lib with events.
 

DonManfred

Expert
Licensed User
Longtime User
Why i must install the jar in PROJECT-Folder? ALL other library are searching the original jar in libs-folder
They all have a line similar to
<dependsOn>asmack-android-19-0.8.10</dependsOn>
inside the XML. Maybe you need to use the dependson in your source...

Edit: I think you must include

@DependsOn(values={"asmack-android-19-0.8.10"})

in your library-source
 

birnesoft

Active Member
Licensed User
Longtime User
Now, new message makes an event.
Thanks to DonManfred for friendly support.

Lib:
@Events(values={"receivedmessage(g as String)"})
...
g=message.getBody();
ba.raiseEventFromDifferentThread(this, null, 0, "receivedmessage", false, new Object[] {g});


B4A:
Sub receivedmessage(g As String)
log (g)
end sub
 

lymey

Active Member
Licensed User
Longtime User
Now, new message makes an event.
Thanks to DonManfred for friendly support.

Lib:



B4A:
Hi! I have downloaded the library and the .jar file.
I am now trying to figure it out - I am happy to help you with this if I can - do you have a working sample project as a starting point?
 

lymey

Active Member
Licensed User
Longtime User
I am not sure about:
B4X:
SmackAndroidInit(Main.ac)
obviously it refers to a (context) value in your main activity.
Also
?
Can you fill me in?
Thanks
 

birnesoft

Active Member
Licensed User
Longtime User
I am not sure about:
B4X:
SmackAndroidInit(Main.ac)
obviously it refers to a (context) value in your main activity.
Also ?
Can you fill me in?
Thanks
gibg or getg is only a getter of the last message. You don't need this, because the receivemessage give u the massage.
I have a working project, but it's nearly 10 MB with the whole asmack in the classpath.

But I've updated the code in the example.

here is the code for the main activity

Sub Process_Globals
Dim ac As Object
End Sub

Sub Globals
Dim r As Reflector
End Sub


Sub Activity_Create(FirstTime As Boolean)
r.Target=Activity
ac=r.GetContext
startservice(chatservice)
end sub

sub msgTitle(msg as string)
activity.title=msg
end sub
 
Last edited:

lymey

Active Member
Licensed User
Longtime User
gibg or getg is only a getter of the last message. You don't need this, because the receivemessage give u the massage.
I have a working project, but it's nearly 10 MB with the whole asmack in the classpath.

But I've updated the code in the example.

here is the code for the main activity

Great thanks.
Can you confirm where you reference the asmack library - where did you put it? In your project directory or the B4A libs directory?
java.lang.NoClassDefFoundError: org.jivesoftware.smack.SmackAndroid
 
Top