I am trying to implement a BroadcastReceiver but it is not working. I want to use it to return progress from a class that implements network io, which is called from an AsyncTask inside my Activity.
Here is the code for my activity:
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);
}
}
}
This is supposed to display a list, then overlay this with a progress dialog while the data for the list is returned from a server. And this works OK. I would like to update the text in the progress dialog as the network io is done. This is the code that implements the network io:
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
}
}
In the Android manifest file I've added the following:
<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>
I get the log print "message sent" But not the log print "I've received something"
I am an Android newbie so I assume I've not implemented something correctly. Any ideas?
Original post updated with intent-filter and set of action when creating the intent. Still not working.
Your <receiver>
tag needs to contain an <intent-filter>
to tell Android which broadcast intents you actually want to receive.
EDIT:
An Intent
is not much more than a container for a message; it's the function that you call to send the Intent
that determines which fields you need to set.
From the docs for Intent
:
[
Intent
] can be used withstartActivity
to launch anActivity
,broadcastIntent
to send it to any interestedBroadcastReceiver
components, andstartService(Intent)
orbindService(Intent, ServiceConnection, int)
to communicate with a backgroundService
.
Those functions are your options for sending Intent
s. startActivity
and the startService
/bindService
functions use explicit Intent
s; sendBroadcast
does not.
Notice that startActivity
throws an exception if it can't find your Intent
's target class, and startService
will return null
if it can't find your target class. sendBroadcast
doesn't do anything like that because it doesn't even look at that field. sendBroadcast
"Broadcasts the given intent to all interested BroadcastReceivers."
Since you are using Context.sendBroadcast()
to send your intent, you should be setting an action on your Intent
and your BroadcastReceiver
should have an intent filter containing an entry for that action.
Ok It seems like the answer is that its not possible to use the manifest to register the receiver. If I change the code so that it uses registerReceiver then it works ok. Code updated like this:
@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!";
}
And remove anything to do with the receiver from the manifest.
Note: the code that sends the Broadcast is like this:
Intent intent = new Intent();
intent.setAction("PROGRESS");
mContext.sendBroadcast(intent);
精彩评论