I'm currently using asmack against an XMPP server which has XEP-0198 enabled.
I'm trying to enable this feature from the asmack library but I could not find any info on how to do this, so following http://xmpp.org/extensions/xep-0198.html I know I have to enable this feature by sending:
<enable xmlns='urn:xmpp:sm:3'/>
But I have no idea on how to do this, since this is not a stanza. Any help is appreciated.
EDIT:
As dant3 has pointed out XEP-0198 is not supported in Smack but I still want to enable it by sending that simple XML through Smack, I just have no idea how to do that.
It looks like smack do not have XEP-0198 implementation. So, you can't enable it.
It would be nice if you contribute it for smack (and thus - for asmack).
EDIT:
Smack 4.1.0 having now support of XEP-0198 stream management. See this wiki page for details.
I solved it by creating my own type of Package:
public class MyPacket extends Packet
{
private String content = "";
public MyPacket(String content)
{
this.content = content;
}
#Override
public String toXML()
{
return this.content;
}
}
I pass the xml in the constructor and then off it goes:
MyPacket p = new MyPacket("<enable xmlns='urn:xmpp:sm:3'/>");
this.connection.sendPacket(p);
Definitely not the best code in the world but it works.
Related
I am relatively new to MQTT and am trying to connect via a websocket in my Android app.
HiveMQ and Paho seem to be the most commonly used libraries, so I'll try my luck with those for now.
Unfortunately I got right at the first library and would need a hint on how to proceed, as the docs don't say anything about this unfortunately.
With HiveMQ, it's not entirely clear to me how to connect via websocket, and how to customize my credentials/headers, because I need to add some custom header like "x-amz-customauthorizer-name" and some more.
This is my attempt without adding the user credentials:
val client = Mqtt3Client.builder()
.identifier(UUID.randomUUID().toString())
.serverAddress(InetSocketAddress(result.data.webSocketServer, 443))
.sslWithDefaultConfig()
.addConnectedListener { context: MqttClientConnectedContext? -> Log.e(javaClass.simpleName, "mqtt Here Connected Yay") }
.addDisconnectedListener { context: MqttClientDisconnectedContext -> Log.e(javaClass.simpleName, "mqtt Disconnected: " + context.cause.message!!) }
.buildAsync()
client.connect()
you just need to add the webSocketConfig to the builder, something like this:
Mqtt3Client client = Mqtt3Client.builder()
.identifier(UUID.randomUUID().toString())
.serverAddress(new InetSocketAddress("localhost", 443))
.sslWithDefaultConfig()
this line-> .webSocketConfig(MqttWebSocketConfig.builder().subprotocol("mqtt").serverPath("/mqtt").build())
.buildAsync();
But I'm think you can't add custom headers yet, see https://github.com/hivemq/hivemq-mqtt-client/issues/457.
Greetings,
Michael
I am creating one chatting application which will work on both iOS and Android platform. Sometimes 'both' subscription is not received at both end. Can anyone tell me what can be the possible issue?
===================== For iOS =====================
Sending request,
XMPPJID *XMPPJIDObj=[XMPPJID jidWithString:aStrOtherJabberId];
[appDelegateObj.xmppRoster addUser:XMPPJIDObj withNickname:nil];
Accepting request,
[appDelegateObj.xmppRoster acceptPresenceSubscriptionRequestFrom:aReceiverJID andAddToRoster:TRUE];
Removing user,
[appDelegateObj.xmppRoster removeUser:[XMPPJID jidWithString:aPresenceObj.userJabberID]];
===================== For Android =====================
Sending request,
Roster.setDefaultSubscriptionMode(SubscriptionMode.manual);
myApp.getXmppConnection().getRoster().createEntry(visitorJabberId, visitorUserName, null);
Accepting request,
final Presence presence1 = new Presence(Type.subscribed);
presence1.setFrom(myApp.getUserJabberId());
presence1.setType(Type.subscribed);
presence1.setTo(visitorJabberId);
myApp.getXmppConnection().sendPacket(presence1);
myApp.getXmppConnection().getRoster().createEntry(visitorJabberId, visitorUserName, null);
Removing user,
final RosterPacket rosterPacket = new RosterPacket();
rosterPacket.setType(IQ.Type.SET);
final RosterPacket.Item item = new RosterPacket.Item(visitorJabberId, null);
item.setItemType(RosterPacket.ItemType.remove);
rosterPacket.addRosterItem(item);
myApp.getXmppConnection().sendPacket(rosterPacket);
Hi Leena for the iOS we have used save thing but I think you have forgot some thing. The actual flow is call add user method of roster class then call subscribe method with subscription value YES and finally send presence tag with subscribe type to the serve. Following are the code here I used XMPPSharedPreference singleton class rather than appdelegate. Hope this will work for you...
XMPPJID *newBuddy = [XMPPJID jidWithString:JIDString];
[[XMPPSharedPreference sharedPreferences].xmppRoster addUser:newBuddy withNickname:#"nicknameValue"];
[[XMPPSharedPreference sharedPreferences].xmppRoster acceptPresenceSubscriptionRequestFrom:newBuddy andAddToRoster:YES];
NSXMLElement *presence = [NSXMLElement elementWithName:#"presence"];
[presence addAttributeWithName:#"to" stringValue:JIDString];
[presence addAttributeWithName:#"type" stringValue:#"subscribe"];
[[self xmppStream] sendElement:presence];
When you add a user to your roster you have to make sure you also subscribe to the friend's presence. That completes the cycle.
So, for iOS for example, you're adding a friend to roster like this:
[appDelegateObj.xmppRoster addUser:XMPPJIDObj withNickname:nil];
But you need to do use this instead:
- (void)addUser:(XMPPJID *)jid withNickname:(NSString *)optionalName groups:(NSArray *)groups subscribeToPresence:(BOOL)subscribe
and make sure you set subscribe to YES
Or, you could keep the code you have but manually subscribe to the user's presence by doing this:
[appDelegateObj.xmppRoster subscribePresenceToUser:XMPPJIDObj]
Let me know how that works out for you.
I am using the new Embarcadero AppMethod 1.14 to do some development for Android Devices (in C++), but I cannot for the life of me figure out how to gain access to the lifecycle events (doPAuse, doResume, etc). If anyone has any how-to's links, tips or code they can share on this subject?
Here is the code I finally came up with:
TGUID guid = StringToGUID("{F3AAF11A-1678-4CC6-A5BF-721A24A676FD}"); // GUID for ApplicationEventService interface
IInterface *AEventSvc;
if (TPlatformServices::Current->SupportsPlatformService(guid)) {
AEventSvc = TPlatformServices::Current->GetPlatformService(guid);
IFMXApplicationEventService *EventSvc;
AEventSvc->QueryInterface(guid,(void**)(&EventSvc));
EventSvc->SetApplicationEventHandler(SysEventHandler);
EventSvc->Release();
}
Kudos out to Pawel Glowaki whose blog gave me the key details to getting this answer: http://blogs.embarcadero.com/pawelglowacki/2013/09/30/40067/
Sorry for lame and easy question but I failed to find an answer to it.
Every time I print something to the System.Diagnostics.Debug.WriteLine I have my message tripled:
System.Diagnostics.Debug.WriteLine("test");
Output:
[0:]
test
[0:] test
10-22 19:57:13.981 I/mono-stdout( 1026): test
I'm stick to System.Diagnostic.Debug because I write messages from both UI part (monodroid) and business logic (PCL)
Is there any way to descrease level of debug noise of Xamarin.Android?
Thank you for any suggestions.
Make your own little abstraction. We have the same issue in our project, this little Interface helps:
public interface ILogger
{
void Write(LogLevel level, String tag, String message);
}
Then you have your Loggers for each platform, for example:
public class AndroidLogger: ILogger
{
public void Write(LogLevel level, string tag, string message)
{
Android.Util.Log.WriteLine(ConvertLogLevel(level), tag, message);
}
}
You inject the logger in the iOS/Android project and you can even create fancy logger like e.g. a nice file-logger for iOS:
#if DEBUG
LOG.AddLogger(new TouchFileLogger());
LOG.AddLogger(new ConsoleLogger());
#endif
The LOG-class is static and needs not to know about the implementations, thats why it can be easily used in your shared PCL library.
Hope that helps, despite your problem might be solved by now ;-)
You can use Android.Util.Log instead, this greatly decreases it. It also has different levels of logging which you can filter in logcat.
Info: Log.Info()
Debug: Log.Debug()
Warning: Log.Warn()
Error: Log.Error()
Verbose: Log.Verbose()
and additionally a WriteLine, which does all of the above:
Log.WriteLine()
Hello Everyone i am new to android and i am currently stuck on this.
I have to return list of public rooms created on xmpp server. The problem i am having is that the code below works fine for java but there is a null pointer exception in case of android.
Any help regarding this would be appreciated.
I am using an openfire server and testing it on local machine so that is the reason why i am using ip Address instead of domain name.
I am using smack library for JAVA and Asmack Library for android
String server_name = "192.168.3.113";
ConnectionConfiguration config = new ConnectionConfiguration(
server_name, 5222);
XMPPConnection connection = new XMPPConnection(config);
try {
connection.connect();
connection.login("s1", "123");
Collection<HostedRoom> rooms = MultiUserChat.getHostedRooms(
connection, "conference.geekoid");
for (HostedRoom room : rooms) {
System.out.println(room.getName());
}
} catch (XMPPException e) {
System.out.println("Error" + e.getMessage() + "\n"); //for JAVA
log.e("Android Error",e.getmessage()); // For Android
}
The problem is that the static block of the ServiceDiscoveryManager class has to be evaluated before any connection is created. In smack this is done via an configuration file, but this approach does not work on Android and therefore on aSmack.
The workaround mentioned in the answer is somehow ugly, since you really don't want to use the Constructor to fetch the SDM object, instead the get() method should be used. But the get() method only works if there was actually a SDM created for the connection.
So in order to init the SDM correctly on Android you need to call the full forName notation to init the static blocks of the class before you create the first (XMPP)Connection object.
Class.forName("org.jivesoftware.smackx.ServiceDiscoveryManager", true, ClassLoader.getSystemClassLoader()):
This is tracked as aSmack Issue 8
I have found the Solution to the problem.
The Android asmack library was using this in
getHostedRooms(Connection connection,
String serviceName) method
ServiceDiscoveryManager discoManager =ServiceDiscoveryManager.getInstanceFor(connection);
i replaced it with
ServiceDiscoveryManager discoManager = new ServiceDiscoveryManager(connection);
For those who are confused where this method is its in
Package: org.jivesoftware.smackx.muc
File: MultiUserChat.java
After you have done this. We have to register all the providers in Android whose detail can be found here. These providers are automatically registered when are using JAVA's smack library (In java Development) but in Android we have to register them ourself.