diff --git a/CHANGELOG.md b/CHANGELOG.md index 945ad2d..e8a9eb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.5 + +* fix Android permission not working + ## 0.1.4 * fix userName vs Password is null object reference diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml index 1463a12..27b8f82 100644 --- a/android/src/main/AndroidManifest.xml +++ b/android/src/main/AndroidManifest.xml @@ -1,8 +1,6 @@ - - diff --git a/android/src/main/kotlin/com/namit/flutter_wowza/FlutterWOWZCameraView.kt b/android/src/main/kotlin/com/namit/flutter_wowza/FlutterWOWZCameraView.kt index 39a756f..46fcf30 100644 --- a/android/src/main/kotlin/com/namit/flutter_wowza/FlutterWOWZCameraView.kt +++ b/android/src/main/kotlin/com/namit/flutter_wowza/FlutterWOWZCameraView.kt @@ -30,15 +30,14 @@ import io.flutter.plugin.platform.PlatformView class FlutterWOWZCameraView internal constructor(private val context: Context?, private val registrar: PluginRegistry.Registrar, private val methodChannel: MethodChannel, id: Int?, params: Map?) : - PlatformView, MethodChannel.MethodCallHandler, WOWZBroadcastStatusCallback, WOWZStatusCallback, PluginRegistry.RequestPermissionsResultListener { - - //define callback interface - interface PermissionCallbackInterface { - fun onPermissionResult(result: Boolean) - } + PlatformView, MethodChannel.MethodCallHandler, + WOWZBroadcastStatusCallback, WOWZStatusCallback, + PluginRegistry.RequestPermissionsResultListener { private var mPermissionsGranted = false private var hasRequestedPermissions = false + var videoIsInitialized = false + var audioIsInitialized = false private val PERMISSIONS_REQUEST_CODE = 0x1 @@ -49,8 +48,6 @@ constructor(private val context: Context?, private val registrar: PluginRegistry // Manifest.permission.READ_PHONE_STATE ) - private var callbackFunction: PermissionCallbackInterface? = null - private val goCoderCameraView: WOWZCameraView = WOWZCameraView(context) // The top-level GoCoder API interface private var goCoder: WowzaGoCoder? = null @@ -62,6 +59,8 @@ constructor(private val context: Context?, private val registrar: PluginRegistry private var goCoderBroadcastConfig: WOWZBroadcastConfig? = null init { + registrar.addRequestPermissionsResultListener(this) + methodChannel.setMethodCallHandler(this) // Create a broadcaster instance goCoderBroadcaster = WOWZBroadcast() @@ -129,51 +128,18 @@ constructor(private val context: Context?, private val registrar: PluginRegistry goCoderCameraView.scaleMode = scale } + "init_go_coder" -> { + if (requestPermissionToAccess()) + onPermissionResult(true) + } "start_preview" -> { - if (goCoder != null) { - var videoIsInitialized = false - var audioIsInitialized = false - this.hasDevicePermissionToAccess(object : PermissionCallbackInterface { - override fun onPermissionResult(result: Boolean) { - - Log.i("FlutterWOWZCameraView", "onPermissionResult $result") - - if (result) { - // Initialize the camera preview - if (hasDevicePermissionToAccess(Manifest.permission.CAMERA)) { - val availableCameras = goCoderCameraView.cameras - // Ensure we can access to at least one camera - if (availableCameras.isNotEmpty()) { - // Set the video broadcaster in the broadcast config - goCoderBroadcastConfig?.videoBroadcaster = goCoderCameraView - videoIsInitialized = true - Log.i("FlutterWOWZCameraView", "*** getOriginalFrameSizes - Get original frame size : ") - } else { - Log.i("FlutterWOWZCameraView", "Could not detect or gain access to any cameras on this device") - goCoderBroadcastConfig?.isVideoEnabled = false - } - } - - if (hasDevicePermissionToAccess(Manifest.permission.RECORD_AUDIO)) { - // Create an audio device instance for capturing and broadcasting audio - goCoderAudioDevice = WOWZAudioDevice() - // Set the audio broadcaster in the broadcast config - goCoderBroadcastConfig?.audioBroadcaster = goCoderAudioDevice - audioIsInitialized = true - } - - if (videoIsInitialized && audioIsInitialized) { - Log.i("FlutterWOWZCameraView", "startPreview") - if (!goCoderCameraView.isPreviewing) - goCoderCameraView.startPreview() - } - } - } - }) - + if (requestPermissionToAccess()) { + if (videoIsInitialized && audioIsInitialized && !goCoderCameraView.isPreviewing ) + goCoderCameraView.startPreview() + else + onPermissionResult(true) } } - "pause_preview" -> activeCamera?.pausePreview() "continue_preview" -> activeCamera.continuePreview() @@ -254,29 +220,37 @@ constructor(private val context: Context?, private val registrar: PluginRegistry } } - private fun hasDevicePermissionToAccess(callback: PermissionCallbackInterface) { - this.callbackFunction = callback - var result = false - - if (goCoderBroadcaster != null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - result = if (mRequiredPermissions.isNotEmpty()) hasDevicePermissionToAccess(mRequiredPermissions) else true - - if (!result && !hasRequestedPermissions) { - ActivityCompat.requestPermissions(registrar.activity(), - mRequiredPermissions, - PERMISSIONS_REQUEST_CODE) - hasRequestedPermissions = true - } + private fun requestPermissionToAccess(): Boolean { + var result = true + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + result = if (mRequiredPermissions.isNotEmpty()) checkPermissionToAccess(mRequiredPermissions) else true + + if (!result && !hasRequestedPermissions) { + ActivityCompat.requestPermissions(registrar.activity(), + mRequiredPermissions, + PERMISSIONS_REQUEST_CODE) + hasRequestedPermissions = true } } - - this.callbackFunction?.onPermissionResult(result) + return result } - private fun hasDevicePermissionToAccess(permissions: Array): Boolean { + private fun requestPermissionToAccess(source: String): Boolean { var result = true + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + result = if (mRequiredPermissions.isNotEmpty()) checkPermissionToAccess(source) else true + if (!result && !hasRequestedPermissions) { + ActivityCompat.requestPermissions(registrar.activity(), + mRequiredPermissions, + PERMISSIONS_REQUEST_CODE) + hasRequestedPermissions = true + } + } + return result + } + private fun checkPermissionToAccess(permissions: Array): Boolean { + var result = true if (goCoderBroadcaster != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { for (permission in permissions) { @@ -285,19 +259,23 @@ constructor(private val context: Context?, private val registrar: PluginRegistry } } } + } else { + Log.e("FlutterWOWZCameraView", "goCoderBroadcaster is null!") + result = false } - - Log.i("FlutterWOWZCameraView", "hasDevicePermissionToAccess $result") return result } - private fun hasDevicePermissionToAccess(source: String): Boolean { + private fun checkPermissionToAccess(source: String): Boolean { if (goCoderBroadcaster != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(registrar.activity(), source) == PackageManager.PERMISSION_DENIED) { return false } } + } else { + Log.e("FlutterWOWZCameraView", "goCoderBroadcaster is null!") + return false } return true } @@ -312,9 +290,56 @@ constructor(private val context: Context?, private val registrar: PluginRegistry } } hasRequestedPermissions = false + onPermissionResult(mPermissionsGranted) } } - this.callbackFunction?.onPermissionResult(mPermissionsGranted) + + Log.i("FlutterWOWZCameraView", "onRequestPermissionsResult has requested: $hasRequestedPermissions") return true } + + private fun onPermissionResult(mPermissionsGranted: Boolean) { + if (goCoder != null) { + if (mPermissionsGranted) { + // Initialize the camera preview + if (requestPermissionToAccess(Manifest.permission.CAMERA)) { + if(!videoIsInitialized) { + val availableCameras = goCoderCameraView.cameras + // Ensure we can access to at least one camera + if (availableCameras.isNotEmpty()) { + // Set the video broadcaster in the broadcast config + goCoderBroadcastConfig?.videoBroadcaster = goCoderCameraView + videoIsInitialized = true + Log.i("FlutterWOWZCameraView", "*** getOriginalFrameSizes - Get original frame size : ") + } else { + Log.e("FlutterWOWZCameraView", "Could not detect or gain access to any cameras on this device") + goCoderBroadcastConfig?.isVideoEnabled = false + } + } + } else { + Log.e("FlutterWOWZCameraView", "Exception Fail to connect to camera service. I checked camera permission in Settings") + } + + if (requestPermissionToAccess(Manifest.permission.RECORD_AUDIO)) { + if(!audioIsInitialized) { + // Create an audio device instance for capturing and broadcasting audio + goCoderAudioDevice = WOWZAudioDevice() + // Set the audio broadcaster in the broadcast config + goCoderBroadcastConfig?.audioBroadcaster = goCoderAudioDevice + audioIsInitialized = true + } + } else { + Log.e("FlutterWOWZCameraView", "Exception Fail to connect to record audio service. I checked camera permission in Settings") + } + + if (videoIsInitialized && audioIsInitialized) { + Log.i("FlutterWOWZCameraView", "startPreview") + if (!goCoderCameraView.isPreviewing) + goCoderCameraView.startPreview() + } + } + } else { + Log.e("FlutterWOWZCameraView", "goCoder is null!, Please check the license key GoCoder SDK, maybe your license key GoCoder SDK is wrong!") + } + } } \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart index 4e34325..7e177a6 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -35,8 +35,8 @@ class _MyAppState extends State { width: 1280, child: WOWZCameraView( apiLicenseKey: (defaultTargetPlatform == TargetPlatform.android) - ? "GOSK-xxxx-xxxx-xxxx-xxxx-xxxx" - : "GOSK-xxxx-xxxx-xxxx-xxxx-xxxx", + ? "GOSK-9C47-010C-2895-D225-9FEF" + : "GOSK-9C47-010C-A9B9-EB78-3FBD", controller: controller, hostAddress: "xxx.xxx.xxx.xxx", portNumber: 1935, diff --git a/example/pubspec.lock b/example/pubspec.lock index 2c235b4..87f4980 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -80,7 +80,7 @@ packages: path: ".." relative: true source: path - version: "0.0.1" + version: "0.1.4" image: dependency: transitive description: @@ -200,3 +200,4 @@ packages: version: "3.5.0" sdks: dart: ">=2.4.0 <3.0.0" + flutter: ">=1.10.0 <2.0.0" diff --git a/ios/Classes/FlutterWOWZCameraView.swift b/ios/Classes/FlutterWOWZCameraView.swift index 5761d3d..66cf013 100644 --- a/ios/Classes/FlutterWOWZCameraView.swift +++ b/ios/Classes/FlutterWOWZCameraView.swift @@ -133,11 +133,11 @@ public class FlutterWOWZCameraView : NSObject, FlutterPlatformView,WOWZBroadcast self.goCoder = goCoder print("gocoder is init!") WowzaGoCoder.requestPermission(for: .camera, response: { (permission) in - print("Camera permission is: \(permission == .authorized ? "authorized" : "denied")") + print("Camera permission is: \(permission == .authorized ? "authorized" : "denied")") }) WowzaGoCoder.requestPermission(for: .microphone, response: { (permission) in - print("Microphone permission is: \(permission == .authorized ? "authorized" : "denied")") + print("Microphone permission is: \(permission == .authorized ? "authorized" : "denied")") }) self.goCoder?.config = self.goCoderConfig self.goCoder?.cameraView = self.uiView @@ -146,11 +146,11 @@ public class FlutterWOWZCameraView : NSObject, FlutterPlatformView,WOWZBroadcast break case "start_preview": WowzaGoCoder.requestPermission(for: .camera, response: { (permission) in - print("Camera permission is: \(permission == .authorized ? "authorized" : "denied")") + print("Camera permission is: \(permission == .authorized ? "authorized" : "denied")") }) WowzaGoCoder.requestPermission(for: .microphone, response: { (permission) in - print("Microphone permission is: \(permission == .authorized ? "authorized" : "denied")") + print("Microphone permission is: \(permission == .authorized ? "authorized" : "denied")") }) self.cameraView?.start() break; diff --git a/lib/gocoder/src/wowz_camera_view.dart b/lib/gocoder/src/wowz_camera_view.dart index 408ab44..6b73b02 100644 --- a/lib/gocoder/src/wowz_camera_view.dart +++ b/lib/gocoder/src/wowz_camera_view.dart @@ -195,12 +195,20 @@ class _WOWZCameraViewState extends State { widget.controller?._setChannel(_channel); // license key gocoder sdk - _channel.invokeMethod(_apiLicenseKey, widget.apiLicenseKey); + _channel.invokeMethod(_apiLicenseKey, widget.apiLicenseKey); // Set the connection properties for the target Wowza Streaming Engine server or Wowza Streaming Cloud live stream - _channel.invokeMethod(_hostAddress, widget.hostAddress); - _channel.invokeMethod(_portNumber, widget.portNumber); - _channel.invokeMethod(_applicationName, widget.applicationName); - _channel.invokeMethod(_streamName, widget.streamName); + if (widget.hostAddress != null && widget.hostAddress.isNotEmpty) { + _channel.invokeMethod(_hostAddress, widget.hostAddress); + } + if (widget.portNumber != null) { + _channel.invokeMethod(_portNumber, widget.portNumber); + } + if (widget.applicationName != null && widget.applicationName.isNotEmpty) { + _channel.invokeMethod(_applicationName, widget.applicationName); + } + if (widget.streamName != null && widget.streamName.isNotEmpty) { + _channel.invokeMethod(_streamName, widget.streamName); + } //authentication if (widget.username != null) { _channel.invokeMethod(_username, widget.username); @@ -219,15 +227,12 @@ class _WOWZCameraViewState extends State { if (widget.scaleMode != null) { _channel.invokeMethod(_scaleMode, widget.scaleMode.toString()); } - if(widget.fps!=null){ _channel.invokeListMethod(_fps,widget.fps); } - if(widget.bps !=null){ _channel.invokeListMethod(_bps,widget.bps); } - if(widget.khz !=null){ _channel.invokeListMethod(_bps,widget.bps); } diff --git a/pubspec.lock b/pubspec.lock index 67a7df1..88711b4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -186,3 +186,4 @@ packages: version: "3.5.0" sdks: dart: ">=2.4.0 <3.0.0" + flutter: ">=1.10.0 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 1fee8d0..af6fca6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_wowza description: Flutter WOWZA plugin for iOS/Android. The project is based on Wowza GoCoder SDK homepage: https://github.com/VNAPNIC/flutter-wowza -version: 0.1.4 +version: 0.1.5 author: vn.apnic@gmail.comn environment: