Как реализовать BroadcastReceiver в Android - PullRequest
0 голосов
/ 11 октября 2011

Я пытаюсь реализовать BroadcastReceiver, но он не работает. Я хочу использовать его для возврата прогресса из класса, реализующего сеть io, который вызывается из AsyncTask внутри моей 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);                     
        }
    }         
}

Это должно отобразить список, а затем наложить его на диалоговое окно хода выполнения, пока данные для списка возвращаются с сервера. И это работает хорошо. Я хотел бы обновить текст в диалоговом окне прогресса, когда сеть io готова. Это код, который реализует сеть 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
    }
}

В файле манифеста 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, поэтому я предполагаю, что что-то неправильно реализовал. Есть идеи?

Исходное сообщение обновлено фильтром намерений и набором действий при создании намерения. Все еще не работает.

Ответы [ 2 ]

2 голосов
/ 11 октября 2011

Ваш тег <receiver> должен содержать <intent-filter>, чтобы сообщить Android, какие трансляции вы хотите получить.

РЕДАКТИРОВАТЬ:

Intent не намного больше, чем контейнер для сообщения;это функция, которую вы вызываете для отправки Intent, которая определяет, какие поля вам нужно установить.

Из документов на Intent:

[Intent] можноиспользовать с startActivity для запуска Activity, broadcastIntent для отправки любым заинтересованным BroadcastReceiver компонентам и startService(Intent) или bindService(Intent, ServiceConnection, int) для связи с фоном Service.

Эти функции являются вашими опциями для отправки Intent с.startActivity и функции startService / bindService используют явные Intent s;sendBroadcast нет.

Обратите внимание, что startActivity выдает исключение, если не может найти целевой класс вашего Intent, и startService вернет null, если не сможет найтиваш целевой класс.sendBroadcast ничего такого не делает, потому что даже не смотрит на это поле.sendBroadcast "Передает данное намерение всем заинтересованным BroadcastReceivers."

Поскольку вы используете Context.sendBroadcast() для отправки своего намерения, вы должны установить действие для Intent иваш BroadcastReceiver должен иметь фильтр намерений, содержащий запись для этого действия.

0 голосов
/ 12 октября 2011

ОК. Кажется, ответ таков: невозможно использовать манифест для регистрации получателя.Если я изменю код, чтобы он использовал 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...