I am developing chat application for one to one chat and group chat.
I have successfully done one to one chat.
Using the below link I have created Group chat.
Link to create Group chat in smack 4.2.0-beta1
I can see the group in admin panel but There is only a single user available, But I have created this group with three members.
Here I have added my code.
public void createGroupChat() {
String DomainName = "conference."+ServiceAddress;
// Create a MultiUserChat using a Connection for a room
// Get the MultiUserChatManager
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
try {
EntityBareJid jid = JidCreate.entityBareFrom("mychatroom3" + "#"
+ DomainName);
// Create a MultiUserChat using an XMPPConnection for a room
MultiUserChat muc = manager.getMultiUserChat(jid);
// Prepare a list of owners of the new room
Set<Jid> owners = JidUtil.jidSetFrom(new String[]{"admin" + "#"
+ DomainName, "dev1" + "#"
+ DomainName, "dev2" + "#"
+ DomainName});
// Create the room
Resourcepart nickname = Resourcepart.from("admin");
muc.create(nickname).getConfigFormManager().setRoomOwners(owners).submitConfigurationForm();
muc.join(nickname);
Log.e("Group chat", "Created");
Toast.makeText(context,
"Group chat" + "Created",
Toast.LENGTH_SHORT).show();
} catch (XmppStringprepException e) {
e.printStackTrace();
} catch (MultiUserChatException.MucAlreadyJoinedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (MultiUserChatException.MissingMucCreationAcknowledgeException e) {
e.printStackTrace();
} catch (NotConnectedException e) {
e.printStackTrace();
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (MultiUserChatException.NotAMucServiceException e) {
e.printStackTrace();
} catch (MultiUserChatException.MucConfigurationNotSupportedException e) {
e.printStackTrace();
}
}
Exception that I got
08-01 05:58:14.589 917-917/com.agarangroup.hello W/System.err: org.jivesoftware.smackx.muc.MultiUserChatException$MucConfigurationNotSupportedException: The MUC configuration 'muc#roomconfig_roomowners' is not supported by the MUC service
08-01 05:58:14.590 917-917/com.agarangroup.hello W/System.err: at org.jivesoftware.smackx.muc.MucConfigFormManager.setRoomOwners(MucConfigFormManager.java:137)
08-01 05:58:14.590 917-917/com.agarangroup.hello W/System.err: at com.agarangroup.hello.Services.MyXMPP.createGroupChat(MyXMPP.java:331)
08-01 05:58:14.590 917-917/com.agarangroup.hello W/System.err: at com.agarangroup.hello.slidingtab.chats.GroupChatActivity.onCreate(GroupChatActivity.java:99)
There are 2 cases:
1) Your conference service does not supports owners (depends by server, Ejabber in your case, and this doesn't sounds normal)
2) Your config form it's not completed as documentation says and you need to create a full form.
How to fix: substitute this line:
muc.create(nickname).getConfigFormManager().setRoomOwners(owners).submitConfigurationForm();
with:
muc.create(nickname);
Form form = muc.getConfigurationForm().createAnswerForm();
form.setAnswer("muc#roomconfig_roomowners", owners);
muc.sendConfigurationForm(form);
pay attention to names:
your DomainName it's the Service conference name + Server Domain Name.
An owner can be a JID (foo#myserver) and not related on service (so foo#service.myserver it's not a valid user, even if server will accept it).
Fix your owners with:
"admin" + "#" + ServiceAddress, "dev1" + "#" + ServiceAddress, "dev2" + "#" + ServiceAddress
Related
I am making a chat application with smack library and openfire as a server but everytime i exit the chat conversation activity between two users and come back, the whole chat gets erased. I have already enabled archive settings to store one to one messages in the server but i do not know how to implement it in the app.
I want to show chats history in recyclerview by the sender and the receiver in the recyclerview.
currently i have implemented this function which caused error
private void setChatHistory(String entityBareId) {
EntityBareJid jid = null;
try {
jid = JidCreate.entityBareFrom(entityBareId);
} catch (XmppStringprepException e) {
e.printStackTrace();
}
MamManager manager = MamManager.getInstanceFor(mConnection);
MamManager.MamQueryResult r = null;
try {
try {
r = manager.mostRecentPage(jid, 10);
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotLoggedInException e) {
e.printStackTrace();
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
}
if (r.forwardedMessages.size() >= 1) //printing first of them
{
Message message = (Message) r.forwardedMessages.get(0).getForwardedStanza();
Log.i("mam", "message received" + message.getBody());
MessagesData data = new MessagesData("send",message.getBody());
mMessagesData.add(data);
mAdapter = new ConversationAdapter(mMessagesData);
recyclerView.setAdapter(mAdapter);
}
}
Error was
Attempt to read from field 'java.util.List org.jivesoftware.smackx.mam.MamManager$MamQueryResult.forwardedMessages' on a null object reference
At r.forwardedmessages.size()>=1.
Thanks in advance
If you want to keep history of conversation, you must save them in database. MAM just for fetching old conversation from server like when you uninstall or logout the app and decide to reinstall and get old messages.
For getting messages from server be sure you already enabled it, then forwarded messages shouldnt be null. here is a guide to enable it.
I have built a chat application using an Openfire (xmpp) server. One-to-one person chats are working fine and the messages are delivered instantly. But when we send a message inside a group, the first message gets delayed and the second message is delivered instantly.
MultiUserChatManager groupChat =
MultiUserChatManager.getInstanceFor(connection).getMultiUserChat("group_name");
groupChat.send("Message object");
Why is the first message getting delayed?
MUC Creation is
MultiUserChatManager mchatManager = MultiUserChatManager.getInstanceFor(xmpptcpConnection);
MultiUserChat mchat = mchatManager.getMultiUserChat(group);
if (!mchat.isJoined()) {
Log.d("CONNECT", "Joining room !! " + group + " and username " + username);
boolean createNow = false;
try {
mchat.createOrJoin(username);
createNow = true;
} catch (Exception e) {
Log.d("CONNECT", "Error while creating the room " + group + e.getMessage());
}
if (createNow) {
Form form = mchat.getConfigurationForm();
Form submitForm = form.createAnswerForm();
List<FormField> formFieldList = submitForm.getFields();
for (FormField formField : formFieldList) {
if(!FormField.Type.hidden.equals(formField.getType()) && formField.getVariable() != null) {
submitForm.setDefaultAnswer(formField.getVariable());
}
}
submitForm.setAnswer("muc#roomconfig_persistentroom", true);
submitForm.setAnswer("muc#roomconfig_publicroom", true);
mchat.sendConfigurationForm(submitForm);
//mchat.sendConfigurationForm(
// new Form(DataForm.Type.submit)); //this is to create the room immediately after join.
}
}
Log.d("CONNECT", "Room created!!");
return true;
} catch (SmackException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
}
There's an issue about creation and a kind of side-effect propagated on sending.
I think simply that you need to join the chat the first time since you didn't before and the first message also activate the Groupchat on server, so the first message it's delayed because you didn't finalized the multiuserchat creation.
How to fix.
In creation phase, this part must be improved:
if (!mchat.isJoined()) {
Log.d("CONNECT", "Joining room !! " + group + " and username " + username);
boolean createNow = false;
try {
mchat.createOrJoin(username);
createNow = true;
} catch (Exception e) {
Log.d("CONNECT", "Error while creating the room " + group + e.getMessage());
}
With just:
boolean createNow
try
{
if (!mchat.isJoined())
{
createNow = mchat.createOrJoin(username);
}
}
catch (Exception e)
{
throw new Exception("ERROR!");
}
and after this invokation:
mchat.sendConfigurationForm(submitForm);
add:
if (!mchat.isJoined()) {
mchat.join(username);
}
creationOrJoin method it's about creation OR join (as name says): to activate the chat, you must join it after the creation phase.
However createOrJoin has maybe an unexpected behaviour due a double check about already joined rooms to keep syncro between session in client and session on server, so the mchat.join() must be invoked after.
An explicit name can sounds like: mustCreateBeforeOrCanJoinDirectly()
I am integrating Stripe in my android application.
I have found two issues and I am stuck.
First (and major) issue is -
I have got token key from the card information. But when I tried to make my first charge, it shows error in following line.
Stripe.apiKey = "sk_test_0000000000000";
I have googled also but couldn't find any solution.
Creating Stripe Customer - cannot resolve symbol apiKey
I have even seen this kind of question too. But I failed to understand its solution.
Following is my code for making charge:
final String publishableApiKey = BuildConfig.DEBUG ?
"pk_test_000000000000000000" :
//"sk_test_00000000000000000000000" :
getString(R.string.com_stripe_publishable_key);
final TextView cardNumberField = (TextView) findViewById(R.id.cardNumber);
final TextView monthField = (TextView) findViewById(R.id.month);
final TextView yearField = (TextView) findViewById(R.id.year);
TextView cvcField = (TextView) findViewById(R.id.cvc);
Card card = new Card(cardNumberField.getText().toString(),
Integer.valueOf(monthField.getText().toString()),
Integer.valueOf(yearField.getText().toString()),
cvcField.getText().toString());
Stripe stripe = new Stripe();
stripe.createToken(card, publishableApiKey, new TokenCallback() {
public void onSuccess(Token token) {
// TODO: Send Token information to your backend to initiate a charge
Toast.makeText(
getApplicationContext(),
"Charge Token created: " + token.getId(),
Toast.LENGTH_LONG).show();
/*make a charge starts*/
// Set your secret key: remember to change this to your live secret key in production
// Create the charge on Stripe's servers - this will charge the user's card
Stripe.apiKey = "sk_test_0000000000000000000000";
try {
Map<String, Object> chargeParams = new HashMap<String, Object>();
chargeParams.put("amount", 100); // amount in cents, again
chargeParams.put("currency", "usd");
chargeParams.put("source", token.getId());
chargeParams.put("description", "Example charge");
Charge charge = Charge.create(chargeParams);
System.out.println("Charge Log :" + charge);
} catch (CardException e) {
// The card has been declined
} catch (APIException e) {
e.printStackTrace();
} catch (AuthenticationException e) {
e.printStackTrace();
} catch (InvalidRequestException e) {
e.printStackTrace();
} catch (APIConnectionException e) {
e.printStackTrace();
}
/*charge ends*/
}
I have tried these code from different examples. I followed Stripe doc too.
But I got this error:
com.stripe.exception.AuthenticationException: No API key provided. (HINT: set your API key using 'Stripe.apiKey = '.
Second Issue is - about validation.
If I am entering my own card details, and if I write wrong cvv number. It still generates token key.
I have already implemented validation of fields using Stripe's official doc. I don't know how to validate it with real time data.
Solution for the First Issue:
com.stripe.Stripe.apiKey = "sk_test_xxxxxxxxxxxxxxxxxxx";
try {
final Map<String, Object> chargeParams = new HashMap<String, Object>();
chargeParams.put("amount", 500); // amount in cents, again
chargeParams.put("currency", "usd");
chargeParams.put("source", token.getId());
chargeParams.put("description", "Example charge");
new Thread(new Runnable() {
#Override
public void run() {
Charge charge = null;
try {
charge = Charge.create(chargeParams);
} catch (AuthenticationException e) {
e.printStackTrace();
} catch (InvalidRequestException e) {
e.printStackTrace();
} catch (APIConnectionException e) {
e.printStackTrace();
} catch (CardException e) {
e.printStackTrace();
} catch (APIException e) {
e.printStackTrace();
}
System.out.println("Charge Log :" + charge);
}
}).start();
} catch (Exception e) {
e.printStackTrace();
}
Stripe's Android bindings only let you tokenize card information. Once the token has been created, it must be sent to an external server where you can use it in API requests.
You cannot use the token directly from the app as the app must never have access to your secret key, where it could easily be extracted by an attacker who would then have access to your account.
Re. your second question, the card isn't validated with the bank when the token is created (there are still some basic sanity checks, such as checking the number of digits, the fact that the expiry date is in the future, etc.). It is only when you use the token in a server-side API request that the card will be checked with the bank.
I am using the below code to create Multi user group but getting Timeout error, even if my timeout error is 10sec.
public void createGroup() {
String roomId = "Group_test003" + "#icoveri.com";
String nick = "Grouptest";
try {
MultiUserChatManager manager = multiUserChatManager.getInstanceFor(connection);
MultiUserChat muc = manager.getMultiUserChat(roomId);
muc.create(nick);
Form form = muc.getConfigurationForm();
Form submitForm = form.createAnswerForm();
List<FormField> fields = form.getFields();
for (int i = 0; i < fields.size(); i++) {
FormField field = (FormField) fields.get(i);
if (!FormField.Type.hidden.equals(field.getType()) && field.getVariable() != null) {
submitForm.setDefaultAnswer(field.getVariable());
}
}
List owners = new ArrayList();
owners.add(user1234 + "#icoveri.com");
submitForm.setAnswer("muc#roomconfig_roomowners", owners);
muc.sendConfigurationForm(submitForm);
} catch (XMPPException e) {
e.printStackTrace();
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (SmackException e) {
e.printStackTrace();
}
}
The error which I am getting is
org.jivesoftware.smack.SmackException$NoResponseException: No response
received within reply timeout. Timeout was 10000ms (~10s). Used
filter: AndFilter: (FromMatchesFilter (full):
Group_test003#iscoveri.com/Grouptest, StanzaTypeFilter:
org.jivesoftware.smack.packet.Presence).
at
org.jivesoftware.smack.PacketCollector.nextResultOrThrow(PacketCollector.java:229)
at
org.jivesoftware.smackx.muc.MultiUserChat.enter(MultiUserChat.java:311)
at
org.jivesoftware.smackx.muc.MultiUserChat.createOrJoin(MultiUserChat.java:400)
at
org.jivesoftware.smackx.muc.MultiUserChat.createOrJoin(MultiUserChat.java:376)
I have got the solution. The problem was in my service i.e. iscoveri.com. I had to use different service name to create the group.
I also have spent a couple hours trying to correct the same error; in my case, the problem happened when I used XMPPBOSHConnection, but not when using XMPPTCPConnection.
I could build a sip profile using SipProfile.Builder class. I used following snippet of code to do it:
if (SipManager.isApiSupported(MyActivity.this)&& SipManager.isVoipSupported(MyActivity.this)) {
SipManager manager=SipManager.newInstance(this);
SipProfile.Builder builder;try {
builder = new Builder(userName,domainName);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} manager = SipManager.newInstance(MyActivity.this);
builder.setPassword(password);
profile = builder.build();
try {
manager.open(profile);
} catch (SipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
manager.register(profile, 30, MyActivity.this);
} catch (SipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Toast.makeText(MyActivity.this, "created",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MyActivity.this, "Not Supported",
Toast.LENGTH_LONG).show();
}
It shows as a sip account in the settings/callsettings/Internet call settings.
Problem is i could not make it as primary account. How can i make it as primary account?
This information is account-based (primary email address for person, primary phone number, primary SIP account etc.) so it's stored in the phone's contacts-book.
It seems to me it's an option that is set per-data, per-account (for example: this type of data (email/phone/sip-addr) set it as primary).
You can set data as primary for a contact using IS_PRIMARY or IS_SUPER_PRIMARY
IS_PRIMARY: Whether this is the primary entry of its kind for the raw
contact it belongs to.
The data you should use it on is ContactsContract.CommonDataKinds.SipAddress. I hope that's useful as starting point.