Skip to content

Commit

Permalink
Merge pull request #65 from shounakmulay/fix/background_call
Browse files Browse the repository at this point in the history
Fix error on calling telephony methods in background. Fix type cast error in getSms methods.
  • Loading branch information
shounakmulay authored Mar 28, 2021
2 parents 6246f14 + 0c8ed1b commit e43a062
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 100 deletions.
Original file line number Diff line number Diff line change
@@ -1,41 +1,35 @@
package com.shounakmulay.telephony

import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import com.shounakmulay.telephony.utils.Constants.PHONE_PERMISSIONS
import com.shounakmulay.telephony.utils.Constants.SERVICE_STATE_PERMISSIONS
import com.shounakmulay.telephony.utils.Constants.SMS_PERMISSIONS

object PermissionsController {
class PermissionsController(private val context: Context) {

private lateinit var activity: Activity
var isRequestingPermission: Boolean = false

fun setActivity(activity: Activity) {
PermissionsController.activity = activity
}

fun hasRequiredPermissions(permissions: List<String>): Boolean {
if (this::activity.isInitialized) {
var hasPermissions = true
for (permission in permissions) {
hasPermissions = hasPermissions && checkPermission(permission)
}
return hasPermissions
}
return false
}

private fun checkPermission(permission: String): Boolean {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || activity.checkSelfPermission(permission) == PERMISSION_GRANTED
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || context.checkSelfPermission(permission) == PERMISSION_GRANTED
}

@RequiresApi(Build.VERSION_CODES.M)
fun requestPermissions(permissions: List<String>, requestCode: Int) {
if (this::activity.isInitialized && !isRequestingPermission) {
fun requestPermissions(activity: Activity, permissions: List<String>, requestCode: Int) {
if (!isRequestingPermission) {
isRequestingPermission = true
activity.requestPermissions(permissions.toTypedArray(), requestCode)
}
Expand All @@ -57,12 +51,9 @@ object PermissionsController {
}

private fun getListedPermissions(): Array<out String> {
if (this::activity.isInitialized) {
activity.applicationContext.apply {
context.apply {
val info = packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS)
return info.requestedPermissions ?: arrayOf()
}
}
return arrayOf()
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.shounakmulay.telephony

import android.app.Activity
import android.content.Context
import androidx.annotation.NonNull
import com.shounakmulay.telephony.sms.IncomingSmsHandler
Expand All @@ -23,11 +24,17 @@ class TelephonyPlugin : FlutterPlugin, ActivityAware {

private lateinit var binaryMessenger: BinaryMessenger

private lateinit var permissionsController: PermissionsController

override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
val isInForeground = IncomingSmsHandler.isApplicationForeground(flutterPluginBinding.applicationContext);
if (!this::binaryMessenger.isInitialized && isInForeground) {
val isInForeground = IncomingSmsHandler.isApplicationForeground(flutterPluginBinding.applicationContext)
if (!this::binaryMessenger.isInitialized) {
binaryMessenger = flutterPluginBinding.binaryMessenger
}

if (!isInForeground) {
setupPlugin(flutterPluginBinding.applicationContext, binaryMessenger)
}
}

override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
Expand All @@ -43,24 +50,24 @@ class TelephonyPlugin : FlutterPlugin, ActivityAware {
}

override fun onAttachedToActivity(binding: ActivityPluginBinding) {
setupPlugin(binding.activity.applicationContext, binaryMessenger)
PermissionsController.setActivity(binding.activity)
setupPlugin(binding.activity.applicationContext, binaryMessenger, binding.activity)
binding.addRequestPermissionsResultListener(smsMethodCallHandler)
}

override fun onDetachedFromActivityForConfigChanges() {
onDetachedFromActivity()
}

private fun setupPlugin(context: Context, messenger: BinaryMessenger) {
private fun setupPlugin(context: Context, messenger: BinaryMessenger, activity: Activity? = null) {
smsController = SmsController(context)
smsMethodCallHandler = SmsMethodCallHandler(context, smsController)
permissionsController = PermissionsController(context)
smsMethodCallHandler = SmsMethodCallHandler(context, smsController, permissionsController, activity)

smsChannel = MethodChannel(messenger, CHANNEL_SMS)
smsChannel.setMethodCallHandler(smsMethodCallHandler)
smsMethodCallHandler.setForegroundChannel(smsChannel)

IncomingSmsReceiver.foregroundSmsChannel = smsChannel
val isInForeground = IncomingSmsHandler.isApplicationForeground(context)
if (isInForeground) IncomingSmsReceiver.foregroundSmsChannel = smsChannel
}

private fun tearDownPlugin() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,7 @@ class SmsController(private val context: Context) {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}

if (dialerIntent.resolveActivity(context.packageManager) != null) {
context.startActivity(dialerIntent)
}
context.startActivity(dialerIntent)
}

@RequiresPermission(allOf = [Manifest.permission.CALL_PHONE])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.shounakmulay.telephony.sms

import android.annotation.SuppressLint
import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
Expand Down Expand Up @@ -45,8 +46,14 @@ import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.PluginRegistry


class SmsMethodCallHandler(private val context: Context, private val smsController: SmsController)
: PluginRegistry.RequestPermissionsResultListener, MethodChannel.MethodCallHandler, BroadcastReceiver() {
class SmsMethodCallHandler(
private val context: Context,
private val smsController: SmsController,
private val permissionsController: PermissionsController,
private val activity: Activity? = null
) : PluginRegistry.RequestPermissionsResultListener,
MethodChannel.MethodCallHandler,
BroadcastReceiver() {

private lateinit var result: MethodChannel.Result
private lateinit var action: SmsAction
Expand All @@ -63,7 +70,7 @@ class SmsMethodCallHandler(private val context: Context, private val smsControll

private var setupHandle: Long = -1
private var backgroundHandle: Long = -1

private lateinit var phoneNumber: String

private var requestCode: Int = -1
Expand Down Expand Up @@ -124,11 +131,11 @@ class SmsMethodCallHandler(private val context: Context, private val smsControll
ActionType.CALL -> {
if (call.hasArgument(PHONE_NUMBER)) {
val phoneNumber = call.argument<String>(PHONE_NUMBER)

if (!phoneNumber.isNullOrBlank()) {
this.phoneNumber = phoneNumber
}

handleMethod(action, CALL_REQUEST_CODE)
}
}
Expand Down Expand Up @@ -252,7 +259,7 @@ class SmsMethodCallHandler(private val context: Context, private val smsControll
result.success(value)
}
}

@SuppressLint("MissingPermission")
private fun handleCallActions(smsAction: SmsAction) {
when (smsAction) {
Expand Down Expand Up @@ -293,22 +300,22 @@ class SmsMethodCallHandler(private val context: Context, private val smsControll
SmsAction.BACKGROUND_SERVICE_INITIALIZED,
SmsAction.DISABLE_BACKGROUND_SERVICE,
SmsAction.REQUEST_SMS_PERMISSIONS -> {
val permissions = PermissionsController.getSmsPermissions()
val permissions = permissionsController.getSmsPermissions()
return checkOrRequestPermission(permissions, requestCode)
}
SmsAction.GET_DATA_NETWORK_TYPE,
SmsAction.OPEN_DIALER,
SmsAction.DIAL_PHONE_NUMBER,
SmsAction.REQUEST_PHONE_PERMISSIONS -> {
val permissions = PermissionsController.getPhonePermissions()
val permissions = permissionsController.getPhonePermissions()
return checkOrRequestPermission(permissions, requestCode)
}
SmsAction.GET_SERVICE_STATE -> {
val permissions = PermissionsController.getServiceStatePermissions()
val permissions = permissionsController.getServiceStatePermissions()
return checkOrRequestPermission(permissions, requestCode)
}
SmsAction.REQUEST_PHONE_AND_SMS_PERMISSIONS -> {
val permissions = listOf(PermissionsController.getSmsPermissions(), PermissionsController.getPhonePermissions()).flatten()
val permissions = listOf(permissionsController.getSmsPermissions(), permissionsController.getPhonePermissions()).flatten()
return checkOrRequestPermission(permissions, requestCode)
}
SmsAction.IS_SMS_CAPABLE,
Expand All @@ -329,9 +336,14 @@ class SmsMethodCallHandler(private val context: Context, private val smsControll

@RequiresApi(Build.VERSION_CODES.M)
private fun checkOrRequestPermission(permissions: List<String>, requestCode: Int): Boolean {
PermissionsController.apply {
permissionsController.apply {

if (activity == null) {
return hasRequiredPermissions(permissions)
}

if (!hasRequiredPermissions(permissions)) {
requestPermissions(permissions, requestCode)
requestPermissions(activity, permissions, requestCode)
return false
}
return true
Expand All @@ -340,7 +352,7 @@ class SmsMethodCallHandler(private val context: Context, private val smsControll

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>?, grantResults: IntArray?): Boolean {

PermissionsController.isRequestingPermission = false
permissionsController.isRequestingPermission = false

val deniedPermissions = mutableListOf<String>()
if (requestCode != this.requestCode && !this::action.isInitialized) {
Expand Down
2 changes: 1 addition & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class _MyAppState extends State<MyApp> {
Center(child: Text("Latest received SMS: $_message")),
TextButton(
onPressed: () async {
await telephony.openDialer('123456789');
await telephony.openDialer("123413453");
},
child: Text('Open Dialer'))
],
Expand Down
8 changes: 7 additions & 1 deletion lib/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,13 @@ enum SimState {
}

/// Represents state of cellular service.
enum ServiceState { IN_SERVICE, OUT_OF_SERVICE, EMERGENCY_ONLY, POWER_OFF, UNKNOWN }
enum ServiceState {
IN_SERVICE,
OUT_OF_SERVICE,
EMERGENCY_ONLY,
POWER_OFF,
UNKNOWN
}

/// Represents the quality of cellular signal.
enum SignalStrength { NONE_OR_UNKNOWN, POOR, MODERATE, GOOD, GREAT }
Expand Down
Loading

0 comments on commit e43a062

Please sign in to comment.