IntentService LocalBroadcastManager not reaching Receiver

夙愿已清 提交于 2019-12-08 08:49:17

问题


I'm using Android Studio 1.3, I have an IntentService setup that gathers some data and sends it out via a LocalBroadcastManager as so:

IntentService

public class cService extends IntentService {

    public cService(){
        super("cService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

            SoapPrimitive response = (SoapPrimitive)envelope.getResponse();

            Intent broadcastIntent = new Intent("action.getTestData");
            broadcastIntent.putExtra("data", response.toString());
            LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
    }
}

The above code runs, but the Broadcast is never captured.

AndroidManifest.xml

<service android:name=".services.cService"
         android:exported="false">
</service>

<receiver android:name=".services.Receiver">
</receiver>

Receiver which extends BroadcastReceiver (Never gets called)

public class Receiver extends BroadcastReceiver
{
    protected MainActivity mainActivityContext;

    public Receiver() {}

    @Override
    public void onReceive(Context context, Intent intent) {

        final String data = intent.getStringExtra("data");

        mainActivityContext.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                TextView txtData = (TextView)mainActivityContext.findViewById(R.id.textView2);
                txtData.setText(data);
            }
        });

    }
}

MainActivity onCreate()

public class MainActivity extends Activity implements View.OnClickListener{

    TextView txtData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Dummy text field that should populate with something upon
        //onReceive() executing...
        txtData = (TextView)findViewById(R.id.textView2);
        txtData.setText("Ready.");

        IntentFilter filter = new IntentFilter("action.getTestData");
        filter.addDataScheme("string"); 

        BroadcastReceiver c = new Receiver();
         LocalBroadcastManager.getInstance(this).registerReceiver(c,filter);

    }

What am I doing wrong here that's causing the Broadcast to not be received? I'm thinking it has to do with my IntentFilter?


回答1:


You may try setting android:exported=true in the <service> block of your XML. According to the docs:

http://developer.android.com/guide/topics/manifest/service-element.html#exported

The default value depends on whether the service contains intent filters. The absence of any filters means that it can be invoked only by specifying its exact class name. This implies that the service is intended only for application-internal use (since others would not know the class name). So in this case, the default value is "false". On the other hand, the presence of at least one filter implies that the service is intended for external use, so the default value is "true".

Hope this helps.




回答2:


Try this:

IntentFilter filter = new IntentFilter(cService.class);
filter.addCategory(Intent.CATEGORY_DEFAULT);
Receiver receiver = new Receiver();
registerReceiver(receiver, filter);



回答3:


I managed to fix the problem I had by incorporating BroadcastReceiver within onResume() of my MainActivity. My goal here was to simply capture that data once the Service completed retrieving all network data.

I hope this helps someone...

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.widget.Button;

    public class MainActivity extends Activity implements View.OnClickListener {

        private boolean isReceiverRegistered;
        private Button btnRetrieveRouteData;
        private BroadcastReceiver receiver;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_main);

            //UI Component Instances
            btnRetrieveRouteData =  (Button)findViewById(R.id.btnGetRouteInformation);
            btnRetrieveRouteData.setOnClickListener(this);
        }

        @Override
        protected void onResume(){
            super.onResume();
            if (!isReceiverRegistered) {
                IntentFilter intentFilter = new IntentFilter("ma.MainActivity.WebServiceReceiver.ReturnedReceivedDataFilePath");
                receiver = new BroadcastReceiver() {
                    @Override
                    public void onReceive(final Context context, Intent intent) {

                        //Get message from WebServiceReceiver Intent
                        String ReceivedDataFromIntent = intent.getStringExtra("WebServiceReceiver_ReturnedReceivedDataFilePath");

                        //Do whatever with the data received from the Service...
                    }
                };

                //Register the receiver
                isReceiverRegistered = true;
                this.registerReceiver(receiver, intentFilter);
            }
        }

        @Override
        protected void onPause(){
            super.onPause();
            if (isReceiverRegistered) {
                try {
                    unregisterReceiver(receiver);
                } catch (IllegalArgumentException e) {
                   //Handle Exception as needed...
                }
                isReceiverRegistered = false;
            }
        }

        @Override
        public void onDestroy(){
            super.onDestroy();
        }

        public void onClick(View view){
           switch(view.getId()){
               case R.id.btnGetRouteInformation:
                     CallWebService("testParam1", "testParam2");
                   break;

                default:
                    //Do nothing
                   break;
           }
        }

        private void CallWebService(String param1, String param2){

            //Begin web call to retrieve necessary data.
            ServerCaller.GetRequestForRouteWithDriverId(this, param1, param2);

            //WebServiceReceiver will get this returned data and broadcast it; received in "onResume()" here.
        }

    }

I then have another classe called WebServiceReceiver, this class will handle the result from the webservice, it will prepare the data and then create the intent that our onResume() Override method will filter and read in.

public class WebServiceReceiver extends BroadcastReceiver
{
    public WebServiceReceiver() {}


    @Override
    public void onReceive(Context context, Intent intent) {

        String action = intent.getAction();

        if (action.equals("Helper_GetRequestForData")){
            //Retrieve the data from incoming Intent that web service submitted
            final String ReceivedDataFilePathThatContainsData = intent.getStringExtra("Helper_GetRequestForData");

            Intent responder = new Intent("ma.MainActivity.WebServiceReceiver.ReturnedReceivedDataFilePath");
            responder.putExtra("WebServiceReceiver_ReturnedReceivedDataFilePath", ReceivedDataFilePathThatContainsData);
            context.sendBroadcast(responder);
        }
    }

}



回答4:


Things started working for me once I replaced

registerReceiver(receiver, filter);

with

LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);

above. Of course, this only applies if you're using a local service, internal to your app.



来源:https://stackoverflow.com/questions/32212327/intentservice-localbroadcastmanager-not-reaching-receiver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!