如何在Flex Mobile App中使用BroadcastReceivers?

时间:2013-08-17 01:37:53

标签: flex android-intent flash-builder broadcastreceiver air-native-extension

我对Flex Mobile应用程序的工作方式不熟悉,因此请在回复中进行描述。

我正在尝试为Android创建一个能够从我创建的服务应用程序接收意图的Flex Mobile应用程序。意图附加了一个字符串,我的应用程序获取该信息非常重要。但是,我似乎无法弄清楚如何使我的Flex应用程序接收服务应用程序发送的意图。

到目前为止,我已经尝试让应用程序暂停在原生Android端3秒钟,希望能够有足够的时间调用onReceive()。这没用。

以下是我的代码。感谢您的帮助。

WiFi功能向服务发送意图以激活Android上的WiFi。

WiFi_info函数应该返回附加到此应用程序将接收的意图的数据。

ANESimpleApp.as - ActionScript库

package com.example.anesimpleapp
{
    import flash.external.ExtensionContext;

    public class ANESimpleApp
    {
        // This will hold the context for the Native Android side of the plugin
        private var context:ExtensionContext;

        // Get a context of the ANE
        public function ANESimpleApp()
        {
            // Checks if the context was already setup
            if(!context)
            {
                context = ExtensionContext.createExtensionContext("com.example.anesimpleapp", null);
            }
        }

        // Turn On/Off the Wifi
        public function WiFi(): void
        {
            context.call("WiFi", null);
        }

        // Get WiFi information
        public function WiFi_Info(): String
        {
            return String (context.call("WiFi_info", null));
        }
    }
}

WiFi_info.java - 原生Android代码

public class WiFi_info implements FREFunction {

    // This will retrieve information about the WiFi network the phone is currently connected to
    public String connectionData = "EMPTY";

    // This is used to reference the string value describing the WiFi network the phone is currently connected to.
    public final String KEY_WiFi_Info = "Update_WiFi_Info";

    // The expected intent
    public final String WiFi_Data = "com.example.Obtain_WiFi_Data";

    // Created a Runnable object
    Runnable myRun;


    @Override
    public FREObject call(FREContext context, FREObject[] object) {

        // The runnable object will be used to allow enough time for the BroadcastReceiver to set itself up
        myRun = new Runnable() {
            @Override
            public void run()
            {
                // Causes this activity to wait 3 second.
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };


        // Sets up intent filter and BroadcastReceiver

        // This intent filter will allow the application to receive certain intents
        IntentFilter filter = new IntentFilter();

        // This allows the application to receive data about the WiFi
        filter.addAction(WiFi_Data);

        // Registers the BroadcastReceiver onReceive() in this app
        context.getActivity().registerReceiver(mybroadcast, filter);


        // Generates a 3 second pause
        Thread myThread = new Thread(myRun);
        myThread.start();


        // Returns the information obtained from onReceive()

        // This will be used to hold the value returned from the function
        FREObject returnValue = null;

        try {
            // Obtains a string containing information about the WiFi network the phone is
            // currently connected to.
            returnValue = FREObject.newObject(connectionData);

        } catch (FREWrongThreadException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

            return null;
        }

       // Unregisters the BroadcastReceiver (Don't want any leaked receivers)
       context.getActivity().unregisterReceiver(mybroadcast);

       // Returns value
       return returnValue;
    }


     // Receives the intent and places extra in class variable
     public BroadcastReceiver mybroadcast = new BroadcastReceiver()
     {
         @Override
         public void onReceive(Context context, Intent intent)
         {
             if(intent.getAction().equalsIgnoreCase(WiFi_Data))
             {
                 connectionData = intent.getStringExtra(KEY_WiFi_Info);
             }
         }
    };
}

ANESimpleAppTestHomeView.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <fx:Script>
        <![CDATA[
            import com.example.anesimpleapp.ANESimpleApp;

            [Bindable(event="UpdateTime")]
            private function WifiUpdate(): String
            {
                var ane:ANESimpleApp = new ANESimpleApp();
                return ane.WiFi_info();
            }

            public function button1_WiFiActivation(event:MouseEvent):void
            {
                var ane:ANESimpleApp = new ANESimpleApp();
                ane.WiFi();
            }

            public function button2_WiFiUpdater(event:MouseEvent):void
            {
                dispatchEvent(new Event("UpdateTime"));
            }
        ]]>
    </fx:Script>
        <s:VGroup>
            <s:HGroup>
                <s:Button id="button1" 
                    x="25"
                    y="27" 
                    label="WiFi" 
                    click="button1_WiFiActivation(event)"/>

                <s:Button id="button2" 
                    x="25"
                    y="27" 
                    label="WiFi Info" 
                    click="button2_WiFiUpdater(event)"/>
            </s:HGroup>

            <s:TextArea id="WiFiInfo"
                width="65%" 
                editable="false" 
                borderVisible="false" 
                contentBackgroundColor="0xFFFFFF" 
                contentBackgroundAlpha="0" 
                height="400"
                text="{WifiUpdate()}"/>
    </s:VGroup>
</s:View>

1 个答案:

答案 0 :(得分:0)

我认为您的代码在3秒内无法正常暂停。看起来好像你正在启动另一个线程来做延迟,这意味着你的代码会在任何行动开始之前注册和取消注册接收器。

最好不要使用延迟,而是在实际的BroadcastReceiver onReceive函数中取消注册接收器。要做到这一点,您可能需要在扩展类 Extension.context 中存储对上下文的引用(尽管您可能已经这样做了)。

另外,我建议你将BroadcastReceiver分解为一个单独的类,以保持代码更清晰,你应该从比FREFunction更全局的地方引用它,例如在你的FREContext中。我将在这里写一些伪代码给你一个想法:

扩展:

public class ANEExtension implements FREContext 
{
    public static FREContext context;

    public FREContext createContext(String arg0) 
    {
        context = new ANEContext();
        return context;
    }

    // Other functions...
}

上下文:

public class ANEContext implements FREContext 
{
    public WifiReceiver receiver = null;

    public void registerWifiReceiver()
    {
        if (receiver == null)
        {
            receiver = new WifiReceiver();
            IntentFilter filter = new IntentFilter();
            filter.addAction("com.example.Obtain_WiFi_Data");
            getActivity().registerReceiver( receiver, filter );
        }
    }

    public void unregisterWifiReceiver()
    {
        if (receiver != null)
        {
            getActivity().unregisterReceiver( receiver );
            receiver = null;
        }
    }

    // .. Map<> getFunctions etc...
}

功能类:

public class WiFi_info implements FREFunction 
{
    @Override
    public FREObject call(FREContext context, FREObject[] object) 
    {
        ((ANEContext)context).registerWifiReceiver();

        // return stuff...
        return NULL;
    }
}

接收者类:

public class WifiReceiver extends BroadcastReceiver 
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        if(intent.getAction().equalsIgnoreCase(WiFi_Data))
        {
            connectionData = intent.getStringExtra(KEY_WiFi_Info);

            //
            // Return Data
            if (ANEExtension.context)
            {
                ANEExtension.context.dispatchStatusEventAsync( 
                    "some:event:type", 
                    connectionData 
                );
            }
            //
            //


            ((ANEContext)ANEExtension.context).unregisterWifiReceiver();
        }
    }
}

编辑:为动作脚本侧的状态事件添加侦听器

以下是所有AS3代码,总结了从本机代码接收状态事件的重要部分。

public class WifiExtension extends EventDispatcher
{
    public static const EXT_CONTEXT_ID : String = "the.extension.id";

    public function WifiExtension()
    {
        _extContext = ExtensionContext.createExtensionContext( EXT_CONTEXT_ID, null );
        _extContext.addEventListener( StatusEvent.STATUS, extension_statusHandler, false, 0, true ); 
    }

    private function extension_statusHandler( event:StatusEvent ):void
    {
        switch (event.code)
        {
            case "some:event:type":
                trace( "The data from the native code = " + event.level );

        }
    }

}