Accept Call between Android and iOS in QuickBlox - java

I use the framework to create a video messenger between Android and IOS.
To do: in iOS session is created and the user is called, which enters with the Android device.
But during the call, before making a call on android - android application crashes.
Maybe someone faced the such? Or what am I doing wrong? I do not understand how to handle the incoming call ... (
My code for Android device
onCreate(...){
QBSettings.getInstance().fastConfigInit(APPLICATION_ID,AUTHORIZATION_KEY,AUTHORIZATION_SECRET);
}
public void createSessionButton(View view){
//Log.d("Tag","onSuccess");
QBAuth.createSession(currentUser,new QBEntityCallbackImpl<QBSession>() {
#Override
public void onSuccess(QBSession session, Bundle params) {
currentUser.setId(session.getUserId());
Log.d("Tag","call set id success");
QBChatService chatService;
if (!QBChatService.isInitialized()) {
Log.d("Tag","QBChatService do not initialize");
QBChatService.init(getApplicationContext());
}
chatService = QBChatService.getInstance();
Log.d("Tag","QBChatService initialize");
// LOG IN CHAT SERVICE
chatService.login(currentUser, new QBEntityCallbackImpl<QBUser>() {
#Override
public void onSuccess() {
runOnUiThread(new Runnable() {
#Override
public void run() {
processTextView.setText("LOG IN CHAT SERVICE onSuccess");
}
});
//processTextView.setText("LOG IN CHAT SERVICE onSuccess");
Log.d("Tag","LOG IN CHAT SERVICE onSuccess");
}
#Override
public void onError(List errors) {
Log.d("Tag","LOG IN CHAT SERVICE onError");
}
});
}
#Override
public void onError(List<String> errors) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Важное сообщение!")
.setMessage("onError")
//.setIcon(R.drawable.ic_android_cat)
.setCancelable(false)
.setNegativeButton("ОК",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
}
public void createSignalingManager(View view) {
QBChatService.getInstance().getVideoChatWebRTCSignalingManager().addSignalingManagerListener(new QBVideoChatSignalingManagerListener() {
#Override
public void signalingCreated(QBSignaling qbSignaling, boolean b) {
if (!b) {
QBRTCClient.getInstance().addSignaling((QBWebRTCSignaling) qbSignaling);
runOnUiThread(new Runnable() {
#Override
public void run() {
processTextView.setText("addSignalingManagerListener");
}
});
}
}
});
// Add activity as callback to RTCClient
QBRTCClient.getInstance().addSessionCallbacksListener(this);
QBRTCClient.getInstance().addConnectionCallbacksListener(this);
QBRTCClient.getInstance().addVideoTrackCallbacksListener(this);
QBRTCClient.getInstance().prepareToProcessCalls(this);
}
My code in iOS
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[QBRTCClient.instance addDelegate:self];
[[QBChat instance] addDelegate:self];
[QBRTCConfig setDisconnectTimeInterval:10];
self.callTestButton.hidden = YES;
}
#pragma mark - Action
- (IBAction)loginAction:(id)sender {
QBUUser* currentUser = [[QBUUser alloc] init];
currentUser.password = pass;
currentUser.login = login;
// connect to Chat
[[QBChat instance] connectWithUser:currentUser completion:^(NSError * error) {
NSLog(#"Error: %#", error);
}];
[QBRequest logInWithUserLogin:login password:pass successBlock:^(QBResponse *response, QBUUser *user) {
NSLog(#"logInWithUserLogin:");
[QBRequest usersWithSuccessBlock:^(QBResponse * response, QBGeneralResponsePage * page, NSArray * users) {
NSLog(#"usersWithSuccessBlock:");
self.callTestButton.hidden = NO;
} errorBlock:^(QBResponse * response) {
}];
} errorBlock:^(QBResponse *response) {
NSLog(#"error: %#", response.error);
}];
}
- (IBAction)callAction:(UIButton *)sender {
NSArray *opponentsIDs = [[NSArray alloc] initWithObjects:[NSNumber numberWithInteger:6919398], nil];
NSLog(#"%ld", (long)[opponentsIDs[0] integerValue]);
QBRTCSession* session = [QBRTCClient.instance createNewSessionWithOpponents:opponentsIDs
withConferenceType:QBRTCConferenceTypeAudio];
session.localMediaStream.videoTrack.enabled = NO;
if (session) {
NSLog(#"new session");
}
NSDictionary *userInfo = #{#"startCall" : #"userInfo"};
[session startCall:userInfo];
}

Please check the documentation that shows how to use Quickblox SDK for videocalls and also check the sample code

Related

How do I disconnect from a device when I close my app?

I am working on a project in Android Studio where I am supposed to connect two devices using Wifi-Direct.
I have managed to connect to another device with Wifi-direct. My problem is that when I close the app manually on my phone, the devices do not disconnect. How can I achieve this? I am quite new with Android Studio and java.
Here is my WifiDirectActivity class:
public class WiFiDirectActivity extends Activity implements WifiP2pManager.ChannelListener, DeviceListFragment.DeviceActionListener {
public static final String TAG = "wifidirectdemo";
private WifiP2pManager manager;
private boolean isWifiP2pEnabled = false;
private boolean retryChannel = false;
private final IntentFilter intentFilter = new IntentFilter();
private WifiP2pManager.Channel channel;
private BroadcastReceiver receiver = null;
/**
* #param isWifiP2pEnabled the isWifiP2pEnabled to set
*/
public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled) {
this.isWifiP2pEnabled = isWifiP2pEnabled;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_peers);
// add necessary intent values to be matched.
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel = manager.initialize(this, getMainLooper(), null);
}
/** register the BroadcastReceiver with the intent values to be matched */
#Override
public void onResume() {
super.onResume();
receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
registerReceiver(receiver, intentFilter);
if (!amConnected) {
performSearch();
}
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
/**
* Remove all peers and clear all fields. This is called on
* BroadcastReceiver receiving a state change event.
*/
public void resetData() {
DeviceListFragment fragmentList = (DeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
DeviceDetailFragment fragmentDetails = (DeviceDetailFragment) getFragmentManager()
.findFragmentById(R.id.frag_detail);
if (fragmentList != null) {
fragmentList.clearPeers();
}
if (fragmentDetails != null) {
fragmentDetails.resetViews();
}
}
#Override
public void showDetails(WifiP2pDevice device) {
DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
.findFragmentById(R.id.frag_detail);
fragment.showDetails(device);
}
#Override
public void connect(WifiP2pConfig config) {
manager.connect(channel, config, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
// WiFiDirectBroadcastReceiver will notify us. Ignore for now.
}
#Override
public void onFailure(int reason) {
Toast.makeText(WiFiDirectActivity.this, "Connect failed. Retry.",
Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void disconnect() {
final DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
.findFragmentById(R.id.frag_detail);
fragment.resetViews();
manager.removeGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onFailure(int reasonCode) {
Log.d(TAG, "Disconnect failed. Reason :" + reasonCode);
}
#Override
public void onSuccess() {
fragment.getView().setVisibility(View.GONE);
}
});
}
#Override
public void onChannelDisconnected() {
// we will try once more
if (manager != null && !retryChannel) {
Toast.makeText(this, "Channel lost. Trying again", Toast.LENGTH_LONG).show();
resetData();
retryChannel = true;
manager.initialize(this, getMainLooper(), this);
} else {
Toast.makeText(this,
"Severe! Channel is probably lost premanently. Try Disable/Re-Enable P2P.",
Toast.LENGTH_LONG).show();
}
}
#Override
public void cancelDisconnect() {
/*
* A cancel abort request by user. Disconnect i.e. removeGroup if
* already connected. Else, request WifiP2pManager to abort the ongoing
* request
*/
if (manager != null) {
final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
if (fragment.getDevice() == null
|| fragment.getDevice().status == WifiP2pDevice.CONNECTED) {
disconnect();
} else if (fragment.getDevice().status == WifiP2pDevice.AVAILABLE
|| fragment.getDevice().status == WifiP2pDevice.INVITED) {
manager.cancelConnect(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(WiFiDirectActivity.this, "Aborting connection",
Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int reasonCode) {
Toast.makeText(WiFiDirectActivity.this,
"Connect abort request failed. Reason Code: " + reasonCode,
Toast.LENGTH_SHORT).show();
}
});
}
}
}
private void performSearch() {
final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
fragment.onInitiateDiscovery();
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(WiFiDirectActivity.this, "Discovery Initiated",
Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int reasonCode) {
Toast.makeText(WiFiDirectActivity.this, "Discovery Failed : " + reasonCode,
Toast.LENGTH_SHORT).show();
}
});
}
}
When you close the app the execution will run through onPause() callback, there you should call the disconnect() method. However, take 5 minutes of your time to understand Android's life cycle principle: https://developer.android.com/guide/components/activities/activity-lifecycle.html. It's one of the first things to learn before developing an Android app.

Using Thread in Android for sending message

I have this code:
if (value) {
thread = new Thread() {
#Override
public void run() {
try {
while (!isConnected()) {
synchronized (this) {
wait(3000);
}
}
} catch (InterruptedException ex) {
}
if(wifiManager.isWifiEnabled()){
sendMessageWidget();
} else {
showWifiSettingsAlert();
}
}
};
thread.start();
}
I want my app to wait until google api client is connected and than send a message.
The code for the isConnected method is:
public boolean isConnected() {
mGoogleApiClient.connect();
if (mGoogleApiClient.isConnected()) {
return true;
}
return false;
}
But I get this error message:
NullPointerException: Can't create handler inside thread that has not called Looper.prepare(), and it says that the mistake is somewhere id showWifiSettingsAlert()
here is the code:
public void showWifiSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
// Setting Dialog Title
alertDialog.setTitle("Location accuracy tips");
// Setting Dialog Message
alertDialog
.setMessage("You can improve the accuracy of your location by turning on\n- Wi-Fi");
// On pressing Settings button
alertDialog.setPositiveButton("Turn on",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
wifiManager.setWifiEnabled(true);
// Posalji poruke al pre toga jos jednom azuriraj
// lokaciju al ako je pozvana aplikacija iz widgeta
if (value) {
sendMessageWidget();
}
}
});
// on pressing cancel button
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
wifiManager.setWifiEnabled(false);
// Posalji poruke al pre toga jos jednom azuriraj
// lokaciju al ako je pozvana aplikacija iz widgeta
if (value) {
sendMessageWidget();
}
}
});
// Showing Alert Message
alertDialog.show();
}
I want, if wifi is not enabled, the user to choose to enable it or not, but either way the message should be sent... can you help please?
Since you can't touch the UI from a thread other than the main thread, you must post these changes back to the UI thread and its looper and associated handlers. You can do so explicitly by creating a handler associated with the UI thread (which will work anywhere, since Looper.getMainLooper() is a static call) such as:
if (value) {
Handler uiCallback = new Handler(Looper.getMainLooper());
thread = new Thread() {
#Override
public void run() {
try {
while (!isConnected()) {
synchronized (this) {
wait(3000);
}
}
} catch (InterruptedException ex) {
}
uiCallback.post(new Runnable() {
#Override public void run() {
if(wifiManager.isWifiEnabled()){
sendMessageWidget();
} else {
showWifiSettingsAlert();
}
}
});
}
};
thread.start();
}
Or instead of using a handler at all, you can wrap the part in the run() method in runOnUiThread() if you are in an activity which does the same thing.
You should note however, you don't actually need to use any threading here. If you follow the example on: https://developer.android.com/google/auth/api-client.html you'll find that by implementing ConnectionCallbacks, OnConnectionFailedListener you can call mGoogleApis.connect() from the activity's onStart() and when it connects or fails to do the corresponding callback will be executed on the calling thread. For instance,
#Override
public void onConnected(Bundle connectionHint) {
if(wifiManager.isWifiEnabled()){
sendMessageWidget();
} else {
showWifiSettingsAlert();
}
}
Achieves the same thing...
You are using mGoogleApiClient.connect();, which is an asynchronous method, in a thread and this isn't allowed.
You could try using runOnUiThread instead :
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
//do your stuff here
}
});

QuickBlox chat messages listener

I use 2.1.1 Android SDK and want to notify user about new incoming messages received by application.
Here is the issue. I would like to notify user as he launches application, thus i would like to add listener at the stage of "user login" as it's shown in the snippet:
QBAuth.createSession(user, new QBEntityCallbackImpl<QBSession>() {
#Override
public void onSuccess(QBSession session, Bundle args) {
// login to Chat
chatService.login(user, new QBEntityCallbackImpl() {
#Override
public void onSuccess() {
HERE I WOULD LIKE A CODE TO START LISTEN FOR ALL INCOMING MESSAGES
As per http://sdk.quickblox.com/android/com/quickblox/chat/listeners/QBMessageListenerImpl.html
listener needs chat QBChat to initiate. But I would like to listen for all of the messages, not only within particular chat.
Long story short, how to implement a message listener to catch all messages addressed to logged in user?
#Naveen Kumar
In my start activity i launch listener to catch XMPP connection.
private void XMPPConnectionListener() {
XMPPConnection.addConnectionCreationListener(new ConnectionCreationListener() {
#Override
public void connectionCreated(XMPPConnection connection) {
GlobalVar.XMPPConn = connection;
ChatHelper.idleMessageListener(StartActivity.this);
}
});
}
Then I use GlobalVar.XMPPConn to catch packets and parse them:
public static void idleMessageListener(final Activity activity) {
PacketListener myListener = new PacketListener() {
public void processPacket(final Packet packet) {
final Integer userID = Integer.parseInt(returnIDFromPacket(packet.getFrom()));
final String body = returnBodyFromPacket(packet.toString());
if (!GlobalVar.currentOpponent.equals(userID) && !body.isEmpty()) {
activity.runOnUiThread(new Runnable() {
public void run() {
QBUsers.getUser(userID, new QBEntityCallbackImpl<QBUser>() {
#Override
public void onSuccess(final QBUser user, Bundle args) {
sendNotification(activity, user, body);
}
#Override
public void onError(List<String> errors) {
Log.d(TAG, errors.toString());
}
});
}
});
}
}
};
PacketFilter filter = new MessageTypeFilter(Message.Type.chat);
if (GlobalVar.XMPPConn != null) {
GlobalVar.XMPPConn.addPacketListener(myListener, filter);
}
}
So logic is to catch the connection fired by QuickBlox and then attach a packet listener to it.

Facebook integration not working in different devices

I am building an app where I am trying to integrate facebook. When I am using device of android 2.3.3 its working fine and i am able to post message. But when I am running that same app in android 4.1 then it showing "failed to post".I am using facebook-sdk version 3.6.0
My code as below
FacebookActivity.java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.facebook);
btnPostStatus = (Button) findViewById(R.id.mBtnPostStatus);
edtPost = (EditText) findViewById(R.id.post_text);
edtPost.setText(messageToPost);
btnPostStatus.setOnClickListener(new OnClickListener() {
#SuppressWarnings("deprecation")
public void onClick(View arg0) {
facebook = new Facebook(APP_ID);
restoreCredentials(facebook);
messageToPost = edtPost.getText().toString();
if (!facebook.isSessionValid()) {
loginAndPostToWall();
} else {
postToWall(messageToPost);
}
}
});
}
#SuppressWarnings("deprecation")
public boolean saveCredentials(Facebook facebook) {
Editor editor = getApplicationContext().getSharedPreferences(KEY,
Context.MODE_PRIVATE).edit();
editor.putString(TOKEN, facebook.getAccessToken());
editor.putLong(EXPIRES, facebook.getAccessExpires());
return editor.commit();
}
#SuppressWarnings("deprecation")
public boolean restoreCredentials(Facebook facebook) {
SharedPreferences sharedPreferences = getApplicationContext()
.getSharedPreferences(KEY, Context.MODE_PRIVATE);
facebook.setAccessToken(sharedPreferences.getString(TOKEN, null));
facebook.setAccessExpires(sharedPreferences.getLong(EXPIRES, 0));
return facebook.isSessionValid();
}
#SuppressWarnings("deprecation")
public void loginAndPostToWall() {
facebook.authorize(this, PERMISSIONS, Facebook.FORCE_DIALOG_AUTH,
new LoginDialogListener());
}
#SuppressWarnings("deprecation")
public void postToWall(String message) {
Bundle parameters = new Bundle();
parameters.putString("message", message);
parameters.putString("description", "topic share");
try {
facebook.request("me");
String response = facebook.request("me/feed", parameters, "POST");
Log.d("Tests", "got response: " + response);
if (response == null || response.equals("")
|| response.equals("false")) {
showToast("Blank response.");
} else {
showToast("Message posted to your facebook wall!");
}
} catch (Exception e) {
showToast("Failed to post to wall!");
e.printStackTrace();
}
}
class LoginDialogListener implements DialogListener {
public void onComplete(Bundle values) {
saveCredentials(facebook);
if (messageToPost != null) {
postToWall(messageToPost);
}
}
public void onFacebookError(FacebookError error) {
showToast("Authentication with Facebook failed!");
}
public void onError(DialogError error) {
showToast("Authentication with Facebook failed!");
}
public void onCancel() {
showToast("Authentication with Facebook cancelled!");
}
}
private void showToast(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT)
.show();
}
}
It not showing any exception, but not able post
Is there any good fb integration tutorial which using latest facebook sdk version ?
Actually I solved my problem. When I am setting a target-sdk version in my manifest.xml then its working for lower version android device but its not working for my jelly bean android device.
So when I remove target-sdk version then its working properly in jelly bean device also .

How to display alert dialog in running thread?

I want to display an alert dialog depending upon the property and when the user clicks on the OK button, call the function again to get updated values within the running process.
I have the following code:
importingProgress = ProgressDialog.show(context, getString(R.string.progressNewsListTitle),
getString(R.string.progressProjectListMessage), true);
new Thread(new Runnable() {
public void run() {
try {
app.SetOtherTaskRunning(true);
Ib_clients client = db.Ib_clients_GetById(app.GetCustomerId());
try {
LogManager.WriteToFile("---------------- Getting News from Webservice :- " + DateFormat.getDateTimeInstance().format(new Date()) + "----------------");
CommonFuctions.CreateXml(context, h, client, db, app.GetBookMonth(), app.GetBookQuater(), app.GetBookYear(), Constants.News, app.GetWebServiceLastSyncDate(Constants.ServiceType.NEWS.toString()), Constants.ServiceType.NEWS, null, null, null, null, null);
Return reponse = null;
do {
reponse = CommonFuctions.SendingRequest(context, handler, db);
if (reponse.type.compareTo("warning") == 0) {
h.post(new Runnable() {
public void run() {
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle(context.getString(R.string.information));
alert.setMessage("dsgdgd");
alert.setPositiveButton(context.getString(R.string.logoutDialogOk), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
});
alert.show();
}
});
}
} while (reponse.type.compareTo("warning") == 0);
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
//Log.d(Constants.TAG, e.getMessage());
e.printStackTrace();
}
if (importingProgress != null) {
importingProgress.dismiss();
importingProgress = null;
}
}
}).start();
If response type is warning, then display a message to the user and if the user clicks the OK button , then call CommonFuctions.SendingRequest(context, handler, db) again to get updated values. Until we get a.response type of warning , we need to display an alert dialog to the user and call CommonFuctions.SendingRequest(context, handler, db) again.
Class to return:
public class Return {
public String type;
public String msg;
public boolean isSuccess;
public int client_id; // for getting clientid from server
public int booking_id; // for getting bookingid form server
}
You will have to use handler to display the AlertDialog because UI can be handled by the main thread only.
The other way is to use asyncTask for multiprocessing and then using the onPostExcecute() of asyncTask to display the AlertDialog
Please feel free to ask any further doubts.
Try to run your dialog as below in runonUIthread:
runOnUiThread(new Runnable() {
#Override
public void run() {
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setTitle(context.getString(R.string.information));
alert.setMessage("dsgdgd");
alert.setPositiveButton(context.getString(R.string.logoutDialogOk), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
});
alert.show();
}
});

Categories