Trouble in AS3 Air export APK with Camera Device Android

Hi there, I ask your help!
I have a big trouble with Camera Device in Android Mobile
In Animate CC 2020 with last AIR 33 the Movie preview Android work fine on PC Windows Desktop, but when I export my APK in Android a blank screen occured and nothin Camera appair…
Please please help me…
This is my simple AS3 code…

package {
    import flash.display.Sprite;
    import flash.media.Camera;
    import flash.media.Video;
    import flash.events.MouseEvent;
    import flash.display.StageScaleMode;

    public class Camera_setModeExample extends Sprite {
        private var cam:Camera;
        private var vid:Video;

        public function Camera_setModeExample() {
            stage.scaleMode = StageScaleMode.NO_SCALE;

            cam = Camera.getCamera();
            
            if (!cam) {
                trace("No camera is installed.");
            }else {
                connectCamera();
            }
        }

        private function connectCamera():void {
            vid = new Video();
            vid.width = cam.width;
            vid.height = cam.height; 
            vid.attachCamera(cam);
            addChild(vid);    

            stage.addEventListener(MouseEvent.CLICK, clickHandler);
        }
    
        private function clickHandler(e:MouseEvent):void {

            switch (cam.width) {
                case 160:
                cam.setMode(320, 240, 10); 
                break;
                case 320:
                cam.setMode(640, 480, 5); 
                break;
                default:
                cam.setMode(160, 120, 15); 
                break;
            } 

            removeChild(vid);           
            connectCamera();
        }
    }
}

Admin edit: added triple backticks around source code for syntax hilighting

You should handle Camera permissions like here: https://forum.starling-framework.org/d/18791-cameraui-bitmapdata-problem-since-air-24-permissions

Please do not send single link without further explanations, this help nobody

now the link you sent, yeah mention the permissions etc. but end up with “it works for your app, does not work for my app” so can be quite confusing for someone who never dealt with permissions

Hi Michele and welcome to the forum

OK that’s normal

In the AIR application sandbox, the application can access any camera without the user’s permission. On Android, however, the application must specify the Android CAMERA permission in the application descriptor.

so yeah on desktop the user permissions are not checked
but once you get to test on Android there the user permissions are checked which create that blank screen

so first, if before you needed to define camera permissions in your AIR app xml
see ANDROID, AIR AND THE CAMERA from Michael Chaize

you would do something like that

<android>
        <manifestAdditions>
            <manifest>
                <data>
                <![CDATA[
                <uses-permission android:name="android.permission.CAMERA" />
                <uses-feature android:name="android.hardware.camera.autofocus"/>
                ]]>
                </data>
            </manifest>
        </manifestAdditions>
</android>

but the way permissions are handled by Android changed

see Adobe AIR 24 Release Notes

PERMISSIONS ON ANDROID AND IOS

Beginning with Android 6.0 (API level 23), the users now need to grant permissions to apps while it is running, not when they install the application. To handle the permissions requests and status, we have introduced Permissions API for Android and iOS. The developers can request permissions for classes like Camera, Microphone, Geolocation, CameraRoll, CameraUI, File, and FileReference. The applications must be packaged with AIRSDK 24 or greater and must have SWF version 35 or later. Apps built using these APIs throw a dialog only on Android 6.0 and later. For Android 5.0 or earlier, you can continue to mention permissions in the application descriptor file.

and if you continue to read, you get the following example

On Android, If you do not want to handle permissions in your application, use targetSdkVersion less than 23 in your application descriptor file.

  1. permissionStatus: This property informs whether the application has been granted the required permission or not. This property always returns the status as GRANTED on AIR desktop and Android apps that have targetSDKVersion less than 23. The list of properties for PermissionStatus class includes UNKNOWN, GRANTED, and DENIED. The property UNKNOWN specifies that the permission hasn’t been requested yet or the permission has been denied by user with check box option ‘Don’t ask again.’.

  2. requestPermission(): The method requestPermission requests for the permission to be granted to the application. A PermissionEvent is dispatched when the user grants or denies a permission.

  3. PermissionError: Accessing properties and methods of such ActionScript classes without requesting for permission throws Error #3800 PermissionError .

package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.PermissionEvent;
    import flash.media.Camera;
    import flash.media.Video;
    import flash.permissions.PermissionStatus;
      
    public class codeSnippet extends Sprite
    {
        private var video:Video;
        private var cam:Camera;
        public function codeSnippet()
        {
            super();
              
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
              
            if (Camera.isSupported)
            {
                cam = Camera.getCamera();
                  
                if (Camera.permissionStatus != PermissionStatus.GRANTED)
                {
                    cam.addEventListener(PermissionEvent.PERMISSION_STATUS, function(e:PermissionEvent):void {

                        if (e.status == PermissionStatus.GRANTED)
                        {
                            connectCamera();
                        }
                        else
                        {
                            // permission denied
                        }
                    });
                      
                    try {
                        cam.requestPermission();
                    } catch(e:Error)
                    {
                        // another request is in progress
                    }
                }
                else
                {
                    connectCamera();
                }
            }
        }
          
        private function connectCamera():void
        {
            video = new Video(640, 480);
            video.attachCamera(cam);
            addChild(video);
        }
    }
}

For training resource on Android permissions, see https://developer.android.com/training/permissions/index.html.

For information about iOS permissions, see Apple’s documentation https://developer.apple.com/ios/human-interface-guidelines/interaction/requesting-permission/.

POINTS TO NOTE

  • A new feature for iOS 10 submissions requires you to add the ‘purpose string’ to your app when accessing a user’s private data such as Camera or Photos. For information about providing keys in your app descriptor file, see Information Property List Key Reference | Cocoa Keys.

  • While requesting for multiple permissions simultaneously, runtime throws the error below:
    Error #3801: Another permission request is in progress.

  • Accessing the File class without requesting for permissions throws Error #3012, which is the old behavior of File API.

so what is confusing is that it is very similar of what is described in the documentation here
ActionScript 3.0 Developer’s Guide / Rich Media Content / Working with cameras

but IT IS DIFFERENT

old example (Working with cameras) use StatusEvent.STATUS

cam.addEventListener(StatusEvent.STATUS, statusHandler);

the permissions are managed in the app descriptor XML


while the new example (release notes) use PermissionEvent.PERMISSION_STATUS

cam.addEventListener( PermissionEvent.PERMISSION_STATUS, function(e:PermissionEvent):void {

    if (e.status == PermissionStatus.GRANTED)
    {
        connectCamera();
    }
    else
    {
        // permission denied
    }
} );

the permissions are managed dynamically


If you did camera permissions before, just forget about how it was done and follow the logic of the AIR 24 Release Notes

1 Like