Repository: flex-examples Updated Branches: refs/heads/develop 5b135032a -> 8ff391f78
Add Camera and CameraUI views. A few bugs remain, so disabling them for now. Project: http://git-wip-us.apache.org/repos/asf/flex-examples/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-examples/commit/75ce7aaf Tree: http://git-wip-us.apache.org/repos/asf/flex-examples/tree/75ce7aaf Diff: http://git-wip-us.apache.org/repos/asf/flex-examples/diff/75ce7aaf Branch: refs/heads/develop Commit: 75ce7aaf69aa8dd695d4b608eaa6df860fda6cfe Parents: 5b13503 Author: OmPrakash Muppirala <bigosma...@gmail.com> Authored: Fri Apr 10 23:41:09 2015 -0700 Committer: OmPrakash Muppirala <bigosma...@gmail.com> Committed: Fri Apr 10 23:41:09 2015 -0700 ---------------------------------------------------------------------- tourdeflexmobile/.actionScriptProperties | 11 +- tourdeflexmobile/src/AIRViews/CameraUIView.mxml | 114 +++++++++++++++++++ tourdeflexmobile/src/AIRViews/CameraView.mxml | 103 ++++++++++++----- tourdeflexmobile/src/TourDeFlexMobile-app.xml | 6 +- tourdeflexmobile/src/styles.css | 8 +- tourdeflexmobile/src/views/HttpServiceView.mxml | 2 +- 6 files changed, 200 insertions(+), 44 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-examples/blob/75ce7aaf/tourdeflexmobile/.actionScriptProperties ---------------------------------------------------------------------- diff --git a/tourdeflexmobile/.actionScriptProperties b/tourdeflexmobile/.actionScriptProperties index b09f3db..2d6ed1e 100644 --- a/tourdeflexmobile/.actionScriptProperties +++ b/tourdeflexmobile/.actionScriptProperties @@ -21,15 +21,12 @@ <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/spark_dmv.swc" useDefaultLinkType="false"/> <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/> <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/> - <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/air/airframework.swc" useDefaultLinkType="false"/> - <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/air/applicationupdater_ui.swc" useDefaultLinkType="false"/> <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_flashflexkit.swc" useDefaultLinkType="false"/> + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/air/applicationupdater_ui.swc" useDefaultLinkType="false"/> + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/air/airframework.swc" useDefaultLinkType="false"/> <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_agent.swc" useDefaultLinkType="false"/> </excludedEntries> </libraryPathEntry> - <libraryPathEntry kind="3" linkType="1" path="/spark/bin/spark.swc" useDefaultLinkType="false"/> - <libraryPathEntry kind="3" linkType="1" path="/mobiletheme/bin/mobiletheme.swc" useDefaultLinkType="false"/> - <libraryPathEntry kind="3" linkType="1" path="/mobilecomponents/bin/mobilecomponents.swc" useDefaultLinkType="false"/> </libraryPath> <sourceAttachmentPath/> </compiler> @@ -43,9 +40,9 @@ <buildCSSFiles/> <flashCatalyst validateFlashCatalystCompatibility="false"/> <buildTargets> - <buildTarget buildTargetName="device" iosSettingsVersion="2" isCurrent="true" platformId="com.adobe.flexide.multiplatform.ios.platform" provisioningFile="" releasePackageType=""> + <buildTarget buildTargetName="device" iosSettingsVersion="2" isCurrent="true" platformId="com.adobe.flexide.multiplatform.ios.platform" provisioningFile="C:/p/documents/certificates/ios/2014/AllMyApps.mobileprovision" releasePackageType=""> <multiPlatformSettings enabled="true" hideAneLibSymbols="0" includePlatformLibs="false" platformID="com.adobe.flexide.multiplatform.ios.platform" reducedSizePackaging="false" version="1"/> - <airSettings airCertificatePath="" airTimestamp="true" anePathSet="false" version="1"> + <airSettings airCertificatePath="C:/p/documents/certificates/ios/2014/ios_development.p12" airTimestamp="true" anePathSet="true" version="1"> <airExcludes/> <anePaths/> <newLaunchParams/> http://git-wip-us.apache.org/repos/asf/flex-examples/blob/75ce7aaf/tourdeflexmobile/src/AIRViews/CameraUIView.mxml ---------------------------------------------------------------------- diff --git a/tourdeflexmobile/src/AIRViews/CameraUIView.mxml b/tourdeflexmobile/src/AIRViews/CameraUIView.mxml new file mode 100644 index 0000000..bb17eeb --- /dev/null +++ b/tourdeflexmobile/src/AIRViews/CameraUIView.mxml @@ -0,0 +1,114 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +--> +<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:s="library://ns.adobe.com/flex/spark" + title="CameraUI" > + + <fx:Script> + <![CDATA[ + + import spark.events.ViewNavigatorEvent; + + private var cameraUI:CameraUI; + private var mpLoader:Loader; + + protected function launchCameraUI(event:MouseEvent):void + { + if( CameraUI.isSupported ) + { + cameraUI= new CameraUI(); + cameraUI.addEventListener(MediaEvent.COMPLETE, onCameraUIComplete); + /*cameraUI.addEventListener(Event.CANCEL, onCameraUICanceled);*/ + cameraUI.addEventListener(ErrorEvent.ERROR, onCameraError); + cameraUI.launch(MediaType.IMAGE); + } + else + { + trace( "Camera interface is not supported."); + } + } + + private function onCameraUIComplete(e:MediaEvent):void + { + /*cameraUI.removeEventListener(MediaEvent.COMPLETE, onCameraUIComplete); + cameraUI.removeEventListener(Event.CANCEL, onCameraUICanceled); + cameraUI.removeEventListener(ErrorEvent.ERROR, onCameraError);*/ + + var mediaPromise:MediaPromise = e.data; + + this.mpLoader = new Loader(); + this.mpLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onMediaPromiseLoaded); + /*this.mpLoader.addEventListener(IOErrorEvent.IO_ERROR, onMediaPromiseLoadError);*/ + this.mpLoader.loadFilePromise(mediaPromise); + } + + private function onMediaPromiseLoaded(e:Event):void + { + var mpLoaderInfo:LoaderInfo = e.target as LoaderInfo; + mpLoaderInfo.removeEventListener(Event.COMPLETE, onMediaPromiseLoaded); + /* mpLoaderInfo.loader.removeEventListener(IOErrorEvent.IO_ERROR, onMediaPromiseLoadError);*/ + this.image.source = mpLoaderInfo.loader; + } + + + protected function onCameraError(event:ErrorEvent):void + { + trace(); + } + + protected function buttonHandler(event:MouseEvent):void + { + if(currentState == "DemoState") + { + currentState = "InfoState"; + } + else if(currentState == "InfoState") + { + currentState = "DemoState"; + } + } + ]]> + </fx:Script> + + <s:states> + <s:State name="DemoState"/> + <s:State name="InfoState"/> + </s:states> + <fx:Declarations> + <s:MultiDPIBitmapSource id="aboutIcon" source160dpi="@Embed('assets/icons/160/about.png')" source240dpi="@Embed('assets/icons/240/about.png')" + source320dpi="@Embed('assets/icons/320/about.png')" source480dpi="assets/icons/480/about.png"/> + <s:MultiDPIBitmapSource id="demoIcon" source160dpi="@Embed('assets/icons/160/dock.png')" source240dpi="@Embed('assets/icons/240/dock.png')" + source320dpi="@Embed('assets/icons/320/dock.png')" source480dpi="assets/icons/480/dock.png"/> + </fx:Declarations> + <s:VGroup width="100%" height="100%" includeIn="DemoState" horizontalAlign="center"> + <s:Button label="Launch Camera UI" click="launchCameraUI(event)" /> + <s:Image id="image" width="100%" height="100%" scaleMode="letterbox" /> + </s:VGroup> + <s:TextArea includeIn="InfoState" selectable="false" left="10" right="10" top="10" bottom="10" editable="false" text="The CameraUI class allows you to capture a still image or video using the default camera application on a device. + 
 
The launch() method requests that the device open the default camera application. The captured image or video is available in the MediaEvent object dispatched for the complete event. Since the default camera application can save the image or video in a variety of formats, there is no guarantee that returned media object can be loaded and displayed by the AIR runtime. + 
 
On some platforms, the media object returned by the camera is accessible as a file-based media promise. On others, the media promise is not file-based and the file and relativePath properties of the MediaPromise object are null. Do not use these properties in code that is used on more than one platform. + 
 
On Android, the default camera application does not open if the external storage card is not available (such as when the user has mounted the card as a USB mass storage device). In addition, the AIR application that launches the camera loses focus. If the device runs low on resources, the AIR application can be terminated by the operating system before the media capture is complete. + 
 
On some platforms, the media object is automatically stored in the device media library. On platforms on which images and video are not automatically stored by the default camera application, you can use the CameraRoll addBitmapData() function to store the media object."/> + + <s:actionContent> + <s:Button click="buttonHandler(event)" icon.DemoState="{aboutIcon}" icon.InfoState="{demoIcon}"/> + </s:actionContent> + +</s:View> http://git-wip-us.apache.org/repos/asf/flex-examples/blob/75ce7aaf/tourdeflexmobile/src/AIRViews/CameraView.mxml ---------------------------------------------------------------------- diff --git a/tourdeflexmobile/src/AIRViews/CameraView.mxml b/tourdeflexmobile/src/AIRViews/CameraView.mxml index a1e26f5..2e75483 100644 --- a/tourdeflexmobile/src/AIRViews/CameraView.mxml +++ b/tourdeflexmobile/src/AIRViews/CameraView.mxml @@ -20,42 +20,77 @@ limitations under the License. <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" - title="Camera" - viewDeactivate="deactivate(event)" - viewActivate="init(event)"> - + title="Camera" + viewActivate="init(event)" + viewDeactivate="deactivate(event)" + > <fx:Script> <![CDATA[ - import mx.core.UIComponent; + import spark.events.IndexChangeEvent; import spark.events.ViewNavigatorEvent; private var camera:Camera; + private var videoHolder:UIComponent; + private var video:Video; private function init(event:ViewNavigatorEvent):void - { + { + stage.addEventListener(StageOrientationEvent.ORIENTATION_CHANGE, handleOrientationChangeComplete); + stage.setOrientation(StageOrientation.ROTATED_RIGHT); + } + + private function deactivate(event:ViewNavigatorEvent):void + { + stage.setOrientation(StageOrientation.DEFAULT); + } + + private function handleOrientationChangeComplete(event:StageOrientationEvent):void + { + buttonBar.enabled = Camera.isSupported; if(Camera.isSupported) - { - camera = Camera.getCamera(); - camera.addEventListener(ActivityEvent.ACTIVITY, activityHandler); - camera.setMode(640, 480, 25); - camera.setQuality(0, 100); - var video:Video = new Video(width,height) - video.attachCamera(camera); - var videoHolder:UIComponent = new UIComponent(); + { + videoHolder = new UIComponent(); videoHolder.x = 0; - videoHolder.y = 0; - videoHolder.percentWidth = 100; - videoHolder.percentHeight = 100; - videoHolder.addChild(video); - videoDisplay.addElement(videoHolder); + videoHolder.y = 0; + videoHolder.width = height; + videoHolder.height = width; + video = new Video(height,width) + videoHolder.addChildAt(video,0); + videoDisplay.addElementAt(videoHolder,0); + getCamera(); + } + } + + protected function onButtonBar_ChangeHandler(event:IndexChangeEvent):void + { + getCamera(); + } + + private function getCamera():void + { + var names:Array = Camera.names; + var i:int = -1; + var n:int = names.length; + + while(++i<n) + { + var cam:Camera = Camera.getCamera( names[i] as String); + if(cam && cam.position == buttonBar.selectedItem.label) + { + attachCamera(cam); + return; + } } + attachCamera(Camera.getCamera()); } - private function activityHandler(event:ActivityEvent):void + private function attachCamera(camera:Camera):void { - trace("activityHandler: " + event); + camera.setMode(height,width, 30,true); + camera.setMotionLevel(0); + video.attachCamera(camera); } protected function buttonHandler(event:MouseEvent):void @@ -70,12 +105,6 @@ limitations under the License. } } - private function deactivate(event:ViewNavigatorEvent):void - { - camera.removeEventListener(ActivityEvent.ACTIVITY, activityHandler); - } - - ]]> </fx:Script> @@ -88,7 +117,11 @@ limitations under the License. <s:MultiDPIBitmapSource id="aboutIcon" source160dpi="@Embed('assets/icons/160/about.png')" source240dpi="@Embed('assets/icons/240/about.png')" source320dpi="@Embed('assets/icons/320/about.png')"/> <s:MultiDPIBitmapSource id="demoIcon" source160dpi="@Embed('assets/icons/160/dock.png')" source240dpi="@Embed('assets/icons/240/dock.png')" source320dpi="@Embed('assets/icons/320/dock.png')"/> </fx:Declarations> - <s:Group width="100%" height="100%" id="videoDisplay"/> + <s:layout> + <s:VerticalLayout horizontalAlign="center" /> + </s:layout> + + <s:Group width="100%" height="100%" id="videoDisplay" includeIn="DemoState"/> <s:TextArea includeIn="InfoState" selectable="false" left="10" right="10" top="10" bottom="10" editable="false" text="Use the Camera class to capture video from the client system or device camera. Use the Video class to monitor the video locally. Use the NetConnection and NetStream classes to transmit the video to Flash Media Server. Flash Media Server can send the video stream to other servers and broadcast it to other clients running Flash Player or AIR. @@ -99,8 +132,20 @@ limitations under the License. 
 
On mobile devices with an autofocus camera, autofocus is enabled automatically. If the camera does not support continuous autofocus, and many mobile device cameras do not, then the camera is focused when the Camera object is attached to a video stream and whenever the setMode() method is called. On desktop computers, autofocus behavior is dependent on the camera driver and settings. 
 
In an AIR application on Android and iOS, the camera does not capture video while an AIR app is not the active, foreground application. In addition, streaming connections can be lost when the application is in the background. On iOS, the camera video cannot be displayed when an application uses the GPU rendering mode. The camera video can still be streamed to a server."/> - + + <s:actionLayout> + <s:HorizontalLayout gap="10" /> + </s:actionLayout> <s:actionContent> + <s:ButtonBar id="buttonBar" requireSelection="true" + change="onButtonBar_ChangeHandler(event)"> + <s:dataProvider> + <s:ArrayList> + <fx:Object label="{CameraPosition.FRONT}"/> + <fx:Object label="{CameraPosition.BACK}"/> + </s:ArrayList> + </s:dataProvider> + </s:ButtonBar> <s:Button click="buttonHandler(event)" icon.DemoState="{aboutIcon}" icon.InfoState="{demoIcon}"/> </s:actionContent> </s:View> http://git-wip-us.apache.org/repos/asf/flex-examples/blob/75ce7aaf/tourdeflexmobile/src/TourDeFlexMobile-app.xml ---------------------------------------------------------------------- diff --git a/tourdeflexmobile/src/TourDeFlexMobile-app.xml b/tourdeflexmobile/src/TourDeFlexMobile-app.xml index 506b9af..5d50469 100644 --- a/tourdeflexmobile/src/TourDeFlexMobile-app.xml +++ b/tourdeflexmobile/src/TourDeFlexMobile-app.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="no"?> -<application xmlns="http://ns.adobe.com/air/application/16.0"> +<application xmlns="http://ns.adobe.com/air/application/17.0"> <!-- Adobe AIR Application Descriptor File Template. @@ -15,7 +15,7 @@ <!-- A universally unique application identifier. Must be unique across all AIR applications. Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. --> - <id>org.apache.flex.tourdeflex.mobile</id> + <id>com.bigosmallm.flex.tourdeflex.mobile</id> <!-- Used as the filename for the application. Required. --> <filename>TourDeFlexMobile</filename> @@ -111,7 +111,7 @@ <!-- Display Resolution for the app (either "standard" or "high"). Optional, OSX-only. Default "standard" --> <!-- <requestedDisplayResolution></requestedDisplayResolution> --> - <autoOrients>true</autoOrients> + <autoOrients>false</autoOrients> <fullScreen>false</fullScreen> <visible>true</visible> <softKeyboardBehavior>none</softKeyboardBehavior> http://git-wip-us.apache.org/repos/asf/flex-examples/blob/75ce7aaf/tourdeflexmobile/src/styles.css ---------------------------------------------------------------------- diff --git a/tourdeflexmobile/src/styles.css b/tourdeflexmobile/src/styles.css index 246be2b..0a32248 100644 --- a/tourdeflexmobile/src/styles.css +++ b/tourdeflexmobile/src/styles.css @@ -3,15 +3,15 @@ @namespace supportClasses "spark.components.supportClasses.*"; @namespace ns "http://flex.apache.org/experimental/ns"; -global +/*global { fontFamily: RobotoRegular; fontSize: 24; color: #000000; -} +}*/ -TextArea +/*TextArea { skinClass: ClassReference("spark.skins.android4.TextAreaSkin"); contentBackgroundAlpha: 0; @@ -22,7 +22,7 @@ TextArea selectionHighlighting: "never"; focusEnabled:"false"; focusThickness: 0; -} +}*/ ns|MobileGrid { http://git-wip-us.apache.org/repos/asf/flex-examples/blob/75ce7aaf/tourdeflexmobile/src/views/HttpServiceView.mxml ---------------------------------------------------------------------- diff --git a/tourdeflexmobile/src/views/HttpServiceView.mxml b/tourdeflexmobile/src/views/HttpServiceView.mxml index a63f871..8d91f53 100644 --- a/tourdeflexmobile/src/views/HttpServiceView.mxml +++ b/tourdeflexmobile/src/views/HttpServiceView.mxml @@ -74,7 +74,7 @@ limitations under the License. <s:Button label="Load" y="10" includeIn="DemoState" width="60" height="40" right="5" click="loadRSS()"/> <s:List id="itemsList" labelField="title" includeIn="DemoState" width="100%" bottom="0" top="60"/> - <s:BusyIndicator id="busyIndicator" verticalCenter="0" horizontalCenter="0" width="20" height="20" visible="false"/> + <s:BusyIndicator id="busyIndicator" verticalCenter="0" horizontalCenter="0" visible="false"/> <s:TextArea includeIn="InfoState" left="10" right="10" top="10" bottom="10" editable="false" selectable="false" text="You use the HTTPService tag to represent an HTTPService object in an MXML file. When you call the HTTPService object's send() method, it makes an HTTP request to the specified URL, and an HTTP response is returned. Optionally, you can pass parameters to the specified URL. When you do not go through the server-based proxy service, you can use only HTTP GET or POST methods. However, when you set the useProxy property to true and you use the server-based proxy service, you can also use the HTTP HEAD, OPTIONS, TRACE, and DELETE methods. 
 
Note: Due to a software limitation, HTTPService does not generate user-friendly error messages when using GET."/>