Android Pusher Singleton channel subscription - android

Hello I have implemented pusher for realtime chat and subscribing to pusher channel , but I have many activities and fragments where i want to listen to pushr events . I have added this code in every activity/fragment but the problem is that it creates multiple subscriptions for every id . I know that i have to use Singleton for this can anyone point me in the right direction to achieve this ?
Here is the code i am writing in every activity/fragment
private PusherOptions options;
private Channel channel;
private Pusher pusher;
options = new PusherOptions();
options.setCluster("ap2");
pusher = new Pusher("afbfc1f591fd7b70190f", options);
pusher.connect();
profile_id = Global.shared().preferences.getString("PROFILE_ID", " ");
channel = pusher.subscribe(profile_id);
channel.bind("message",
new SubscriptionEventListener() {
#Override
public void onEvent(String s, String s1, final String data) {
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
JSONObject result = new JSONObject(data);
String message = result.getString("message");
String time = result.getString("time");
String reId = result.getString("recieverId");
new_message = message;
getConvoData(k, message);
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println("DATA ====>>" + data);
}
});
}
});

okay so after trying for a while i figured it out my self i created a global class and just added pusher code to it so that it maintains just one connection for the entire lifecycle of the app
public class Global extends MultiDexApplication {
#Override
public void onCreate() {
super.onCreate();
SharedPreferences preferences = sharedInstance.getSharedPreferences(sharedInstance.getString(R.string.shared_preferences), Context.MODE_PRIVATE);
sharedInstance.preferences = preferences;
connectTopusher();
}
public void connectTopusher() {
PusherOptions options;
Channel channel;
Pusher pusher;
options = new PusherOptions();
options.setCluster("ap2");
pusher = new Pusher("afbfc1f591fd7b70190f", options);
pusher.connect();
String profile = Global.shared().preferences.getString("PROFILE_ID", "");
channel = pusher.subscribe(profile);
channel.bind("message",
new SubscriptionEventListener() {
#Override
public void onEvent(String s, String s1, final String data) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
try {
JSONObject result = new JSONObject(data);
String message = result.getString("message");
String time = result.getString("time");
String reId = result.getString("recieverId");
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println("DATA ====>>" + data);
}
});
}
});
channel.bind("status_change", new SubscriptionEventListener() {
#Override
public void onEvent(String s, String s1, final String data) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
try {
JSONObject result = new JSONObject(data);
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println("DATA ====>>" + data);
}
});
}
});
}

You can expose channel in your Global class. That will allow you to call bind and unbind in your fragments, when they are in the foreground.
connectToPusher should just create a channel and subscribe to it.
In Global.java:
private Channel channel;
public void connectTopusher() {
PusherOptions options;
Pusher pusher;
options = new PusherOptions();
options.setCluster("ap2");
pusher = new Pusher("afbfc1f591fd7b70190f", options);
pusher.connect();
String profile = Global.shared().preferences.getString("PROFILE_ID", "");
this.channel = pusher.subscribe(profile);
}
public Channel getChannel(){
return this.channel;
}
And then in your activity/fragment you can bind/unbind your listeners to when they are resumed/paused - just keep a reference to it like this:
YourActivity.java (could also be your Fragment)
private SubscriptionEventListener messageListener = new SubscriptionEventListener(){
#Override
public void onEvent(String channel, String event, String data) {
//TODO: do something with events
}
}
//Bind when the listener comes into the foreground:
#Override
protected void onResume() {
super.onResume();
((Global) getActivity().getApplication()).getChannel().bind("message", messageListener);
}
//Make sure to unbind the event listener!
#Override
protected void onPause() {
super.onPause();
((Global) getActivity().getApplication()).getChannel().unbind("message", messageListener);
}
I hope this helps :)

Related

Withings API integration in android

I am building Android App which shows Withings user's activity data in my Application.
But when I am trying to call refresh_token url:
https://oauth.withings.com/account/request_token?oauth_callback=******&oauth_consumer_key=******&oauth_nonce=******&oauth_signature=CcMrI7JaI8M5tEenye3s95wx%2BZ4%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1477386344&oauth_version=1.0
Then I am getting Invalid Signature response like below:
{
"status":0,
"message":"Invalid signature :\n CcMrI7JaI8M5tEenye3s95wx+Z4= .. \n{\"oauth_callback\":\"******\",\"oauth_consumer_key\":\"ce54bd6c671546ef8f8d394c0db4bd86688289d5f7fb39f371c5ebce4d01\",\"oauth_nonce\":\"f339febe0fdf4b53b953501e45a049db\",\"oauth_signature\":\"CcMrI7JaI8M5tEenye3s95wx+Z4=\",\"oauth_signature_method\":\"HMAC-SHA1\",\"oauth_timestamp\":\"1477386344\",\"oauth_version\":\"1.0\"}\n{\"base_string\":\"GET&https%3A%2F%2Foauth.withings.com%2Faccount%2Frequest_token&oauth_callback%3D******%26oauth_consumer_key%3D******%26oauth_nonce%3Df339febe0fdf4b53b953501e45a049db%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1477386344%26oauth_version%3D1.0\"}\n{\"key\":\"******\",\"secret\":\"******\",\"callback_url\":null}"
}
First of all you can use the scribe lib
On my sample code I have an Authentication Activity that has an WebView that the user uses to verify the app. Then that Authentication Activity sends back to the MainActivity the response.
On my example I am storing locally on a DB the authenticated user to not ask every time the credentials.
Also I am sending the access token to python server that will get all data stored on Withings Cloud to save it to my Server DB and represent them on a Graph Activity. {I have removed that part}
Because of the copy paste maybe something is missing but most of the code is here
public class WithingsApi extends DefaultApi10a {
private static final String AUTHORIZATION_URL ="https://oauth.withings.com/account/authorize?oauth_token=%s";
private static final String apiKey = "API_KEY";
private static final String apiSecret = "API_SECRET";
#Override
public String getRequestTokenEndpoint() {
return "https://oauth.withings.com/account/request_token";
}
#Override
public String getAccessTokenEndpoint() {
return "https://oauth.withings.com/account/access_token";
}
#Override
public String getAuthorizationUrl(Token requestToken) {
return String.format(getAUTHORIZATION_URL(), requestToken.getToken());
}
public static String getKey(){
return apiKey;
}
public static String getSecret(){
return apiSecret;
}
public static String getAUTHORIZATION_URL() {
return AUTHORIZATION_URL;
}
}
#SuppressLint("SetJavaScriptEnabled")
public class AuthenticationActivity extends Activity {
final String LOGTAG = "WITHINGS";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_authentication);
final WebView wvAuthorise = (WebView) findViewById(R.id.wvAuthorise);
wvAuthorise.getSettings().setJavaScriptEnabled(true);
wvAuthorise.setWebViewClient(new MyWebViewClient(wvAuthorise));
MainActivity.service = new ServiceBuilder().provider(WithingsApi.class)
.apiKey(WithingsApi.getKey())
.apiSecret(WithingsApi.getSecret())
.build();
new Thread(new Runnable() {
public void run() {
MainActivity.requestToken = MainActivity.service.getRequestToken();
final String authURL = MainActivity.service.getAuthorizationUrl(MainActivity.requestToken);
wvAuthorise.post(new Runnable() {
#Override
public void run() {
wvAuthorise.loadUrl(authURL);
}
});
}
}).start();
}
class MyWebViewClient extends WebViewClient{
WebView wvAuthorise;
MyWebViewClient(WebView wv){
wvAuthorise = wv;
}
#Override
public void onPageFinished(WebView view, String url) {
getUSERID(url);
}
}
private void getUSERID(final String url) {
try {
String divStr = "userid=";
int first = url.indexOf(divStr);
if(first!=-1){
final String userid = url.substring(first+divStr.length());
Intent intent = new Intent();
intent.putExtra("USERID",userid);
setResult(RESULT_OK,intent);
finish();
}
else
{
//...
}
} catch (Exception e) {
Log.e(LOGTAG,e.getMessage());
//...
}
}
}
public class MainActivity extends FragmentActivity {
public static OAuthService service;
public static Token requestToken;
String secret, token;
Token accessToken;
String userId = "";
private UsersDataSource datasource;
private TextView nameTV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_mainActivity = this;
nameTV = (TextView) findViewById(R.id.nameTitleTextView);
nameTV.setText("--");
getCredentials();
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == AUTHENTICATION_REQUEST) {
if (resultCode == RESULT_OK) {
Bundle extras = intent.getExtras();
if (extras != null) {
userId = extras.getString("USERID");
getAccessTokenThread.execute((Object) null);
}
}
}
}
#Override
protected void onResume() {
datasource.open();
super.onResume();
}
#Override
protected void onPause() {
datasource.close();
super.onPause();
}
private void getCredentials() {
try {
datasource = new UsersDataSource(this);
datasource.open();
List<User> users = datasource.getAllUsers();
if (users.isEmpty()) {
startAuthenticationActivity();
} else {
// TODO load all users and if isn't anyone correct
// startAuthenticationActivity
secret = users.get(0).getSecret();
token = users.get(0).getToken();
userId = users.get(0).getUserId();
Log.i(LOGTAG, "secret : " + secret);
Log.i(LOGTAG, "token : " + token);
Log.i(LOGTAG, "userId : " + userId);
try {
service = new ServiceBuilder().provider(WithingsApi.class)
.apiKey(WithingsApi.getKey())
.apiSecret(WithingsApi.getSecret()).build();
accessToken = new Token(token, secret);
loadData();
} catch (Exception ex) {
startAuthenticationActivity();
}
}
} catch (Exception ex) {
Log.e(LOGTAG, "try on create" + ex.getLocalizedMessage());
}
}
private void startAuthenticationActivity() {
Intent intent = new Intent(this,
ics.forth.withings.authentication.AuthenticationActivity.class);
startActivityForResult(intent, AUTHENTICATION_REQUEST);
}
AsyncTask<Object, Object, Object> getAccessTokenThread = new AsyncTask<Object, Object, Object>() {
#Override
protected Object doInBackground(Object... params) {
accessToken = service
.getAccessToken(requestToken, new Verifier(""));
secret = accessToken.getSecret();
token = accessToken.getToken();
return null;
}
#Override
protected void onPostExecute(Object result) {
// authentication complete send the token,secret,userid, to python
datasource.createUser(token, secret, userId);
loadData();
};
};
}
UPDATE
OAuthService class is from Scribe
Token class is from Scribe
UserDataSource class is a DB Helper Class more here

Get a string value out of a thread

I have a String variable, and I set it's value inside a thread, since it's using a netwok operation.
How can I access the values stored in the Strings?
public class HomeActivity extends AppCompatActivity {
// Initialize AWS DynamoDB Client
public static AmazonDynamoDBClient ddbClient;
public static DynamoDBMapper mapper;
public static Aqua aqua;
// App details
public static String a = "A";
public static String b;
public static Boolean c;
public static String d;
public static String e;
public static String f;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// Initialize the Amazon Cognito credentials provider
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(),
"******", // Identity Pool ID
Regions.**** // Region
);
// Initialize AWS DynamoDB
ddbClient = new AmazonDynamoDBClient(credentialsProvider);
mapper = new DynamoDBMapper(ddbClient);
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
// Get app details
aqua = mapper.load(Aqua.class, a);
b = aqua.getB();
c = aqua.getC();
d = aqua.getD();
e = aqua.getE();
f = aqua.getF();
} catch (Exception e) {
Log.e("error", e.getMessage());
}
}
});
thread.start();
}
}
Use ExecutorService and submit Callable (below assumes you want the data that is stored inside b,c,d,e,f):
ExecutorService exec = Executors.newSingleThreadExecutor();
Future<String[]> future = exec.submit(new Callable<String[]>() {
#Override
public String[] call() {
try {
// Get app details
aqua = mapper.load(Aqua.class, a);
b = aqua.getB();
c = aqua.getC();
d = aqua.getD();
e = aqua.getE();
f = aqua.getF();
} catch (Exception e) {
Log.e("error", e.getMessage());
}
return new String[] {b, c, d, e, f};
}
});
// ... b will be at value[0], c at value[1]
String[] value = future.get();
Declare the string globally in your Activity/Fragment. This way you can acces it from everywhere.
You could also use handler.sendMessage(message); with your String as message to send it whenever your Thread has finished or whenever you want to. You can then retrieve your String int
protected Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
String status = (String) msg.obj;
Log.i("Got a new message", "MESSAGE: "+status);
}
};
Hope it helps :)

How to transfer data from a socket.io Service to an Activity

Currently, I have a Service that is supposed to keep a socket.io connection open for multiple different Activitys to use. One of the biggest functions of the application is to update an album-art gallery whenever a song is added to a playlist. The Node.js server broadcasts if a song is added, and my goal is for the SocketService to update the UI when .on("song added"... is triggered. However, currently, I cannot figure out how to transfer the incoming data to the UI from the SocketService. How would I go about doing this?
For reference:
The "song add" command from the server emits a JSONObject.
public class SocketService extends IntentService {
Socket socket;
String roomID;
String userID;
ArrayList<JSONObject> queuedSongs;
ArrayList<JSONObject> suggestionSongs;
int users;
public SocketService() {
super("SocketService");
}
#Override
protected void onHandleIntent(Intent intent) {
userID = intent.getExtras().getString("userid", "0");
Log.i("SocketService", "userID=" + userID);
roomID = intent.getExtras().getString("code");
Log.i("SocketService", "roomID=" + roomID);
super.onCreate();
try {
socket = IO.socket("server address");
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.i("Internet-Task", "Connected to "server address"");
}
}).on("song add", new Emitter.Listener() {
#Override
public void call(Object... args) {
try {
suggestionSongs.add(new JSONObject(args[0].toString()));
} catch (JSONException e) {
e.printStackTrace();
}
}
});
//**//
socket.io().on(Manager.EVENT_TRANSPORT, new Emitter.Listener() {
#Override
public void call(Object... args) {
Transport transport = (Transport) args[0];
transport.on(Transport.EVENT_REQUEST_HEADERS, new Emitter.Listener() {
#Override
public void call(Object... args) {
#SuppressWarnings("unchecked")
Map<String, List<String>> headers = (Map<String, List<String>>) args[0];
// modify request headers
headers.put("userid", Arrays.asList(userID));
headers.put("roomid", Arrays.asList(roomID));
}
});
socket.connect();
} catch (URISyntaxException e) {
Log.e(getClass().getCanonicalName(), e.toString());
}
Additionally, here is the call to the service made in the Activity onCreate(). No new thread is made prior.
protected void onCreate(Bundle savedInstanceState) {
...
Intent serviceIntent = new Intent(getBaseContext(), SocketService.class);
Bundle serviceBundle = new Bundle();
serviceBundle.putString("code", roomID);;
serviceBundle.putString("userid", userID);
serviceIntent.putExtras(mBundle);
startService(serviceIntent);
Again, my question is: How do I transfer data from my SocketService to the UI of my Activity?

Android Pusher not connecting to Private Channels

I am trying to implement pusher chat in my Android Application, i am able to connect with pusher, got the response as CONNECTED. But not able to connect to Private channels(Local server). Can anyone help on this.
adding the code below.
Thanks in advance
final HttpAuthorizer authorizer = new HttpAuthorizer(myurl);
authorizer.setHeaders(getMapAuthorizationHeaders());
PusherOptions options = new PusherOptions().setAuthorizer(authorizer);
final Pusher pusher = new Pusher("pusher_key", options);
pusher.connect(new com.pusher.client.connection.ConnectionEventListener() {
#Override
public void onConnectionStateChange(ConnectionStateChange connectionStateChange) {
Log.e("connectionStateChange" , connectionStateChange.getCurrentState().toString());
if (connectionStateChange.getCurrentState() == ConnectionState.CONNECTED) {
SOCKET_ID = pusher.getConnection().getSocketId();
Log.e("SOCKET_ID" , ""+SOCKET_ID);
Channel channel = pusher.subscribePrivate(PUSH_CHANNEL, new PrivateChannelEventListener() {
#Override
public void onAuthenticationFailure(String s, Exception e) {
Log.e("PUSHER", "Channel subscription authorization failed");
}
#Override
public void onSubscriptionSucceeded(String s) {
Log.e("PUSHER", "Channel subscription authorization succeeded");
}
#Override
public void onEvent(String s, String s2, String s3) {
Log.e("PUSHER", "An event with name " + s2 + " was delivered!!");
}
}, "my-event");
}
}
#Override
public void onError(String s, String s1, Exception e) {
}
});
public static HashMap<String, String> getMapAuthorizationHeaders() {
try {
HashMap<String, String> authHeader = new HashMap<>();
authHeader.put("HeaderKey1", "HeaderValue1");
authHeader.put("HeaderKey2", "HeaderValue2");
return authHeader;
} catch (Exception e) {
return null;
}
}
Can I assume that where you've put "pusher_key", you've just added this for security purposes on here, and in your application you're actually using your key?
Other than that, where are you defining PUSH_CHANNEL for: pusher.subscribePrivate(PUSH_CHANNEL,

Quickblox android sdk groupchat

I'm using quickblox sdk group chat.
This is my code. But I still wrong. Can anybody guide me, please?
UserListForGroupActivity.java
public class UserListForGroupActivity extends Activity implements QBCallback {
private ListView usersList;
private ProgressDialog progressDialog;
private Button btnChat;
private SimpleAdapter usersAdapter;
private ArrayList<Friend_Users> friends= new ArrayList<Friend_Users>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_list_for_group);
usersList = (ListView) findViewById(R.id.usersList);
btnChat=(Button)findViewById(R.id.btnstartGroupChat);
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Loading fiends list");
progressDialog.show();
// ================= QuickBlox ===== Step 4 =================
// Get all users of QB application.
QBUsers.getUsers(this);
}
#Override
public void onComplete(Result result) {
if (result.isSuccess()) {
if (progressDialog != null) {
progressDialog.dismiss();
}
// Cast 'result' to specific result class QBUserPagedResult.
QBUserPagedResult pagedResult = (QBUserPagedResult) result;
final ArrayList<QBUser> users = pagedResult.getUsers();
System.out.println(users.toString());
// Prepare users list for simple adapter.
ArrayList<Map<String, String>> usersListForAdapter = new ArrayList<Map<String, String>>();
for (QBUser u : users) {
Map<String, String> umap = new HashMap<String, String>();
umap.put("userLogin", u.getLogin());
umap.put("chatLogin", QBChat.getChatLoginFull(u));
usersListForAdapter.add(umap);
}
// Put users list into adapter.
usersAdapter = new SimpleAdapter(this, usersListForAdapter,
android.R.layout.simple_list_item_multiple_choice,
new String[]{"userLogin", "chatLogin"},
new int[]{android.R.id.text1, android.R.id.text2});
usersList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
usersList.setAdapter(usersAdapter);
btnChat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
SparseBooleanArray checked= usersList.getCheckedItemPositions();
for (int i = 0; i < checked.size(); i++) {
// Item position in adapter
int position = checked.keyAt(i);
// Add sport if it is checked i.e.) == TRUE!
if (checked.valueAt(i))
{
QBUser friendUser = users.get(position);
String login, password;
int id;
id=friendUser.getId();
login=friendUser.getLogin();
password=friendUser.getPassword();
friends.add(new Friend_Users(id,login, password));
}
}
Friend_Users_Wrapper wrapper= new Friend_Users_Wrapper(friends);
Log.e("UserListForGroupAcitvity friend list pass intent=>", friends.size()+ friends.get(0).getLogin());
Bundle extras = getIntent().getExtras();
Intent intent=new Intent(UserListForGroupActivity.this, GroupChatActivity.class);
intent.putExtra("friends", wrapper);
intent.putExtras(extras);
startActivity(intent);
}
});
} else {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setMessage("Error(s) occurred. Look into DDMS log for details, " +
"please. Errors: " + result.getErrors()).create().show();
}
}
#Override
public void onComplete(Result result, Object context) { }
}
GroupChatActivity.java
public class GroupChatActivity extends Activity {
private EditText messageText;
private TextView meLabel;
private TextView friendLabel;
private ViewGroup messagesContainer;
private ScrollView scrollContainer;
private QBUser me;
private GroupChatController groupChatController;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat);
// Load QBUser objects from bundle (passed from previous activity).
Bundle extras = getIntent().getExtras();
Friend_Users_Wrapper wrapper= (Friend_Users_Wrapper) getIntent().getSerializableExtra("friends");
ArrayList<Friend_Users> friendArray= wrapper.getFriend_Users();
me = new QBUser();
me.setId(extras.getInt("myId"));
me.setLogin(extras.getString("myLogin"));
me.setPassword(extras.getString("myPassword"));
System.out.println("user login =>"+extras.getString("myLogin"));
QBUser friends= new QBUser();
for (Friend_Users friend_Users : friendArray) {
friends.setId(friend_Users.getId());
friends.setLogin(friend_Users.getLogin());
friends.setPassword(friend_Users.getPassword());
}
// UI stuff
messagesContainer = (ViewGroup) findViewById(R.id.messagesContainer);
scrollContainer = (ScrollView) findViewById(R.id.scrollContainer);
Button sendMessageButton = (Button) findViewById(R.id.sendButton);
sendMessageButton.setOnClickListener(onSendMessageClickListener);
messageText = (EditText) findViewById(R.id.messageEdit);
// ================= QuickBlox ===== Step 5 =================
// Get chat login based on QuickBlox user account.
// Note, that to start chat you should use only short login,
// that looks like '17744-1028' (<qb_user_id>-<qb_app_id>).
String chatLogin = QBChat.getChatLoginShort(me);
// Our current (me) user's password.
String password = me.getPassword();
if (me != null && friends != null) {
// ================= QuickBlox ===== Step 6 =================
// All chat logic can be implemented by yourself using
// ASMACK library (https://github.com/Flowdalic/asmack/downloads)
// -- Android wrapper for Java XMPP library (http://www.igniterealtime.org/projects/smack/).
groupChatController = new GroupChatController(chatLogin, password);
groupChatController.setOnMessageReceivedListener(onMessageReceivedListener);
// ================= QuickBlox ===== Step 7 =================
// Get friend's login based on QuickBlox user account.
// Note, that for your companion you should use full chat login,
// that looks like '17792-1028#chat.quickblox.com' (<qb_user_id>-<qb_app_id>#chat.quickblox.com).
// Don't use short login, it
String friendLogin = QBChat.getChatLoginFull(friends);
groupChatController.startChat(friendLogin);
}
}
private void sendMessage() {
if (messageText != null) {
String messageString = messageText.getText().toString();
groupChatController.sendMessage(messageString);
messageText.setText("");
showMessage(me.getLogin() + " (me) : "+messageString, true);
}
}
private GroupChatController.OnMessageReceivedListener onMessageReceivedListener = new GroupChatController.OnMessageReceivedListener() {
#Override
public void onMessageReceived(final Message message) {
String messageString = message.getBody();
showMessage(messageString, false);
}
};
private void showMessage(String message, boolean leftSide) {
final TextView textView = new TextView(GroupChatActivity.this);
textView.setTextColor(Color.BLACK);
textView.setText(message);
int bgRes = R.drawable.left_message_bg;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
if (!leftSide) {
bgRes = R.drawable.right_message_bg;
params.gravity = Gravity.RIGHT;
}
textView.setLayoutParams(params);
textView.setBackgroundResource(bgRes);
runOnUiThread(new Runnable() {
#Override
public void run() {
messagesContainer.addView(textView);
// Scroll to bottom
if (scrollContainer.getChildAt(0) != null) {
scrollContainer.scrollTo(scrollContainer.getScrollX(), scrollContainer.getChildAt(0).getHeight());
}
scrollContainer.fullScroll(View.FOCUS_DOWN);
}
});
}
private View.OnClickListener onSendMessageClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
sendMessage();
}
};
}
GroupChatController.java
public class GroupChatController {
// Get QuickBlox chat server domain.
// There will be created connection with chat server below.
public static final String CHAT_SERVER = QBChat.getChatServerDomain();
private XMPPConnection connection;
private ConnectionConfiguration config;
private Chat chat;
// Multi-User Chat
private MultiUserChat muc2;
private String chatLogin;
private String password;
private String friendLogin;
private ChatManager chatManager;
public GroupChatController(String chatLogin, String password) {
this.chatLogin = chatLogin;
this.password = password;
}
public void startChat(String buddyLogin) {
this.friendLogin = buddyLogin;
new Thread(new Runnable() {
#Override
public void run() {
// Chat action 1 -- create connection.
Connection.DEBUG_ENABLED = true;
config = new ConnectionConfiguration(CHAT_SERVER);
connection = new XMPPConnection(config);
try {
connection.connect();
connection.login(chatLogin, password);
// Chat action 2 -- create chat manager.
chatManager = connection.getChatManager();
// Chat action 3 -- create chat.
chat = chatManager.createChat(friendLogin, messageListener);
// Set listener for outcoming messages.
chatManager.addChatListener(chatManagerListener);
// Muc 2
if(connection != null){
muc2 = new MultiUserChat(connection, "2389_chat1#muc.chat.quickblox.com");
// Discover whether user3#host.org supports MUC or not
// The room service will decide the amount of history to send
muc2.join(chatLogin);
muc2.invite(friendLogin, "Welcome!");
Log.d("friendLogin ->",friendLogin);
// Set listener for outcoming messages.
//chatManager.addChatListener(chatManagerListener);
muc2.addMessageListener(packetListener);
addListenerToMuc(muc2);
//chat1#muc.chat.quickblox.com
}
Message message = new Message(friendLogin + "#muc.chat.quickblox.com");
message.setBody("Join me for a group chat!");
message.addExtension(new GroupChatInvitation("2389_chat1#muc.chat.quickblox.com"));
connection.sendPacket(message);
} catch (XMPPException e) {
e.printStackTrace();
}
}
}).start();
}
/*** muc */
private void addListenerToMuc(MultiUserChat muc){
if(null != muc){
muc.addMessageListener(new PacketListener() {
#Override
public void processPacket(Packet packet) {
Log.i("processPacket", "receiving message");
}
});
}
}
PacketListener packetListener = new PacketListener() {
#Override
public void processPacket(Packet packet) {
Message message = (Message)packet;
try {
muc2.sendMessage(message);
} catch (XMPPException e) {
e.printStackTrace();
}
//System.out.println("got message " + message.toXML());
}
};
private PacketInterceptor packetInterceptor = new PacketInterceptor() {
#Override
public void interceptPacket(Packet packet) {
System.out.println("Sending message: " + packet.toString());
Message message = muc2.createMessage();
message.setBody("Hello from producer, message " +
" ");
try {
muc2.sendMessage(message);
} catch (XMPPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
/***/
private ChatManagerListener chatManagerListener = new ChatManagerListener() {
#Override
public void chatCreated(Chat chat, boolean createdLocally) {
// Set listener for incoming messages.
chat.addMessageListener(messageListener);
muc2.addMessageListener(packetListener);
}
};
public void sendMessage(String message) {
try {
if (chat != null) {
chat.sendMessage(message);
}
if (muc2 != null) {
muc2.sendMessage(message);
}
} catch (XMPPException e) {
e.printStackTrace();
}
}
private MessageListener messageListener = new MessageListener() {
#Override
public void processMessage(Chat chat, Message message) {
// 'from' and 'to' fields contains senders ids, e.g.
// 17792-1028#chat.quickblox.com/mac-167
// 17744-1028#chat.quickblox.com/Smack
String from = message.getFrom().split("#")[0];
String to = message.getTo().split("#")[0];
System.out.println(String.format(">>> Message received (from=%s, to=%s): %s",
from, to, message.getBody()));
if (onMessageReceivedListener != null) {
onMessageReceivedListener.onMessageReceived(message);
}
}
};
public static interface OnMessageReceivedListener {
void onMessageReceived(Message message);
}
// Callback that performs when device retrieves incoming message.
private OnMessageReceivedListener onMessageReceivedListener;
public OnMessageReceivedListener getOnMessageReceivedListener() {
return onMessageReceivedListener;
}
public void setOnMessageReceivedListener(OnMessageReceivedListener onMessageReceivedListener) {
this.onMessageReceivedListener = onMessageReceivedListener;
}
}
public void startChat(String buddyLogin) {
...
List<String> usersLogins= new ArrayList<String>();
for(String userLogin: usersLogins){
muc2.invite(userLogin, "Welcome!");
}
...
}

Categories

Resources