モバイルアプリケーションでの HTML コンテンツの表示

Adobe AIR 2.5 以降

StageWebView クラスは、モバイルデバイスではシステムのブラウザーコントロールを、デスクトップコンピューターでは標準の Adobe® AIR® HTMLLoader コントロールを使用して HTML コンテンツを表示します。このクラスが現在のデバイスでサポートされているかどうかを判断するには、 StageWebView.isSupported プロパティを確認してください。モバイルプロファイル内のすべてのデバイスでサポートされているとは限りません。

すべてのプロファイルにおいて、StageWebView クラスがサポートする HTML コンテンツと他のアプリケーションとの間のやり取りは限定されています。ナビゲーションの制御は可能ですが、データのクロススクリプト(直接交換)は許可されていません。ローカルまたはリモートの URL からコンテンツを読み込んだり、HTML のストリングを渡したりすることができます。

以下の参照をお勧めします。

AIR2.5 StageWebView demo – OAuth Support

Mark Doherty
エバンジェリストの Mark Doherty が、OAuth で保護された Twitter などのサイトに StageWebView クラスを使用してログインする方法を説明します。

StageWebView オブジェクト

StageWebView オブジェクトは表示オブジェクトではないので、表示リストに追加することはできません。代わりに、ステージに直接関連付けられたビューポートとして機能します。StageWebView コンテンツは、表示リストのコンテンツの上に描画されます。複数の StageWebView オブジェクトの描画順序を制御する方法はありません。

StageWebView オブジェクトを表示するには、StageWebView の stage プロパティに、オブジェクトを表示するステージを割り当てます。 viewPort プロパティを使用して表示サイズを設定します。

viewPort プロパティの x 座標と y 座標には -8192~8191 を設定します。ステージの幅と高さの最大値は 8191 です。サイズがこの最大値を上回ると、例外がスローされます。

次の例では、StageWebView オブジェクトを作成し、 stage プロパティと viewPort プロパティを設定して、HTML のストリングを表示します。

var webView:StageWebView = new StageWebView(); 
webView.viewPort = new Rectangle( 0, 0, this.stage.stageWidth, this .stage.stageHeight); 
webView.stage = this.stage; 
var htmlString:String = "<!DOCTYPE HTML>" + 
                        "<html><body>" + 
                        "<p>King Philip could order five good steaks.</p>" + 
                        "</body></html>"; 
webView.loadString( htmlString );

StageWebView オブジェクトを非表示にするには、その stage プロパティを null に設定します。オブジェクトを完全に破棄するには、 dispose() メソッドを呼び出します。 dispose() の呼び出しはオプションですが、このメソッドを呼び出すと、オブジェクトですぐに使用するメモリをガベージコレクターで再生できます。

コンテンツ

loadURL() および loadString() という 2 つのメソッドを使用して、StageWebView オブジェクトにコンテンツを読み込むことができます。

loadURL() メソッドは、指定された URL にあるリソースを読み込みます。システムの Web ブラウザーコントロールでサポートされている任意の URI スキーム(data:、file:、http:、https:、javascript: など)を使用できます。app: スキームと app-storage: スキームはサポートされていません。AIR では、URL ストリングの検証は行われません。

loadString() メソッドは、HTML コンテンツを含むリテラルストリングを読み込みます。このメソッドにより読み込まれるページの場所は、次のように表されます。
  • デスクトップ上:about:blank

  • iOS 上: htmlString

  • Android 上:エンコードされた htmlString のデータ URI 形式

URI スキームでは、埋め込まれたコンテンツまたはデータを読み込むルールを決定します。

URI スキーム

ローカルリソースの読み込み

リモートリソースの読み込み

ローカル XMLHttpRequest

リモート XMLHttpRequest

data:

不可

不可

不可

file:

http:、https:

不可

不可

同じドメイン

about:(loadString() メソッド)

不可

不可

不可

注意: ステージの displayState プロパティが FULL_SCREEN に設定されている場合、StageWebView に表示されるテキストフィールドに入力することはできません。ただし、iOS と Android では、ステージの displayState FULL_SCREEN の場合でも StageWebView のテキストフィールドに入力できます。

次の例では、StageWebView オブジェクトを使用して Adobe の Web サイトを表示します。

package  { 
    import flash.display.MovieClip; 
    import flash.media.StageWebView; 
    import flash.geom.Rectangle; 
     
    public class StageWebViewExample extends MovieClip{ 
 
        var webView:StageWebView = new StageWebView(); 
         
        public function StageWebViewExample() { 
            webView.stage = this.stage; 
            webView.viewPort = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight ); 
            webView.loadURL( "http://www.adobe.com" ); 
        } 
    } 
}

Android デバイスのアプリケーションでリモートリソースを正常に読み込むには、Android の INTERNET 権限を指定する必要があります。

Android 3.0 以降では、アプリケーションはAIR アプリケーション記述子の Android manifestAdditions エレメントでハードウェアアクセラレーションを有効にして、StageWebView オブジェクト内のプラグインコンテンツを表示する必要があります。「 StageWebView オブジェクトでの Flash Player およびその他のプラグインの有効化 」を参照してください。

JavaScript URI

JavaScript URI を使用して、StageWebView オブジェクトが読み込んだ HTML ページに定義されている関数を呼び出すことができます。JavaScript URI を使用して呼び出す関数は、読み込まれた Web ページのコンテキストで実行されます。次の例では、StageWebView オブジェクトを使用して JavaScript 関数を呼び出します。

package { 
    import flash.display.*; 
    import flash.geom.Rectangle; 
    import flash.media.StageWebView; 
    public class WebView extends Sprite 
    { 
        public var webView:StageWebView = new StageWebView(); 
        public function WebView() 
        {     
            var htmlString:String = "<!DOCTYPE HTML>" + 
            "<html><script type=text/javascript>" + 
            "function callURI(){" + 
            "alert(\"You clicked me!!\");"+ 
            "}</script><body>" + 
            "<p><a href=javascript:callURI()>Click Me</a></p>" + 
            "</body></html>"; 
            webView.stage = this.stage; 
            webView.viewPort = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight ); 
            webView.loadString( htmlString ); 
        } 
    } 
}

ナビゲーションイベント

ユーザーが HTML 内のリンクをクリックすると、StageWebView オブジェクトは locationChanging イベントを送出します。このイベントオブジェクトの preventDefault() メソッドを呼び出すと、ナビゲーションを停止することができます。それ以外の場合、StageWebView オブジェクトは新しいページに移動して locationChange イベントを送出します。ページの読み込みが完了すると、StageWebView は complete イベントを送出します。

HTML リダイレクトのたびに locationChanging イベントが送出されます。 locationChange イベントと complete イベントは適切なタイミングで送出されます。

iOS では、 locationChanging イベントは、最初の loadURL() メソッドまたは loadString() メソッドの場合を除き、 locationChange イベントの前に送出されます。また、 locationChange イベントは、iFrame およびフレームのナビゲーションを変更した場合にも送出されます。

次の例は、場所の変更を行わず、代わりにシステムのブラウザーで新しいページを開く方法を示しています。

package  { 
    import flash.display.MovieClip; 
    import flash.media.StageWebView; 
    import flash.events.LocationChangeEvent; 
    import flash.geom.Rectangle; 
    import flash.net.navigateToURL; 
    import flash.net.URLRequest; 
     
    public class StageWebViewNavEvents extends MovieClip{ 
        var webView:StageWebView = new StageWebView(); 
         
        public function StageWebViewNavEvents() { 
            webView.stage = this.stage; 
            webView.viewPort = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight ); 
        webView.addEventListener( LocationChangeEvent.LOCATION_CHANGING, onLocationChanging ); 
            webView.loadURL( "http://www.adobe.com" ); 
        } 
        private function onLocationChanging( event:LocationChangeEvent ):void 
        { 
            event.preventDefault(); 
            navigateToURL( new URLRequest( event.location ) ); 
        } 
    } 
}

ヒストリー

ユーザーが StageWebView オブジェクトに表示されているコンテンツ内のリンクをクリックすると、このコントロールは後方と前方の履歴スタックを保存します。次の例は、2 つの履歴スタック間を移動する方法を示しています。この例では、「Back」および「Search」というソフトキーを使用します。

package  { 
    import flash.display.MovieClip; 
    import flash.media.StageWebView; 
    import flash.geom.Rectangle; 
    import flash.events.KeyboardEvent; 
    import flash.ui.Keyboard; 
     
    public class StageWebViewExample extends MovieClip{ 
 
        var webView:StageWebView = new StageWebView(); 
         
        public function StageWebViewExample() 
        { 
            webView.stage = this.stage; 
            webView.viewPort = new Rectangle( 0, 0, stage.stageWidth, stage.stageHeight ); 
            webView.loadURL( "http://www.adobe.com" ); 
             
            stage.addEventListener( KeyboardEvent.KEY_DOWN, onKey ); 
        } 
         
        private function onKey( event:KeyboardEvent ):void 
        { 
            if( event.keyCode == Keyboard.BACK && webView.isHistoryBackEnabled ) 
            { 
                trace("back"); 
                webView.historyBack(); 
                event.preventDefault(); 
            } 
            if( event.keyCode == Keyboard.SEARCH && webView.isHistoryForwardEnabled ) 
            { 
                trace("forward"); 
                webView.historyForward(); 
            } 
        } 
    } 
}

フォーカス

StageWebView クラスが表示オブジェクトではない場合でも、このクラスには、コントロールに対するフォーカスの切り替えの管理を可能にするメンバーが含まれています。

StageWebView オブジェクトは、フォーカスを取得すると focusIn イベントを送出します。必要に応じて、このイベントを使用してアプリケーション内のフォーカスエレメントを管理します。

StageWebView は、フォーカスを放棄すると focusOut イベントを送出します。StageWebView インスタンスは、ユーザーがデバイスのトラックボールや矢印キーを使用して Web ページ上の先頭または末尾のタブコントロールに移動したときにフォーカスを放棄できます。このイベントオブジェクトの direction プロパティを確認すると、フォーカスのフローがページの下から上なのか上から下なのかを把握することができます。StageWebView の上または下にある適切な表示オブジェクトにフォーカスを割り当てるには、この情報を使用します。

iOS では、フォーカスをプログラムから設定することはできません。StageWebView が focusIn イベントと focusOut イベントを、 FocusEvent の direction プロパティに none を設定して送出します。ユーザーが StageWebView の内部をタッチすると、 focusIn イベントが送出されます。ユーザーが StageWebView の外部をタッチすると、 focusOut イベントが送出されます。

次の例は、StageWebView オブジェクトから Flash 表示オブジェクトにフォーカスを渡す方法を示しています。

package  { 
    import flash.display.MovieClip; 
    import flash.media.StageWebView; 
    import flash.geom.Rectangle; 
    import flash.events.KeyboardEvent; 
    import flash.ui.Keyboard; 
    import flash.text.TextField; 
    import flash.text.TextFieldType; 
    import flash.events.FocusEvent; 
    import flash.display.FocusDirection; 
    import flash.events.LocationChangeEvent; 
     
    public class StageWebViewFocusEvents extends MovieClip{ 
        var webView:StageWebView = new StageWebView(); 
        var topControl:TextField = new TextField(); 
        var bottomControl:TextField = new TextField(); 
         
        public function StageWebViewFocusEvents() 
        { 
            trace("Starting"); 
            topControl.type = TextFieldType.INPUT; 
            addChild( topControl ); 
            topControl.height = 60; 
            topControl.width = stage.stageWidth; 
            topControl.background = true; 
            topControl.text = "One control on top."; 
            topControl.addEventListener( FocusEvent.FOCUS_IN, flashFocusIn ); 
            topControl.addEventListener( FocusEvent.FOCUS_OUT, flashFocusOut ); 
             
            webView.stage = this.stage; 
            webView.viewPort = new Rectangle( 0, 60, stage.stageWidth, stage.stageHeight 
- 120 ); 
            webView.addEventListener( FocusEvent.FOCUS_IN, webFocusIn ); 
            webView.addEventListener(FocusEvent.FOCUS_OUT, webFocusOut ); 
            webView.addEventListener(LocationChangeEvent.LOCATION_CHANGING, 
                                     function( event:LocationChangeEvent ):void 
                                     { 
                                         event.preventDefault(); 
                                     } ); 
            webView.loadString("<form action='#'><input/><input/><input/></form>"); 
            webView.assignFocus(); 
             
            bottomControl.type = TextFieldType.INPUT; 
            addChild( bottomControl ); 
            bottomControl.y = stage.stageHeight - 60; 
            bottomControl.height = 60; 
            bottomControl.width = stage.stageWidth; 
            bottomControl.background = true; 
            bottomControl.text = "One control on the bottom.";             
            bottomControl.addEventListener( FocusEvent.FOCUS_IN, flashFocusIn ); 
            bottomControl.addEventListener( FocusEvent.FOCUS_OUT, flashFocusOut );        } 
         
        private function webFocusIn( event:FocusEvent ):void 
        { 
            trace("Web focus in"); 
        } 
         
        private function webFocusOut( event:FocusEvent ):void 
        { 
            trace("Web focus out: " + event.direction); 
            if( event.direction == FocusDirection.TOP ) 
            { 
                stage.focus = topControl; 
            } 
            else 
            { 
                stage.focus = bottomControl; 
            } 
        } 
 
        private function flashFocusIn( event:FocusEvent ):void 
        { 
            trace("Flash focus in"); 
            var textfield:TextField = event.target as TextField; 
            textfield.backgroundColor = 0xff5566; 
        } 
         
        private function flashFocusOut( event:FocusEvent ):void 
        { 
            trace("Flash focus out"); 
            var textfield:TextField = event.target as TextField; 
            textfield.backgroundColor = 0xffffff; 
        } 
         
    } 
}

ビットマップキャプチャ

StageWebView オブジェクトは、すべての表示リストコンテンツ上でレンダリングされます。StageWebView オブジェクト上にコンテンツを追加することはできません。例えば、StageWebView コンテンツにドロップダウンを拡張することはできません。この問題を解決するには、StageWebView のスナップショットをキャプチャします。その後、StageWebView を隠し、代わりにビットマップスナップショットを追加します。

次の例は、 drawViewPortToBitmapData メソッドを使用して StageWebView オブジェクトのスナップショットをキャプチャする方法を示しています。このメソッドは、ステージに null を設定することによって StageWebView オブジェクトを隠します。Web ページが完全に読み込まれた後に、ビットマップをキャプチャして表示する関数を呼び出します。実行時には、このコードにより Google と Facebook という 2 つのラベルが表示されます。ラベルをクリックすると対応する Web ページがキャプチャされ、これがスナップショットしてステージ上に表示されます。

package 
{ 
    import flash.display.Bitmap; 
    import flash.display.BitmapData; 
    import flash.display.Sprite; 
    import flash.events.*; 
    import flash.geom.Rectangle; 
    import flash.media.StageWebView; 
    import flash.net.*; 
    import flash.text.TextField; 
    public class stagewebview extends Sprite 
    { 
        public var webView:StageWebView=new StageWebView(); 
        public var textGoogle:TextField=new TextField(); 
        public var textFacebook:TextField=new TextField(); 
        public function stagewebview() 
        { 
            textGoogle.htmlText="<b>Google</b>"; 
            textGoogle.x=300; 
            textGoogle.y=-80;         
            addChild(textGoogle); 
            textFacebook.htmlText="<b>Facebook</b>"; 
            textFacebook.x=0; 
            textFacebook.y=-80; 
            addChild(textFacebook); 
            textGoogle.addEventListener(MouseEvent.CLICK,goGoogle); 
            textFacebook.addEventListener(MouseEvent.CLICK,goFaceBook); 
            webView.stage = this.stage; 
            webView.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight); 
        } 
    public function goGoogle(e:Event):void 
        { 
            webView.loadURL("http://www.google.com"); 
            webView.stage = null; 
            webView.addEventListener(Event.COMPLETE,handleLoad); 
        } 
     
    public function goFaceBook(e:Event):void 
        { 
            webView.loadURL("http://www.facebook.com"); 
            webView.stage = null; 
            webView.addEventListener(Event.COMPLETE,handleLoad); 
        } 
    public function handleLoad(e:Event):void 
        { 
            var bitmapData:BitmapData = new BitmapData(webView.viewPort.width, webView.viewPort.height); 
            webView.drawViewPortToBitmapData(bitmapData); 
            var webViewBitmap:Bitmap=new Bitmap(bitmapData); 
            addChild(webViewBitmap); 
        } 
    } 
}