- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用适用于 Android 的 Quickblox-SDK 开发视频通话应用程序。如果应用程序打开,应用程序运行良好且完美但如果应用程序在后台,我将无法接听电话。我使用这个 link 创建了应用程序请帮忙。我尝试了以下操作:
1) 当通知到达时打开 CallActivity,使用 GCM 进行通知,但作为接收通知的通话时间,这个东西也不起作用。
谢谢。
最佳答案
创建一个将在后台运行甚至 Activity 销毁的粘性服务,该服务负责 QBsession 和所有其他操作,因此它将在后台检测调用。我成功地实现了这一点,并且我通过它成功地在后台接听电话。
public class BloxService extends Service implements QBRTCClientSessionCallbacks {
private QBChatService chatService;
private volatile boolean resultReceived = true;
static final String APP_ID = "";
static final String AUTH_KEY = "";
static final String AUTH_SECRET = "";
static final String ACCOUNT_KEY = "";
private QBRTCClient rtcClient;
public static BloxService bloxService;
private static final String TAG = "BloxService";
public boolean isSessionRunning;
public boolean isCallRunning;
private Date tokenExpirationDate;
private QBAuth qbAuth;
private AppPrefs prefs;
private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
/*boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
String reason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
boolean isFailover = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);*/
NetworkInfo currentNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
//NetworkInfo otherNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
if(currentNetworkInfo!=null && currentNetworkInfo.isConnected()){
if(!QBChatService.getInstance().isLoggedIn()){
if(!isSessionRunning) {
initializeQb();
}
}
}
}
};
@Override
public void onCreate() {
super.onCreate();
// prefs = AppPrefs.getInstance(getApplicationContext()); // for testing we put this line on start
registerReceiver(this.mConnReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("bloxservice","onDestroy");
try{
unregisterReceiver(mConnReceiver);
}catch (Exception e){
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
prefs = AppPrefs.getInstance(getApplicationContext());
if (prefs.getData(IS_USER_LOGIN, false)) {
Log.d("bloxservice","start");
try {
if (!QBChatService.getInstance().isLoggedIn()) {
initializeQb();
}
}catch (Exception e)
{
initializeQb();
}
bloxService=this;
}
else {
stopSelf();
}
return START_STICKY;
}
public static BloxService getBloxService() {
return bloxService;
}
public void initializeQb(){
QBSettings.getInstance().init(getApplicationContext(), APP_ID, AUTH_KEY, AUTH_SECRET);
QBSettings.getInstance().setAccountKey(ACCOUNT_KEY);
QBChatService.setDebugEnabled(true);
// added on 20 july
QBChatService.setDefaultAutoSendPresenceInterval(60);
QBChatService.ConfigurationBuilder chatServiceConfigurationBuilder = new QBChatService.ConfigurationBuilder();
chatServiceConfigurationBuilder.setSocketTimeout(60); //Sets chat socket's read timeout in seconds
chatServiceConfigurationBuilder.setKeepAlive(true); //Sets connection socket's keepAlive option.
QBChatService.setConfigurationBuilder(chatServiceConfigurationBuilder);
// QBChatService.getInstance().startAutoSendPresence(10);// added on 20 july
chatService = QBChatService.getInstance();
/* tokenExpirationDate = qbAuth.getTokenExpirationDate();
try {
String Token= QBAuth.getSession().toString();
QBAuth.createFromExistentToken()
} catch (QBResponseException e) {
e.printStackTrace();
}
*/
if(AppPrefs.getInstance(this).getData(Constants.PrefsConstatnt.IS_USER_LOGIN,false)){
Log.e("Login Process", "Started");
isSessionRunning=true;
String userId=AppPrefs.getInstance(this).getData(Constants.PrefsConstatnt.USER_ID,"");
String name=AppPrefs.getInstance(this).getData(Constants.PrefsConstatnt.USER_NAME,"");
String picUrl=AppPrefs.getInstance(this).getData(Constants.PrefsConstatnt.USER_IMAGE,"");
String phone=prefs.getData(Constants.PrefsConstatnt.USER_PHONE, "");
if(name.isEmpty()){
name=userId;
}
createAppSession(Integer.parseInt(userId)<10?"0"+userId:userId,name,userId,picUrl,phone);
}
}
private void createAppSession(final String userId, final String name,final String exId,final String picUrl,final String phone) {
QBAuth.createSession(new QBEntityCallback<QBSession>() {
@Override
public void onSuccess(QBSession qbSession, Bundle bundle) {
loadUsers(userId, name, exId,picUrl,phone);
final SharedPreferences prefs = getGCMPreferences(getApplicationContext());
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.isEmpty()) {
}
// Subscribe to Push Notifications
//subscribeToPushNotifications(registrationId);
}
@Override
public void onError(QBResponseException exc) {
exc.printStackTrace();
isSessionRunning=false;
}
});
}
//QBUser users;
public void loadUsers(String userId,String name,String exId,String picUrl,String phone) {
final QBUser userr = new QBUser(userId, DataHolder.PASSWORD);
userr.setFullName(name);
userr.setExternalId(exId);
userr.setCustomData(picUrl);
userr.setPhone(phone);
QBUsers.signUp(userr, new QBEntityCallback<QBUser>() {
@Override
public void onSuccess(QBUser user, Bundle args) {
createSession(userr.getLogin(), userr.getPassword());
}
@Override
public void onError(QBResponseException error) {
error.printStackTrace();
QBUsers.signIn(userr, new QBEntityCallback<QBUser>() {
@Override
public void onSuccess(QBUser user, Bundle args) {
createSession(userr.getLogin(), userr.getPassword());
}
@Override
public void onError(QBResponseException error) {
error.printStackTrace();
isSessionRunning = false;
}
});
}
});
}
private void createSession(final String login, final String password) {
final QBUser user = new QBUser(login, password);
QBAuth.createSession(login, password, new QBEntityCallback<QBSession>() {
@Override
public void onSuccess(QBSession session, Bundle bundle) {
user.setId(session.getUserId());
Log.e("User" + session.getUserId(), "Login");
QBSettings.getInstance().fastConfigInit(APP_ID, AUTH_KEY, AUTH_SECRET);
sendRegistrationToServer(AppPrefs.getInstance(BloxService.this).getData(Constants.PrefsConstatnt.DEVICE_TOKEN, ""));
DataHolder.setLoggedUser(user);
if (chatService.isLoggedIn()) {
resultReceived = true;
initQBRTCClient();
isSessionRunning = false;
} else {
chatService.login(user, new QBEntityCallback<Void>() {
@Override
public void onSuccess(Void result, Bundle bundle) {
initQBRTCClient();
resultReceived = true;
isSessionRunning = false;
}
@Override
public void onError(QBResponseException exc) {
resultReceived = true;
isSessionRunning = false;
}
});
}
/* QBRosterListener rosterListener = new QBRosterListener() {
@Override
public void entriesDeleted(Collection<Integer> userIds) {
Log.d("mayanks","changed");
}
@Override
public void entriesAdded(Collection<Integer> userIds) {
Log.d("mayanks","changed");
}
@Override
public void entriesUpdated(Collection<Integer> userIds) {
Log.d("mayanks","changed");
}
@Override
public void presenceChanged(QBPresence presence) {
Log.d("mayanks","changed");
}
};
QBSubscriptionListener subscriptionListener = new QBSubscriptionListener() {
@Override
public void subscriptionRequested(int userId) {
}
};
QBRoster chatRoster = QBChatService.getInstance().getRoster(QBRoster.SubscriptionMode.mutual, subscriptionListener);
chatRoster.addRosterListener(rosterListener);
Collection<QBRosterEntry> entries = chatRoster.getEntries();
QBPresence presence = chatRoster.getPresence(9);
if (presence!=null) {
if (presence.getType() == QBPresence.Type.online) {
Log.d("mayanks","online");
// User is online
}else{
Log.d("mayanks","offline");
// User is offline
}
}*/
}
@Override
public void onError(QBResponseException exc) {
resultReceived = true;
isSessionRunning = false;
}
});
}
private void sendRegistrationToServer(final String token) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
final SharedPreferences prefs = getGCMPreferences(getApplicationContext());
String deviceID = prefs.getString(PROPERTY_DEVICE_ID, null);
if(deviceID==null)
{
deviceID=DeviceUtils.getDeviceUid();
storeDeviceId(getApplicationContext(),deviceID);
}
QBSubscription qbSubscription = new QBSubscription();
qbSubscription.setNotificationChannel(QBNotificationChannel.GCM);
qbSubscription.setDeviceUdid(deviceID);
qbSubscription.setRegistrationID(token);
qbSubscription.setEnvironment(QBEnvironment.DEVELOPMENT); // Don't forget to change QBEnvironment to PRODUCTION when releasing application
QBPushNotifications.createSubscription(qbSubscription,
new QBEntityCallback<ArrayList<QBSubscription>>() {
@Override
public void onSuccess(ArrayList<QBSubscription> qbSubscriptions, Bundle bundle) {
Log.e(TAG, "Successfully subscribed for QB push messages");
//saveGcmRegIdToPreferences(gcmRegId);
isSessionRunning=false;
}
@Override
public void onError(QBResponseException error) {
Log.e(TAG, "Unable to subscribe for QB push messages; " + error.toString());
isSessionRunning=false;
}
});
}
});
}
@Override
public void onReceiveNewSession(final QBRTCSession qbrtcSession) {
Log.d("bloxservice","CallRecive");
new Handler().post(new Runnable() {
@Override
public void run() {
if(!isCallRunning) {
DataHolder.incomingSession = qbrtcSession;
/* Map<String,String> userInfo = qbrtcSession.getUserInfo();
String s=userInfo.get("mayank");*/
Intent intent = new Intent(BloxService.this, CallActivity.class);
intent.putExtra("incoming", true);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
else{
Log.e("User","Busy");
}
}
});
}
@Override
public void onUserNotAnswer(QBRTCSession qbrtcSession, Integer integer) {
// ToastUtil.showShortToast(this, "no answer");
}
@Override
public void onCallRejectByUser(QBRTCSession qbrtcSession, Integer integer, Map<String, String> map) {
// ToastUtil.showShortToast(this,"rejected");
}
@Override
public void onCallAcceptByUser(QBRTCSession qbrtcSession, Integer integer, Map<String, String> map) {
//ToastUtil.showShortToast(this,"accepted");
}
@Override
public void onReceiveHangUpFromUser(QBRTCSession qbrtcSession, Integer integer, Map<String, String> map) {
}
@Override
public void onUserNoActions(QBRTCSession qbrtcSession, Integer integer) {
// ToastUtil.showShortToast(this,"no Action");
}
@Override
public void onSessionClosed(QBRTCSession qbrtcSession) {
// ToastUtil.showShortToast(this,"onSessionClosed");
}
@Override
public void onSessionStartClose(QBRTCSession qbrtcSession) {
// ToastUtil.showShortToast(this,"onSessionStartClose");
}
private void initQBRTCClient() {
rtcClient = QBRTCClient.getInstance(this);
QBVideoChatWebRTCSignalingManager qbChatService = QBChatService.getInstance().getVideoChatWebRTCSignalingManager();
if (qbChatService != null) {
qbChatService.addSignalingManagerListener(new QBVideoChatSignalingManagerListener() {
@Override
public void signalingCreated(QBSignaling qbSignaling, boolean createdLocally) {
if (!createdLocally) {
rtcClient.addSignaling((QBWebRTCSignaling) qbSignaling);
}
}
});
QBRTCConfig.setMaxOpponentsCount(2);
QBRTCConfig.setDisconnectTime(40);
QBRTCConfig.setAnswerTimeInterval(30l);
QBRTCConfig.setDebugEnabled(true);
rtcClient.addSessionCallbacksListener(this);
rtcClient.prepareToProcessCalls();
QBChatService.getInstance().addConnectionListener(new AbstractConnectionListener() {
@Override
public void connectionClosedOnError(Exception e) {
}
@Override
public void reconnectionSuccessful() {
}
@Override
public void reconnectingIn(int seconds) {
}
});
}
}
public void logout(){
chatService.logout(new QBEntityCallback<Void>() {
@Override
public void onSuccess(Void result, Bundle bundle) {
}
@Override
public void onError(QBResponseException list) {
}
});
}
/* public void subscribeToPushNotifications(String registrationID) {
QBSubscription subscription = new QBSubscription(QBNotificationChannel.GCM);
subscription.setEnvironment(QBEnvironment.DEVELOPMENT);
//
String deviceId;
final TelephonyManager mTelephony = (TelephonyManager) getSystemService(
Context.TELEPHONY_SERVICE);
if (mTelephony.getDeviceId() != null) {
deviceId = mTelephony.getDeviceId(); /*//*** use for mobiles
} else {
deviceId = Settings.Secure.getString(getContentResolver(),
Settings.Secure.ANDROID_ID); /*//*** use for tablets
}
subscription.setDeviceUdid(deviceId);
//
subscription.setRegistrationID(registrationID);
//
QBPushNotifications.createSubscription(subscription, new QBEntityCallback<ArrayList<QBSubscription>>() {
@Override
public void onSuccess(ArrayList<QBSubscription> subscriptions, Bundle args) {
Log.d("push_send","sucess");
}
@Override
public void onError(QBResponseException error) {
Log.d("push_send","sucess");
}
});
}*/
private SharedPreferences getGCMPreferences(Context context) {
// This sample app persists the registration ID in shared preferences,
// but
// how you store the regID in your app is up to you.
Log.e("getGCMPreferences", "package= " + context.getPackageName());
return getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE);
}
private void storeDeviceId(Context context, String deviceId) {
final SharedPreferences prefs = getGCMPreferences(context);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_DEVICE_ID, deviceId);
editor.commit();
}
}
关于android - Quickblox - Android 应用程序的 SDK 在应用程序处于后台时不接听电话,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38651265/
我正在尝试在 IN sql 条件下使用数据库字段。我的字段是一串由逗号分隔的值(如 it,en,fr,de),我必须在 WHERE 子句中使用它,如下所示: WHERE d.iso639code =
他大家 我的以下代码有问题: import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp e
在处理 ReadOnlyMany 存储时,我正在努力理解 PersistentVolume 上的容量参数的概念,以及 PersistentVolumeClaim 上的存储请求。如果存储以只读方式安装
我试图让一个 while 循环在另一个 while 循环中工作,我之前已经让它工作过,但无法再次管理它。 我试图计算航类查询中的总记录,然后在小时记录中尝试添加时间。我已经让所有查询单独工作,但是当我
我们的数据库更新性能偶尔会大幅下降。 例如,表 FooTable 我们有大约 40 列与 varchar PK 此外还有 10 个索引。以下查询用时 44 秒,而在其他时候它几乎立即运行。在减速期间,
我可以在 Release模式下使用 Trace.WriteLine 吗? Trace.Write 和 Debug.Write 之间的主要区别是什么? 最佳答案 不同之处在于 Release模式。 当未
我刚刚遇到了一个非常奇怪的场景,并且在其他地方找不到任何相关信息。当 Xcode 在我的断点处中断时,整个系统的所有键盘输入都没有响应。我可以切换到另一个应用程序,但没有记录任何击键。 Xcode 本
我一直在尝试在一组 Raspberry Pi 上设置 K8s 集群。这是我的 GitHub 页面的链接,描述了整个设置: https://github.com/joesan/plant-infra/b
我的 pod 处于 Pending 状态,因为提到的所有答案我都试图获得描述输出但不知道为什么它保持在 Pending 状态: k8s@k8s-master:~/deployment$ kubectl
我已经开发了一个非消耗性的应用内购买iOS应用程序。我已经获取了应用内购买的 bundle 包标识符,并编写了代码并将其提交给appstore ...提交应用程序后,其状态显示在-App Purcha
我有 2 个具有一对多关系的实体,一个地址可以是多个员工。 MySQL 数据库: 地址 address_id INT PK AutoIncr 城市 VARCHAR 国家/地区 VARCHAR 员工 i
我想在我的项目中使用 ProGuard。我激活了选项 minifyEnabled。当我打开使用库 Retrofit2 的 Activity 时,应用程序崩溃并显示: 无法为接口(interface)
我刚刚在 MVC 应用程序中启用了 Application Insights,并注意到在本地调试时,我的 Azure Application Insight 中会捕获跟踪信息。 处于 Debug模式时
我正在使用一个启动和结束线程的类。线程是在构造函数中创建的。只要标志为 TRUE,线程函数就会继续循环。该标志是该类的静态成员。解构器将标志设置为 FALSE。这样,该类的每个实例都有一个关联的线程,
我有一个 Angular PWA。在我从 Angular 5.0 升级到 7.2 之前,它的 service worker 工作完美 升级后,我在/ngsw/state中看到以下错误 Driver s
可能有一些背景:当用户单击它时,我试图在可滚动的全屏 EditText 上方显示一个特定的键盘 View 。问题是如果光标位于 EditText 的底部,它会被弹出的键盘 View 隐藏。 与常规 I
当进度条处于 Activity 状态时禁用后台交互的正确方法是什么。 Box( modifier = Modifier.fillMaxSize(), contentAlignmen
这个问题在这里已经有了答案: Draw Rectangle inside picture box SizeMode Zoom (1 个回答) 关闭 3 年前。 我有一个 PictureBox1,其
我们刚刚开始在 kubernetes 上创建我们的集群。 现在我们尝试部署分蘖,但出现错误: NetworkPlugin cni failed to set up pod "tiller-deploy
我使用 NRPE 插件将一台 Linux 主机配置为 Nagios 监控服务器。 为此,我遵循以下 URL http://www.tecmint.com/how-to-add-linux-host-t
我是一名优秀的程序员,十分优秀!