Skip to content

Commit

Permalink
-android using service for ringtone
Browse files Browse the repository at this point in the history
-iOS getDevicePushTokenVoIP feature
  • Loading branch information
hiennguyen92 committed Feb 21, 2022
1 parent b3f0c5f commit a6e0e5e
Show file tree
Hide file tree
Showing 21 changed files with 238 additions and 154 deletions.
6 changes: 4 additions & 2 deletions PUSHKIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ If you are making VoIP application than you definitely want to update your appli
## 🚀  Setup


Make sure when you create Bundle ID(https://developer.apple.com/account/resources/identifiers) for app you have checked `Push Notifications`
Make sure when you create Bundle ID(https://developer.apple.com/account/resources/identifiers) for you have checked `Push Notifications`

1. Enable Voice over IP Setting
* Xcode Project > Capabilities

![image info](https://raw.githubusercontent.com/hiennguyen92/flutter_callkit_incoming/master/images/Setting.png)

<br>
make sure when you create Bundle ID(https://developer.apple.com/account/resources/identifiers) you have checked Push Notifications

* VoIP Services Certificate

Go to https://developer.apple.com/account/resources/certificates/add
Expand Down Expand Up @@ -63,6 +63,7 @@ make sure when you create Bundle ID(https://developer.apple.com/account/resource
<br>
<br>
3. Testing

* Using App
https://github.com/onmyway133/PushNotifications

Expand All @@ -75,6 +76,7 @@ make sure when you create Bundle ID(https://developer.apple.com/account/resource
curl -v \
-d '{"aps":{"alert":"Hien Nguyen Call"},"id":"44d915e1-5ff4-4bed-bf13-c423048ec97a","nameCaller":"Hien Nguyen","handle":"0123456789","isVideo":true}' \
-H "apns-topic: com.hiennv.testing.voip" \
-H "apns-push-type: voip" \
--http2 \
--cert VOIP.pem:'<passphrase>' \
https://api.development.push.apple.com/3/device/<device token>
Expand Down
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,36 @@ A Flutter plugin to show incoming call in your Flutter app(Custom for Android/Ca
[{"id": "8BAA2B26-47AD-42C1-9197-1D75F662DF78", ...}]
```

* Get device push token VoIP. iOS: return deviceToken, Android: Empty

```dart
await FlutterCallkitIncoming.getDevicePushTokenVoIP();
```
Output

```json
<device token>

//Example
d6a77ca80c5f09f87f353cdd328ec8d7d34e92eb108d046c91906f27f54949cd
```
Make sure using `SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken)` inside AppDelegate.swift (<a href="https://github.com/hiennguyen92/flutter_callkit_incoming/blob/master/example/ios/Runner/AppDelegate.swift">Example</a>)
```swift
func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) {
print(credentials.token)
let deviceToken = credentials.token.map { String(format: "%02x", $0) }.joined()
//Save deviceToken to your server
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken)
}
func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
print("didInvalidatePushTokenFor")
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP("")
}
```


* Listen events
```dart
FlutterCallkitIncoming.onEvent.listen((event) {
Expand Down Expand Up @@ -168,6 +198,9 @@ A Flutter plugin to show incoming call in your Flutter app(Custom for Android/Ca
case CallEvent.ACTION_CALL_TOGGLE_AUDIO_SESSION:
// TODO: only iOS
break;
case CallEvent.ACTION_DID_UPDATE_DEVICE_PUSH_TOKEN_VOIP:
// TODO: only iOS
break;
}
});
```
Expand All @@ -186,6 +219,7 @@ A Flutter plugin to show incoming call in your Flutter app(Custom for Android/Ca
let data = flutter_callkit_incoming.Data(id: "44d915e1-5ff4-4bed-bf13-c423048ec97a", nameCaller: "Hien Nguyen", handle: "0123456789", type: 0)
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.showCallkitIncoming(data, fromPushKit: true)
```

```objc
//Objective-C
#if __has_include(<flutter_callkit_incoming/flutter_callkit_incoming-Swift.h>)
Expand All @@ -199,6 +233,13 @@ A Flutter plugin to show incoming call in your Flutter app(Custom for Android/Ca
[SwiftFlutterCallkitIncomingPlugin.sharedInstance showCallkitIncoming:data fromPushKit:YES];
```

```java
//send custom event from native
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.sendEventCustom("customEvent", body: ["customKey": "customValue"])


```

4. Properties

| Prop | Description | Default |
Expand Down Expand Up @@ -267,7 +308,6 @@ A Flutter plugin to show incoming call in your Flutter app(Custom for Android/Ca

7. Todo
* Add `WakeLock` (background tasks) for Android
* Switch using `service` for Android

<br>

Expand Down
5 changes: 5 additions & 0 deletions android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,10 @@
</intent-filter>
</receiver>

<service
android:enabled="true"
android:exported="true"
android:name=".CallkitSoundPlayerService"/>

</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import android.view.animation.AnimationUtils
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.hiennv.flutter_callkit_incoming.CallkitIncomingBroadcastReceiver.Companion.ACTION_CALL_INCOMING
import com.hiennv.flutter_callkit_incoming.CallkitIncomingBroadcastReceiver.Companion.EXTRA_CALLKIT_AVATAR
Expand All @@ -34,6 +36,10 @@ import de.hdodenhof.circleimageview.CircleImageView
import kotlin.math.abs
import okhttp3.OkHttpClient
import com.squareup.picasso.OkHttp3Downloader
import android.view.ViewGroup.MarginLayoutParams





class CallkitIncomingActivity : Activity() {
Expand Down Expand Up @@ -77,6 +83,7 @@ class CallkitIncomingActivity : Activity() {
private lateinit var ivLogo: ImageView
private lateinit var ivAvatar: CircleImageView

private lateinit var llAction: LinearLayout
private lateinit var ivAcceptCall: ImageView
private lateinit var ivDeclineCall: ImageView

Expand Down Expand Up @@ -217,6 +224,12 @@ class CallkitIncomingActivity : Activity() {
ivLogo = findViewById(R.id.ivLogo)
ivAvatar = findViewById(R.id.ivAvatar)

llAction = findViewById(R.id.llAction)

val params = llAction.layoutParams as MarginLayoutParams
params.setMargins(0,0,0,Utils.getNavigationBarHeight(this@CallkitIncomingActivity))
llAction.layoutParams = params

ivAcceptCall = findViewById(R.id.ivAcceptCall)
ivDeclineCall = findViewById(R.id.ivDeclineCall)
animateAcceptCall()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper

class CallkitIncomingBroadcastReceiver : BroadcastReceiver() {

Expand Down Expand Up @@ -92,17 +90,17 @@ class CallkitIncomingBroadcastReceiver : BroadcastReceiver() {


override fun onReceive(context: Context, intent: Intent) {
val callkitSoundPlayer = CallkitSoundPlayer.getInstance(context.applicationContext)
//val callkitSoundPlayer = CallkitSoundPlayer.getInstance(context.applicationContext)
val callkitNotificationManager = CallkitNotificationManager(context)
val action = intent.action ?: return
val data = intent.extras?.getBundle(EXTRA_CALLKIT_INCOMING_DATA) ?: return
when (action) {
ACTION_CALL_INCOMING -> {
try {
sendEventFlutter(ACTION_CALL_INCOMING, data)
val duration = data.getLong(EXTRA_CALLKIT_DURATION, 0L)
callkitSoundPlayer.setDuration(duration)
callkitSoundPlayer.play(data)
val soundPlayerServiceIntent = Intent(context, CallkitSoundPlayerService::class.java)
soundPlayerServiceIntent.putExtras(data)
context.startService(soundPlayerServiceIntent)
} catch (error: Exception) {
error.printStackTrace()
}
Expand All @@ -119,7 +117,7 @@ class CallkitIncomingBroadcastReceiver : BroadcastReceiver() {
try {
Utils.backToForeground(context)
sendEventFlutter(ACTION_CALL_ACCEPT, data)
callkitSoundPlayer.stop()
context.stopService(Intent(context, CallkitSoundPlayerService::class.java))
callkitNotificationManager.clearIncomingNotification(data)
addCall(context, Data.fromBundle(data))
} catch (error: Exception) {
Expand All @@ -129,7 +127,7 @@ class CallkitIncomingBroadcastReceiver : BroadcastReceiver() {
ACTION_CALL_DECLINE -> {
try {
sendEventFlutter(ACTION_CALL_DECLINE, data)
callkitSoundPlayer.stop()
context.stopService(Intent(context, CallkitSoundPlayerService::class.java))
callkitNotificationManager.clearIncomingNotification(data)
removeCall(context, Data.fromBundle(data))
} catch (error: Exception) {
Expand All @@ -139,7 +137,7 @@ class CallkitIncomingBroadcastReceiver : BroadcastReceiver() {
ACTION_CALL_ENDED -> {
try {
sendEventFlutter(ACTION_CALL_ENDED, data)
callkitSoundPlayer.stop()
context.stopService(Intent(context, CallkitSoundPlayerService::class.java))
callkitNotificationManager.clearIncomingNotification(data)
removeCall(context, Data.fromBundle(data))
} catch (error: Exception) {
Expand All @@ -149,7 +147,7 @@ class CallkitIncomingBroadcastReceiver : BroadcastReceiver() {
ACTION_CALL_TIMEOUT -> {
try {
sendEventFlutter(ACTION_CALL_TIMEOUT, data)
callkitSoundPlayer.stop()
context.stopService(Intent(context, CallkitSoundPlayerService::class.java))
callkitNotificationManager.showMissCallNotification(data)
removeCall(context, Data.fromBundle(data))
} catch (error: Exception) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ import android.graphics.drawable.Drawable
import android.media.AudioAttributes
import android.media.RingtoneManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.*
import android.view.View
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
Expand Down Expand Up @@ -78,6 +75,7 @@ class CallkitNotificationManager(private val context: Context) {

notificationBuilder = NotificationCompat.Builder(context, "callkit_incoming_channel_id")
notificationBuilder.setAutoCancel(false)
notificationBuilder.setChannelId("callkit_incoming_channel_id")
notificationBuilder.setDefaults(NotificationCompat.DEFAULT_VIBRATE)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notificationBuilder.setCategory(Notification.CATEGORY_CALL)
Expand Down Expand Up @@ -160,7 +158,9 @@ class CallkitNotificationManager(private val context: Context) {
).build()
notificationBuilder.addAction(acceptAction)
}
getNotificationManager().notify(notificationId, notificationBuilder.build())
val notification = notificationBuilder.build()
notification.flags = Notification.FLAG_INSISTENT
getNotificationManager().notify(notificationId, notification)
}

fun showMissCallNotification(data: Bundle) {
Expand All @@ -177,6 +177,7 @@ class CallkitNotificationManager(private val context: Context) {
}
}
notificationBuilder = NotificationCompat.Builder(context, "callkit_missed_channel_id")
notificationBuilder.setChannelId("callkit_missed_channel_id")
notificationBuilder.setContentTitle(data.getString(EXTRA_CALLKIT_NAME_CALLER, ""))
notificationBuilder.setContentText(data.getString(EXTRA_CALLKIT_HANDLE, ""))
notificationBuilder.setSubText(context.getString(R.string.text_missed_call))
Expand Down Expand Up @@ -205,18 +206,17 @@ class CallkitNotificationManager(private val context: Context) {
notificationBuilder.color = Color.parseColor(actionColor)
} catch (error: Exception) {
}
notificationBuilder.setChannelId("callkit_missed_channel_id")
val callbackAction: NotificationCompat.Action = NotificationCompat.Action.Builder(
R.drawable.ic_accept,
context.getString(R.string.text_call_back),
getCallbackPendingIntent(notificationId, data)
).build()
notificationBuilder.addAction(callbackAction)

getNotificationManager().notify(notificationId, notificationBuilder.build())
val notification = notificationBuilder.build()
getNotificationManager().notify(notificationId, notification)
Handler(Looper.getMainLooper()).postDelayed({
try {
getNotificationManager().notify(notificationId, notificationBuilder.build())
getNotificationManager().notify(notificationId, notification)
} catch (error: Exception) {
}
}, 1000)
Expand Down Expand Up @@ -250,7 +250,7 @@ class CallkitNotificationManager(private val context: Context) {
).apply {
description = ""
vibrationPattern =
longArrayOf(1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000)
longArrayOf(0, 1000, 500, 1000, 500)
lightColor = Color.RED
enableLights(true)
enableVibration(true)
Expand All @@ -259,7 +259,7 @@ class CallkitNotificationManager(private val context: Context) {

val attributes = AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_UNKNOWN)
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
.build()
val channelMissedCall = NotificationChannel(
"callkit_missed_channel_id",
Expand Down
Loading

0 comments on commit a6e0e5e

Please sign in to comment.