Android - Fehler "Broadcast kann nicht gesendet werden" auf einem dynamisch registrierten Broadcast-Empfäng

Ich versuche, eine relativ einfache Aufgabe auszuführen: Ich habe ein Fragment, das einen Dienst zum Abrufen von JSON von einem Remoteserver startet. Anschließend möchte ich diesen JSON-Code mithilfe eines Broadcasts an das ursprüngliche aufrufende Fragment zurückgeben, wobei der BroadcastReceiver als anonyme Klasse im Fragment definiert ist.

Jedoch, wenn ich das versuche, erhalte ich immer wieder die folgende Fehlermeldung:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.roundarch.codetest, PID: 21974
    android.app.RemoteServiceException: can't deliver broadcast
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1631)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

Code

public class Part3Fragment extends Fragment {

    PostCodeAdapter postCodeAdapter;
    ListView listView;
    BroadcastReceiver receiver;
    IntentFilter intentFilter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_part3, null);

        initialiseReceiver();

        View emptyView = (View) view.findViewById(R.id.empty_textview);
        ListView listView = (ListView) view.findViewById(R.id.part3_listview);
        listView.setEmptyView(emptyView);

        // TODO - the listview will need to be provided with a source for data

        // TODO - (optional) you can set up handling to list item selection if you wish

        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        initialiseReceiver();
        getActivity().startService(new Intent(getActivity(), Part3Service.class));
    }

    public void initialiseReceiver(){
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Bundle bundle = intent.getBundleExtra("bundle");
                ArrayList<PostCodesResult.Result> postcodes = (ArrayList<PostCodesResult.Result>) bundle.getSerializable("postcodeArray");
                updatePostcodes(postcodes);
            }
        };
        intentFilter = new IntentFilter("JSON_RECEIVED");

        getActivity().registerReceiver(receiver, intentFilter);
    }

    @Override
    public void onPause() {
        super.onPause();


    }

    private void updatePostcodes(ArrayList<PostCodesResult.Result> postcodes) {
        if (postcodes.size() > 0){
            postCodeAdapter = new PostCodeAdapter(getActivity(), R.layout.part3_listview_item, postcodes);
            listView.setAdapter(postCodeAdapter);
            postCodeAdapter.notifyDataSetChanged();
        }
    }
}

Und hier ist der Code für dasBedienung

public class Part3Service extends Service {

    private final String TAG = this.getClass().getSimpleName();

    // TODO - we can use this as the broadcast intent to filter for in our Part3Fragment
    public static final String ACTION_SERVICE_DATA_UPDATED = "com.roundarch.codetest.ACTION_SERVICE_DATA_UPDATED";

    private List<Map<String, String>> data = null;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.i(TAG, "Service has started");
        new PostCodeRetriever().execute("http://gomashup.com/json.php?fds=geo/usa/zipcode/state/IL");


        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private void updateData() {
        // TODO - start the update process for our data
    }

    private void broadcastDataUpdated(String jsonString) {
        Intent intent = new Intent();
        intent.setAction("JSON_RECEIVED");
        ArrayList<PostCodesResult.Result> postcodes = new ArrayList<>();
        if (jsonString != null) {
            Gson gson = new Gson();
            PostCodesResult result = gson.fromJson(jsonString, PostCodesResult.class);
            postcodes.addAll(result.getResult());
        }
        Bundle bundle = new Bundle();
        bundle.putSerializable("postcodeArray", postcodes);
        intent.putExtra("bundle", bundle);
        sendBroadcast(intent);
        stopSelf();
    }

    class PostCodeRetriever extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {

            Uri uri = Uri.parse(params[0]);

            String jsonString = "";

            try {
                URL postcodesUrl = new URL(uri.toString());
                InputStream inputStream = null;

                HttpURLConnection connection = (HttpURLConnection) postcodesUrl.openConnection();
                connection.connect();

                inputStream = connection.getInputStream();
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                StringBuilder stringBuilder = new StringBuilder();

                String line = "";
                while ((line = bufferedReader.readLine()) != null) {
                    stringBuilder.append(line);
                }

                stringBuilder.deleteCharAt(0);
                stringBuilder.deleteCharAt(stringBuilder.length() -1);

                jsonString = stringBuilder.toString();

                bufferedReader.close();
                inputStreamReader.close();
                inputStream.close();
                connection.disconnect();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }


            return jsonString;

        }

        @Override
        protected void onPostExecute(String jsonString) {

            broadcastDataUpdated(jsonString);
            super.onPostExecute(jsonString);
        }
    }
}

Ich habe so viele verschiedene Dinge ausprobiert: Nur die rohe JSON-Zeichenfolge über die Absicht senden, den Broadcast-Empfänger als separate Klasse definieren, die JSON in eine serialisierte ArrayList konvertieren und diese über die Absicht senden und schließlich versuchen, alles einzuschließen in einem Bündel und das Senden.

Die bizarre Sache ist, dass sehr ähnlicher Code für meine Klassenkameraden gut zu funktionieren scheint - ich sehe keine Unterschiede zwischen ihrem Code und meinem Code, die das Problem verursachen könnten (und sie können es auch nicht). Wenn ich versuche, einfach einen anderen String durch die Absicht zu senden, dann scheint das in Ordnung zu sein - der Rundfunkempfänger nimmt ihn ab und onReceive wird so aufgerufen, wie er sein sollte. Der Fehler "Broadcast kann nicht gesendet werden" scheint nur bei dem Versuch aufzutreten, diesen bestimmten Datensatz zu übermitteln, und zwar nur für mich!

Antworten auf die Frage(4)

Ihre Antwort auf die Frage