Skip to content

Commit

Permalink
Merge pull request #118 from ConnectyCube/development
Browse files Browse the repository at this point in the history
Release 2.4.0
  • Loading branch information
TatankaConCube committed Nov 17, 2023
2 parents 4e62f10 + e286f5b commit 5d48e68
Show file tree
Hide file tree
Showing 25 changed files with 461 additions and 199 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 2.4.0
- (Android) Add the Call photo to the Call notification and the Incoming call screen;
- (Android) Add different icons to the Accept buttons depending on the call type;
- (Android) Add the possibility for setting the Notification icon depending on the call type;

## 2.3.0
- (iOS) Add a method for notifying the CallKit about muting/unmuting the call;
- (iOS) Improvements for audio after accepting the call from the background or killed state;
Expand Down
29 changes: 26 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ getting token and displaying the Incoming call screen.
- some customizations according to your app needs (ringtone, icon, accent color(for Android))


<kbd><img alt="Flutter P2P Calls code sample, incoming call in background Android" src="https://developers.connectycube.com/docs/_images/code_samples/flutter/background_call_android.png" height="440" /></kbd> <kbd><img alt="Flutter P2P Calls code sample, incoming call locked Android" src="https://developers.connectycube.com/docs/_images/code_samples/flutter/background_call_android_locked.png" height="440" /></kbd> <kbd><img alt="Flutter P2P Calls code sample, incoming call in background iOS" src="https://developers.connectycube.com/docs/_images/code_samples/flutter/background_call_ios.PNG" height="440" /></kbd>
<kbd><img alt="Flutter P2P Calls code sample, incoming call in background Android" src="https://developers.connectycube.com/docs/_images/code_samples/flutter/background_call_android.png" height="440" /></kbd>
<kbd><img alt="Flutter P2P Calls code sample, incoming call locked Android" src="https://developers.connectycube.com/docs/_images/code_samples/flutter/background_call_android_locked.png" height="440" /></kbd>
<kbd><img alt="Flutter P2P Calls code sample, incoming call in background iOS" src="https://developers.connectycube.com/docs/_images/code_samples/flutter/background_call_ios.PNG" height="440" /></kbd>
<kbd><img alt="Flutter P2P Calls code sample, incoming call locked iOS" src="https://developers.connectycube.com/docs/_images/code_samples/flutter/background_call_ios_locked.PNG" height="440" /></kbd>

## Configure your project
Expand Down Expand Up @@ -82,11 +84,30 @@ and notification accent color (Android only). Use the next method for it:
```dart
ConnectycubeFlutterCallKit.instance.updateConfig(
ringtone: 'custom_ringtone',
icon: 'app_icon',
notificationIcon: 'ic_notification',
icon: Platform.isAndroid ? 'default_avatar' : 'CallKitIcon', // is used as an avatar placeholder for Android and as the app icon for iOS
color: '#07711e');
```

#### [Android only] Notification icon customisation
You can set different icons for Audion and Video calls, add suitable resources to your
`android/app/src/main/AndroidManifest.xml` to the `application` section for it:
```xml
<meta-data
android:name="com.connectycube.flutter.connectycube_flutter_call_kit.audio_call_notification_icon"
android:resource="@drawable/ic_notification_audio_call" />

<meta-data
android:name="com.connectycube.flutter.connectycube_flutter_call_kit.video_call_notification_icon"
android:resource="@drawable/ic_notification_video_call" />
```

If you don't need it, add only the default notification icon:
```xml
<meta-data
android:name="com.connectycube.flutter.connectycube_flutter_call_kit.app_notification_icon"
android:resource="@drawable/ic_notification" />
```

### Show Incoming call notification

```dart
Expand All @@ -98,6 +119,7 @@ CallEvent callEvent = CallEvent(
callerId: incomingCall.callerId,
callerName: 'Caller Name',
opponentsIds: incomingCall.opponentsIds,
callPhoto: 'https://i.imgur.com/KwrDil8b.jpg',
userInfo: {'customParameter1': 'value1'});
ConnectycubeFlutterCallKit.showCallNotification(callEvent);
```
Expand Down Expand Up @@ -221,6 +243,7 @@ params.parameters = {
'caller_id': currentCall.callerId,
'caller_name': callerName,
'call_opponents': currentCall.opponentsIds.join(','),
'photo_url': 'https://i.imgur.com/KwrDil8b.jpg'
'signal_type': 'startCall',
'ios_voip': 1,
};
Expand Down
11 changes: 8 additions & 3 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ group 'com.connectycube.flutter.connectycube_flutter_call_kit'
version '2.3.0'

buildscript {
ext.kotlin_version = '1.6.21'
ext.kotlin_version = '1.9.10'
repositories {
google()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:4.0.2'
classpath 'com.android.tools.build:gradle:7.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.10'
}
Expand All @@ -26,7 +26,7 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

android {
compileSdkVersion 29
compileSdkVersion 34

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
Expand All @@ -42,6 +42,11 @@ android {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'com.google.android.material:material:1.10.0'
implementation 'com.skyfishjy.ripplebackground:library:1.0.1'
implementation 'com.github.bumptech.glide:glide:4.14.2'
annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2'

implementation platform('com.google.firebase:firebase-bom:29.0.3')
implementation 'com.google.firebase:firebase-messaging-ktx'
Expand Down
2 changes: 1 addition & 1 deletion android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
6 changes: 5 additions & 1 deletion android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.connectycube.flutter.connectycube_flutter_call_kit">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />

<application>
<receiver android:name=".EventReceiver" />
<activity
android:name=".IncomingCallActivity"
android:excludeFromRecents="true"
android:inheritShowWhenLocked="true"
android:noHistory="true"
android:screenOrientation="sensorPortrait"
android:showForAllUsers="true"
android:showOnLockScreen="true"
android:showWhenLocked="true"
android:taskAffinity="com.connectycube.flutter.connectycube_flutter_call_kit.INCOMING_CALL_AFFINITY"
android:theme="@android:style/Theme.Holo.NoActionBar"
android:theme="@style/CallkitIncomingTheme"
android:turnScreenOn="true" />

<service
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ class ConnectycubeFCMReceiver : BroadcastReceiver() {
val callType = data["call_type"]?.toInt()
val callInitiatorId = data["caller_id"]?.toInt()
val callInitiatorName = data["caller_name"]
val callPhoto = data["photo_url"]
val callOpponentsString = data["call_opponents"]
var callOpponents = ArrayList<Int>()
if (callOpponentsString != null) {
callOpponents = ArrayList(callOpponentsString.split(',').map { it.toInt() })
}

val userInfo = data["user_info"] ?: JSONObject(emptyMap<String, String>()).toString()

if (callType == null || callInitiatorId == null || callInitiatorName == null || callOpponents.isEmpty()) {
Expand All @@ -86,6 +86,7 @@ class ConnectycubeFCMReceiver : BroadcastReceiver() {
callInitiatorId,
callInitiatorName,
callOpponents,
callPhoto,
userInfo
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ class ConnectycubeFlutterCallKitPlugin : FlutterPlugin, MethodCallHandler,
val callOpponents = ArrayList((arguments["call_opponents"] as String)
.split(',')
.map { it.toInt() })
val callPhoto = arguments["photo_url"] as String?
val userInfo = arguments["user_info"] as String

showCallNotification(
Expand All @@ -156,6 +157,7 @@ class ConnectycubeFlutterCallKitPlugin : FlutterPlugin, MethodCallHandler,
callInitiatorId,
callInitiatorName,
callOpponents,
callPhoto,
userInfo
)

Expand Down Expand Up @@ -293,7 +295,7 @@ class ConnectycubeFlutterCallKitPlugin : FlutterPlugin, MethodCallHandler,
}

"muteCall" -> {
result.success(null)
result.success(null)
}

else ->
Expand Down Expand Up @@ -532,6 +534,7 @@ class CallStreamHandler(private var context: Context) : EventChannel.StreamHandl
callEventMap["caller_name"] = intent.getStringExtra(EXTRA_CALL_INITIATOR_NAME)
callEventMap["call_opponents"] =
intent.getIntegerArrayListExtra(EXTRA_CALL_OPPONENTS)?.joinToString(separator = ",")
callEventMap["photo_url"] = intent.getStringExtra(EXTRA_CALL_PHOTO)
callEventMap["user_info"] = intent.getStringExtra(EXTRA_CALL_USER_INFO)

Log.d("ConnectycubeFlutterCallKitPlugin", "callEventMap: $callEventMap")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const val EXTRA_CALL_INITIATOR_NAME = "extra_call_initiator_name"
const val EXTRA_CALL_OPPONENTS = "extra_call_opponents"
const val EXTRA_CALL_USER_INFO = "extra_call_user_info"
const val EXTRA_PUSH_TOKEN = "extra_push_token"
const val EXTRA_CALL_PHOTO = "photo_url"

const val ACTION_CALL_ACCEPT = "action_call_accept"
const val ACTION_CALL_REJECT = "action_call_reject"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class EventReceiver : BroadcastReceiver() {
val callInitiatorId = extras?.getInt(EXTRA_CALL_INITIATOR_ID)
val callInitiatorName = extras?.getString(EXTRA_CALL_INITIATOR_NAME)
val callOpponents = extras?.getIntegerArrayList(EXTRA_CALL_OPPONENTS)
val callPhoto = extras?.getString(EXTRA_CALL_PHOTO)
val userInfo = extras?.getString(EXTRA_CALL_USER_INFO)
Log.i(TAG, "NotificationReceiver onReceive Call REJECT, callId: $callId")

Expand All @@ -36,6 +37,7 @@ class EventReceiver : BroadcastReceiver() {
bundle.putInt(EXTRA_CALL_INITIATOR_ID, callInitiatorId!!)
bundle.putString(EXTRA_CALL_INITIATOR_NAME, callInitiatorName)
bundle.putIntegerArrayList(EXTRA_CALL_OPPONENTS, callOpponents)
bundle.putString(EXTRA_CALL_PHOTO, callPhoto)
bundle.putString(EXTRA_CALL_USER_INFO, userInfo)
broadcastIntent.putExtras(bundle)

Expand All @@ -62,6 +64,7 @@ class EventReceiver : BroadcastReceiver() {
val callInitiatorId = extras?.getInt(EXTRA_CALL_INITIATOR_ID)
val callInitiatorName = extras?.getString(EXTRA_CALL_INITIATOR_NAME)
val callOpponents = extras?.getIntegerArrayList(EXTRA_CALL_OPPONENTS)
val callPhoto = extras?.getString(EXTRA_CALL_PHOTO)
val userInfo = extras?.getString(EXTRA_CALL_USER_INFO)
Log.i(TAG, "NotificationReceiver onReceive Call ACCEPT, callId: $callId")

Expand All @@ -72,6 +75,7 @@ class EventReceiver : BroadcastReceiver() {
bundle.putInt(EXTRA_CALL_INITIATOR_ID, callInitiatorId!!)
bundle.putString(EXTRA_CALL_INITIATOR_NAME, callInitiatorName)
bundle.putIntegerArrayList(EXTRA_CALL_OPPONENTS, callOpponents)
bundle.putString(EXTRA_CALL_PHOTO, callPhoto)
bundle.putString(EXTRA_CALL_USER_INFO, userInfo)
broadcastIntent.putExtras(bundle)

Expand Down Expand Up @@ -101,6 +105,7 @@ class EventReceiver : BroadcastReceiver() {
val callType = extras?.getInt(EXTRA_CALL_TYPE)
val callInitiatorId = extras?.getInt(EXTRA_CALL_INITIATOR_ID)
val callInitiatorName = extras?.getString(EXTRA_CALL_INITIATOR_NAME)
val callPhoto = extras?.getString(EXTRA_CALL_PHOTO)
val userInfo = extras?.getString(EXTRA_CALL_USER_INFO)
Log.i(
TAG,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.Nullable
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.bumptech.glide.Glide
import com.connectycube.flutter.connectycube_flutter_call_kit.utils.getPhotoPlaceholderResId
import com.google.android.material.imageview.ShapeableImageView
import com.skyfishjy.library.RippleBackground


fun createStartIncomingScreenIntent(
context: Context, callId: String, callType: Int, callInitiatorId: Int,
callInitiatorName: String, opponents: ArrayList<Int>, userInfo: String
callInitiatorName: String, opponents: ArrayList<Int>, callPhoto: String?, userInfo: String
): Intent {
val intent = Intent(context, IncomingCallActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
Expand All @@ -28,6 +32,7 @@ fun createStartIncomingScreenIntent(
intent.putExtra(EXTRA_CALL_INITIATOR_ID, callInitiatorId)
intent.putExtra(EXTRA_CALL_INITIATOR_NAME, callInitiatorName)
intent.putIntegerArrayListExtra(EXTRA_CALL_OPPONENTS, opponents)
intent.putExtra(EXTRA_CALL_PHOTO, callPhoto)
intent.putExtra(EXTRA_CALL_USER_INFO, userInfo)
return intent
}
Expand All @@ -41,6 +46,7 @@ class IncomingCallActivity : Activity() {
private var callInitiatorId = -1
private var callInitiatorName: String? = null
private var callOpponents: ArrayList<Int>? = ArrayList()
private var callPhoto: String? = null
private var callUserInfo: String? = null


Expand All @@ -59,6 +65,10 @@ class IncomingCallActivity : Activity() {
)
}

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q){
setInheritShowWhenLocked(true)
}

processIncomingData(intent)
initUi()
initCallStateReceiver()
Expand All @@ -80,6 +90,7 @@ class IncomingCallActivity : Activity() {
ACTION_CALL_NOTIFICATION_CANCELED, ACTION_CALL_REJECT, ACTION_CALL_ENDED -> {
finishAndRemoveTask()
}

ACTION_CALL_ACCEPT -> finishDelayed()
}
}
Expand Down Expand Up @@ -116,6 +127,7 @@ class IncomingCallActivity : Activity() {
callInitiatorId = intent.getIntExtra(EXTRA_CALL_INITIATOR_ID, -1)
callInitiatorName = intent.getStringExtra(EXTRA_CALL_INITIATOR_NAME)
callOpponents = intent.getIntegerArrayListExtra(EXTRA_CALL_OPPONENTS)
callPhoto = intent.getStringExtra(EXTRA_CALL_PHOTO)
callUserInfo = intent.getStringExtra(EXTRA_CALL_USER_INFO)
}

Expand All @@ -127,21 +139,40 @@ class IncomingCallActivity : Activity() {
findViewById(resources.getIdentifier("call_type_txt", "id", packageName))
callSubTitleTxt.text =
String.format(CALL_TYPE_PLACEHOLDER, if (callType == 1) "Video" else "Audio")
val avatarImg: ImageView =

val callAcceptButton: ImageView =
findViewById(resources.getIdentifier("start_call_btn", "id", packageName))
val acceptButtonIconName = if (callType == 1) "ic_video_call_start" else "ic_call_start"
callAcceptButton.setImageResource(
resources.getIdentifier(
acceptButtonIconName,
"drawable",
packageName
)
)

val avatarImg: ShapeableImageView =
findViewById(resources.getIdentifier("avatar_img", "id", packageName))

val defaultImgResId = resources.getIdentifier("connectycube_place_holder", "drawable", packageName)
val customAvatarResName = com.connectycube.flutter.connectycube_flutter_call_kit.utils.getString(this, "icon")
if (TextUtils.isEmpty(customAvatarResName)){
avatarImg.setImageResource(defaultImgResId)
val defaultPhotoResId = getPhotoPlaceholderResId(applicationContext)

if (!TextUtils.isEmpty(callPhoto)) {
Glide.with(applicationContext)
.load(callPhoto)
.error(defaultPhotoResId)
.placeholder(defaultPhotoResId)
.into(avatarImg)
} else {
val imgResourceId = resources.getIdentifier(customAvatarResName, "drawable", packageName)
if (imgResourceId != 0){
avatarImg.setImageResource(imgResourceId)
} else {
avatarImg.setImageResource(defaultImgResId)
}
avatarImg.setImageResource(defaultPhotoResId)
}

val acceptButtonAnimation: RippleBackground =
findViewById(resources.getIdentifier("accept_button_animation", "id", packageName))
acceptButtonAnimation.startRippleAnimation()

val rejectButtonAnimation: RippleBackground =
findViewById(resources.getIdentifier("reject_button_animation", "id", packageName))
rejectButtonAnimation.startRippleAnimation()
}

// calls from layout file
Expand All @@ -152,6 +183,7 @@ class IncomingCallActivity : Activity() {
bundle.putInt(EXTRA_CALL_INITIATOR_ID, callInitiatorId)
bundle.putString(EXTRA_CALL_INITIATOR_NAME, callInitiatorName)
bundle.putIntegerArrayList(EXTRA_CALL_OPPONENTS, callOpponents)
bundle.putString(EXTRA_CALL_PHOTO, callPhoto)
bundle.putString(EXTRA_CALL_USER_INFO, callUserInfo)

val endCallIntent = Intent(this, EventReceiver::class.java)
Expand All @@ -168,6 +200,7 @@ class IncomingCallActivity : Activity() {
bundle.putInt(EXTRA_CALL_INITIATOR_ID, callInitiatorId)
bundle.putString(EXTRA_CALL_INITIATOR_NAME, callInitiatorName)
bundle.putIntegerArrayList(EXTRA_CALL_OPPONENTS, callOpponents)
bundle.putString(EXTRA_CALL_PHOTO, callPhoto)
bundle.putString(EXTRA_CALL_USER_INFO, callUserInfo)

val startCallIntent = Intent(this, EventReceiver::class.java)
Expand Down
Loading

0 comments on commit 5d48e68

Please sign in to comment.