Skip to content

Commit 8ca8994

Browse files
committed
4.2.0-videochat-java
1 parent 57638df commit 8ca8994

26 files changed

+581
-92
lines changed

sample-videochat-java/app/build.gradle

+10-13
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,24 @@ repositories {
1818
android {
1919
def versionQACode = 1
2020

21-
compileSdkVersion 31
22-
buildToolsVersion "31.0.0"
23-
flavorDimensions "default"
24-
2521
defaultConfig {
2622
applicationId "com.quickblox.sample.videochat.java"
2723
minSdkVersion 21
28-
targetSdkVersion 31
29-
versionCode 410010
30-
versionName '4.1.1'
24+
targetSdkVersion 34
25+
compileSdk 34
26+
versionCode 420000
27+
versionName '4.2.0'
3128
multiDexEnabled true
3229
}
3330

31+
flavorDimensions += "dimension"
3432
productFlavors {
3533
dev {
36-
dimension "default"
3734
buildConfigField('boolean', "IS_QA", "false")
3835
buildConfigField("int", "VERSION_QA_CODE", versionQACode.toString())
3936
}
4037

4138
qa {
42-
dimension "default"
4339
buildConfigField("boolean", "IS_QA", "true")
4440
buildConfigField("int", "VERSION_QA_CODE", versionQACode.toString())
4541
}
@@ -80,16 +76,17 @@ android {
8076
sourceCompatibility JavaVersion.VERSION_1_8
8177
targetCompatibility JavaVersion.VERSION_1_8
8278
}
79+
namespace 'com.quickblox.sample.videochat.java'
8380
}
8481

8582
dependencies {
86-
implementation 'com.quickblox:quickblox-android-sdk-videochat-webrtc:3.10.1'
87-
implementation 'com.quickblox:quickblox-android-sdk-messages:3.10.1'
83+
implementation 'com.quickblox:quickblox-android-sdk-videochat-webrtc:4.1.3'
84+
implementation 'com.quickblox:quickblox-android-sdk-messages:4.1.3'
8885

89-
implementation 'com.google.firebase:firebase-core:21.1.0'
86+
implementation 'com.google.firebase:firebase-core:21.1.1'
9087
implementation 'com.navercorp.pulltorefresh:library:3.2.3@aar'
9188

92-
implementation 'com.google.android.material:material:1.6.1'
89+
implementation 'com.google.android.material:material:1.12.0'
9390
implementation 'com.github.johnkil.android-robototextview:robototextview:4.0.0'
9491
}
9592

sample-videochat-java/app/proguard-rules.pro

+4-1
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,7 @@
4444
-keep class com.google.android.gms.** { *; }
4545

4646
#json
47-
-keep class org.json.** { *; }
47+
-keep class org.json.** { *; }
48+
-keep class com.google.gson.reflect.TypeToken
49+
-keep class * extends com.google.gson.reflect.TypeToken
50+
-keep public class * implements java.lang.reflect.Type

sample-videochat-java/app/src/main/AndroidManifest.xml

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
xmlns:tools="http://schemas.android.com/tools"
4-
package="com.quickblox.sample.videochat.java">
3+
xmlns:tools="http://schemas.android.com/tools">
54

65
<uses-permission android:name="android.permission.CAMERA" />
76
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
7+
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
88
<uses-permission android:name="android.permission.RECORD_AUDIO" />
99
<uses-permission android:name="android.permission.INTERNET" />
1010
<uses-permission android:name="android.permission.VIBRATE" />
@@ -14,6 +14,10 @@
1414
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
1515
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
1616

17+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA" />
18+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
19+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
20+
1721
<uses-feature android:name="android.hardware.camera" />
1822
<uses-feature android:name="android.hardware.camera.autofocus" />
1923

@@ -70,7 +74,8 @@
7074

7175
<service
7276
android:name=".services.CallService"
73-
android:foregroundServiceType="mediaProjection" />
77+
android:exported="false"
78+
android:foregroundServiceType="camera|microphone|mediaProjection" />
7479

7580
<service
7681
android:name=".services.fcm.PushListenerService"
@@ -90,7 +95,7 @@
9095

9196
<meta-data
9297
android:name="com.quickblox.messages.TYPE"
93-
android:value="GCM" />
98+
android:value="FCM" />
9499

95100
<meta-data
96101
android:name="com.quickblox.messages.SENDER_ID"

sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/CallActivity.java

+63-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package com.quickblox.sample.videochat.java.activities;
22

3+
import static com.quickblox.sample.videochat.java.services.CallService.ONE_OPPONENT;
4+
import static com.quickblox.videochat.webrtc.BaseSession.QBRTCSessionState.QB_RTC_SESSION_NEW;
5+
import static com.quickblox.videochat.webrtc.BaseSession.QBRTCSessionState.QB_RTC_SESSION_PENDING;
6+
37
import android.app.Activity;
48
import android.app.KeyguardManager;
59
import android.content.ComponentName;
610
import android.content.Context;
711
import android.content.Intent;
812
import android.content.ServiceConnection;
13+
import android.media.projection.MediaProjectionManager;
914
import android.net.Uri;
1015
import android.os.Build;
1116
import android.os.Bundle;
@@ -44,11 +49,11 @@
4449
import com.quickblox.sample.videochat.java.utils.UsersUtils;
4550
import com.quickblox.sample.videochat.java.utils.WebRtcSessionManager;
4651
import com.quickblox.users.model.QBUser;
47-
import com.quickblox.videochat.webrtc.AppRTCAudioManager;
4852
import com.quickblox.videochat.webrtc.BaseSession;
4953
import com.quickblox.videochat.webrtc.QBRTCScreenCapturer;
5054
import com.quickblox.videochat.webrtc.QBRTCSession;
5155
import com.quickblox.videochat.webrtc.QBRTCTypes;
56+
import com.quickblox.videochat.webrtc.audio.QBAudioManager;
5257
import com.quickblox.videochat.webrtc.callbacks.QBRTCClientSessionCallbacks;
5358
import com.quickblox.videochat.webrtc.callbacks.QBRTCClientVideoTracksCallbacks;
5459
import com.quickblox.videochat.webrtc.callbacks.QBRTCSessionEventsCallback;
@@ -64,9 +69,6 @@
6469
import java.util.List;
6570
import java.util.Map;
6671

67-
import static com.quickblox.sample.videochat.java.services.CallService.ONE_OPPONENT;
68-
import static com.quickblox.videochat.webrtc.BaseSession.QBRTCSessionState.QB_RTC_SESSION_PENDING;
69-
7072
/**
7173
* QuickBlox team
7274
*/
@@ -77,6 +79,7 @@ public class CallActivity extends BaseActivity implements IncomeCallFragmentCall
7779

7880
public static final String INCOME_CALL_FRAGMENT = "income_call_fragment";
7981
public static final int REQUEST_PERMISSION_SETTING = 545;
82+
public static final int REQUEST_SHARING_MEDIA_PROJECTION = 1060;
8083

8184
private final ArrayList<CurrentCallStateCallback> currentCallStateCallbackList = new ArrayList<>();
8285
private final UsersDbManager dbManager = UsersDbManager.getInstance();
@@ -97,7 +100,6 @@ public static void start(Context context, boolean isIncomingCall) {
97100
intent.putExtra(Consts.EXTRA_IS_INCOMING_CALL, isIncomingCall);
98101
SharedPrefsHelper.getInstance().save(Consts.EXTRA_IS_INCOMING_CALL, isIncomingCall);
99102
context.startActivity(intent);
100-
CallService.start(context);
101103
}
102104

103105
@Override
@@ -107,6 +109,38 @@ protected void onCreate(Bundle savedInstanceState) {
107109
setContentView(R.layout.activity_main);
108110
checker = new PermissionsChecker(this);
109111
connectionView = (LinearLayout) View.inflate(CallActivity.this, R.layout.connection_popup, null);
112+
113+
boolean isVideoCall = isVideoSession();
114+
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.TIRAMISU && isVideoCall && isNewSession()) {
115+
requestSharingPermissions(this);
116+
return;
117+
}
118+
119+
CallService.start(this);
120+
}
121+
122+
private boolean isNewSession() {
123+
QBRTCSession currentSession = WebRtcSessionManager.getInstance(getApplicationContext()).getCurrentSession();
124+
if (currentSession == null) {
125+
return false;
126+
}
127+
128+
BaseSession.QBRTCSessionState sessionState = currentSession.getState();
129+
if (sessionState == null) {
130+
return false;
131+
}
132+
133+
return currentSession.getState().equals(QB_RTC_SESSION_NEW) || currentSession.getState().equals(QB_RTC_SESSION_PENDING);
134+
}
135+
136+
private boolean isVideoSession() {
137+
QBRTCSession currentSession = WebRtcSessionManager.getInstance(getApplicationContext()).getCurrentSession();
138+
return currentSession != null && currentSession.getConferenceType().equals(QBRTCTypes.QBConferenceType.QB_CONFERENCE_TYPE_VIDEO);
139+
}
140+
141+
public void requestSharingPermissions(Activity context) {
142+
MediaProjectionManager mMediaProjectionManager = (MediaProjectionManager) context.getSystemService(MEDIA_PROJECTION_SERVICE);
143+
context.startActivityForResult(mMediaProjectionManager.createScreenCaptureIntent(), REQUEST_SHARING_MEDIA_PROJECTION);
110144
}
111145

112146
@Override
@@ -134,6 +168,7 @@ public void finish() {
134168
@Override
135169
public void onBackPressed() {
136170
// to prevent returning from Call Fragment
171+
super.onBackPressed();
137172
}
138173

139174
private void allowOnLockScreen() {
@@ -211,8 +246,17 @@ protected void onActivityResult(int requestCode, int resultCode, final Intent da
211246
startScreenSharing(data);
212247
Log.i(TAG, "Starting Screen Capture");
213248
}
249+
250+
if (requestCode == REQUEST_SHARING_MEDIA_PROJECTION) {
251+
if (resultCode == Activity.RESULT_OK) {
252+
CallService.start(this);
253+
} else {
254+
finish();
255+
}
256+
}
214257
}
215258

259+
216260
private void startScreenSharing(final Intent data) {
217261
Fragment fragmentByTag = getSupportFragmentManager().findFragmentByTag(ScreenShareFragment.class.getSimpleName());
218262
if (!(fragmentByTag instanceof ScreenShareFragment)) {
@@ -341,7 +385,9 @@ private void startIncomeCallTimer(long time) {
341385

342386
private void stopIncomeCallTimer() {
343387
Log.d(TAG, "stopIncomeCallTimer");
344-
showIncomingCallWindowTaskHandler.removeCallbacks(showIncomingCallWindowTask);
388+
if (showIncomingCallWindowTask != null) {
389+
showIncomingCallWindowTaskHandler.removeCallbacks(showIncomingCallWindowTask);
390+
}
345391
}
346392

347393
private void addIncomeCallFragment() {
@@ -448,6 +494,11 @@ public void onReceiveHangUpFromUser(final QBRTCSession session, final Integer us
448494
}
449495
}
450496

497+
@Override
498+
public void onChangeReconnectionState(QBRTCSession qbrtcSession, Integer userId, QBRTCTypes.QBRTCReconnectionState qbrtcReconnectionState) {
499+
// empty
500+
}
501+
451502
@Override
452503
public void onCallAcceptByUser(QBRTCSession session, Integer userId, Map<String, String> userInfo) {
453504
if (callService.isCurrentSession(session)) {
@@ -646,6 +697,11 @@ public QBRTCVideoTrack getVideoTrack(Integer userId) {
646697
return callService.getVideoTrack(userId);
647698
}
648699

700+
@Override
701+
public QBRTCTypes.QBRTCReconnectionState getState(Integer userId) {
702+
return callService.getState(userId);
703+
}
704+
649705
@Override
650706
public void onStopPreview() {
651707
callService.stopScreenSharing();
@@ -707,7 +763,7 @@ public void run() {
707763
}
708764

709765
public interface OnChangeAudioDevice {
710-
void audioDeviceChanged(AppRTCAudioManager.AudioDevice newAudioDevice);
766+
void audioDeviceChanged(QBAudioManager.AudioDevice newAudioDevice);
711767
}
712768

713769
public interface CurrentCallStateCallback {

sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/PermissionsActivity.java

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ private void allPermissionsGranted() {
103103

104104
@Override
105105
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
106+
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
106107
if (requestCode == PERMISSION_REQUEST_CODE && hasAllPermissionsGranted(grantResults)) {
107108
requiresCheck = true;
108109
allPermissionsGranted();

sample-videochat-java/app/src/main/java/com/quickblox/sample/videochat/java/activities/SplashActivity.java

+31-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.quickblox.sample.videochat.java.activities;
22

3+
import android.Manifest;
34
import android.content.DialogInterface;
45
import android.content.Intent;
56
import android.content.pm.PackageManager;
@@ -11,17 +12,22 @@
1112
import android.util.Log;
1213
import android.widget.TextView;
1314

15+
import androidx.annotation.NonNull;
16+
import androidx.annotation.Nullable;
17+
import androidx.annotation.RequiresApi;
18+
import androidx.appcompat.app.AlertDialog;
19+
import androidx.core.app.ActivityCompat;
20+
import androidx.core.content.ContextCompat;
21+
1422
import com.quickblox.sample.videochat.java.R;
1523
import com.quickblox.sample.videochat.java.services.LoginService;
1624
import com.quickblox.sample.videochat.java.utils.PermissionsChecker;
1725
import com.quickblox.sample.videochat.java.utils.SharedPrefsHelper;
1826
import com.quickblox.sample.videochat.java.utils.ToastUtils;
1927

20-
import androidx.annotation.Nullable;
21-
import androidx.appcompat.app.AlertDialog;
22-
2328
public class SplashActivity extends BaseActivity {
2429
private static final String TAG = SplashActivity.class.getSimpleName();
30+
private static final int NOTIFICATION_PERMISSION_REQUEST_CODE = 1010;
2531

2632
private static final int SPLASH_DELAY = 1500;
2733

@@ -32,6 +38,7 @@ public class SplashActivity extends BaseActivity {
3238

3339
private SharedPrefsHelper sharedPrefsHelper;
3440

41+
@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
3542
@Override
3643
protected void onCreate(Bundle savedInstanceState) {
3744
super.onCreate(savedInstanceState);
@@ -44,11 +51,32 @@ protected void onCreate(Bundle savedInstanceState) {
4451
getSupportActionBar().hide();
4552
}
4653

54+
checkNotificationPermission();
55+
4756
if (checkOverlayPermissions()) {
4857
runNextScreen();
4958
}
5059
}
5160

61+
private void checkNotificationPermission() {
62+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
63+
boolean isNotificationPermissionDenied = ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_DENIED;
64+
65+
if (isNotificationPermissionDenied) {
66+
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.POST_NOTIFICATIONS}, NOTIFICATION_PERMISSION_REQUEST_CODE);
67+
}
68+
}
69+
}
70+
71+
@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
72+
@Override
73+
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
74+
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
75+
if (requestCode == NOTIFICATION_PERMISSION_REQUEST_CODE && grantResults.length > 0 && grantResults[0] != 0) {
76+
ToastUtils.longToast(getString(R.string.permission_unavailable, Manifest.permission.POST_NOTIFICATIONS));
77+
}
78+
}
79+
5280
private void runNextScreen() {
5381
if (sharedPrefsHelper.hasUser()) {
5482
LoginService.start(SplashActivity.this, sharedPrefsHelper.getUser());

0 commit comments

Comments
 (0)