如何在Android中实现BroadcastReceiver

时间:2011-10-11 15:50:36

标签: android broadcastreceiver

我正在尝试实现BroadcastReceiver,但它无法正常工作。 我想用它从实现网络io的类返回进度,这个类是从我的Activity中的AsyncTask调用的。

以下是我的活动代码:

package com.ClinicalInterface;

public class TestActivity extends ListActivity {

    static AsyncDataLoader mAsyncDataLoader;
    static ProgressDialog dialog;
    static ArrayList<String> list;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        dialog = new ProgressDialog(this);
        dialog.setMessage("Loading...");
        dialog.show();
        mAsyncDataLoader = new AsyncDataLoader();
        mAsyncDataLoader.execute();  
     }

    public class AsyncDataLoader extends AsyncTask<Void, Integer, String> {        

        public class mTestReceiver extends BroadcastReceiver {
            @Override 
            public void onReceive(Context context, Intent intent){
                System.out.println( "I've received something!" );
                publishProgress(2);
            }
        }

        @Override
        protected String doInBackground( Void ... params ) {            
            TestLoader tl = new TestLoader();
            tl.setContext(getApplicationContext());
            tl.setServeraddress("192.168.2.109");
            list = tl.doLST(null);
            return "COMPLETE!";
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            if (values[0] == 2) {
                dialog.setMessage("Loading data ...");
            }
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            dialog.dismiss();
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(TestActivity.this, R.layout.list_item, list);
            TestActivity.this.setListAdapter(adapter);                     
        }
    }         
}

这应该显示一个列表,然后使用进度对话框覆盖它,同时从服务器返回列表的数据。这个工作正常。 我想在网络完成后更新进度对话框中的文本。 这是实现网络的代码:

package com.ClinicalInterface;

public class TestLoader {
    private Context mContext;

    public void setContext(Context context) {
        mContext = context;
    }

     public ArrayList<String> doLST(String arg) {

         // Send intent to AsyncTask         
         Intent intent = new Intent(mContext, mTestReceiver.class);
         intent.setAction("PROGRESS");
         mContext.sendBroadcast(intent);
         System.out.println( "message sent" );

         // Code that actually does network io removed for brevity
    }
}

在Android清单文件中,我添加了以下内容:

<activity android:name="TestActivity" android:label="TestActivity">
    <receiver android:name=".AsyncDataLoader.mTestReceiver">
        <intent-filter>
            <action android:name="android.intent.action.PROGRESS" />
        </intent-filter>
    </receiver>
</activity>

我收到日志打印“发送的消息” 但不是日志打印“我收到了什么”

我是Android新手,所以我假设我没有正确实现。 有什么想法吗?

在创建意图时,使用intent-filter和操作集更新了原始帖子。仍然没有工作。

2 个答案:

答案 0 :(得分:2)

您的<receiver>代码需要包含<intent-filter>,以告知Android您实际想要接收的广播意图。

修改

Intent只不过是邮件的容器;它是您调用以发送Intent来确定您需要设置哪些字段的函数。

来自Intent的文档:

  

{Intent]可与startActivity一起发布,ActivitybroadcastIntent将其发送给任何感兴趣的BroadcastReceiver }组件,startService(Intent)bindService(Intent, ServiceConnection, int)与后台Service进行通信。

这些功能是您发送Intent的选项。 startActivitystartService / bindService函数使用显式Intent s; sendBroadcast没有。

请注意startActivity如果无法找到您的Intent目标类,则会引发异常,startService如果找不到您的null则会返回sendBroadcast目标类。 sendBroadcast没有做那样的事情,因为它甚至没有看那个字段。 Context.sendBroadcast()“将给定的意图广播给所有感兴趣的BroadcastReceivers。”

由于您使用Intent发送意图,因此您应该在BroadcastReceiver上设置操作,并且{{1}}应该有一个包含该操作条目的意图过滤器。< / p>

答案 1 :(得分:0)

好 似乎答案是它不可能使用清单来注册接收器。 如果我更改代码以便它使用registerReceiver,那么它可以正常工作。 代码更新如下:

@Override
protected String doInBackground( Void ... params ) {            
    TestLoader tl = new TestLoader();
    IntentFilter intentFilter = new IntentFilter("PROGRESS");
    mReceiver mmReceiver = new mReceiver();
    registerReceiver(mmReceiver, intentFilter);            
    tl.setContext(getApplicationContext());
    tl.setServeraddress("192.168.2.109");
    list = tl.doLST(null);
    unregisterReceiver(mmReceiver);
    return "COMPLETE!";
}

从清单中移除与接收器有关的任何内容。

注意:发送广播的代码如下:

 Intent intent = new Intent();
 intent.setAction("PROGRESS");
 mContext.sendBroadcast(intent);