2017-09-21 13 views
1

私はアラームアプリケーションを作成しています。私はBroadcastReceiverを持っています。私はAlarmServiceを使ってアラームを処理しています。Android BroadcastReceiver:ネットワークコールを実行してサウンドを再生

BroadcastReceiverでは、ネットワークコールを実行してから、いくつかの条件が満たされた場合は、SoundPoolを使用してサウンドを再生します。

しかし、BroadcastReceiverを実行しているスレッドではネットワークコールが許可されていないため、NetworkOnMainThreadExceptionが表示されています。私はIntentServiceを使ってみました。これはバックグラウンドスレッドで実行されています。バックグラウンドスレッドはネットワーク呼び出しの問題を回避します。しかし、私はそれからサウンドを再生するには、管理、および取得していない:

W/MessageQueue: Handler (android.media.SoundPool$EventHandler) {d64695a} sending message to a Handler on a dead thread 

java.lang.IllegalStateException: Handler (android.media.SoundPool$EventHandler) {d64695a} sending message to a Handler on a dead thread 

私の理解では、サウンドを再生しSoundPoolは非同期に再生され、スレッドが死亡したということです。

BroadcastReceiverから、ネットワークコールを実行してSoundPoolを呼び出す方法はありますか。

UPDATE

これは私がBroadcastReceiver内部のHTTP呼び出しを行うにしようとしていますコードの最初のバージョンです。その後、私は受け取っている例外です。ここでは、サウンドを再生する部分は決してここに到達しませんが、HTTPコールをスキップすると動作します。

package com.marksoft.alarm.alarm.events; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.media.AudioAttributes; 
import android.media.SoundPool; 

import com.marksoft.alarm.R; 
import com.marksoft.alarm.alarm.data.IAlarmRepository; 
import com.marksoft.alarm.alarm.data.InMemoryAlarmRepository; 
import com.marksoft.alarm.backend.myApi.model.Prediction; 
import com.marksoft.alarm.tfl.TflService; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import java.util.List; 

public class BusStopCheckReceiver extends BroadcastReceiver { 

    private static final Logger LOG = LoggerFactory.getLogger(com.marksoft.alarm.alarm.events.BusStopCheckReceiver.class); 
    private SoundPool soundPool; 
    private TflService tflService = new TflService(); 
    private IAlarmRepository alarmRepository = InMemoryAlarmRepository.getInstance(); 

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

     // ... 
     if(shouldSoundAlarm()) { 
      playSound(context); 
     } 
     // ... 
    } 

    private boolean shouldSoundAlarm() { 
     // HTTP call 
     List<Prediction> predictions = tflService.getBusStopArrivals(alarm.getStopId()); 

     for(Prediction prediction : predictions) { 
      LOG.info("Checking prediction {}", prediction); 
      if(...) { 
       LOG.info("Should sound alarm for prediction {}", prediction); 
       return true; 
      } 
     } 
     return false; 
    } 

    private int playSound(final Context context) { 
     // Load the sound 
     AudioAttributes attributes = new AudioAttributes.Builder() 
       .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) 
       .build(); 
     soundPool = new SoundPool.Builder() 
       .setAudioAttributes(attributes).build(); 
     soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() { 
      @Override 
      public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { 
       soundPool.play(sampleId, 1, 1, 1, 0, 1f); 
       LOG.info("Played sound"); 
      } 
     }); 
     return soundPool.load(context, R.raw.bell1, 1); 
    } 
} 

と例外:

09-21 13:53:05.020 3218-3218/com.marksoft.alarm D/AndroidRuntime: Shutting down VM 


     --------- beginning of crash 
     09-21 13:53:05.021 3218-3218/com.marksoft.alarm E/AndroidRuntime: FATAL EXCEPTION: main 
     Process: com.marksoft.alarm, PID: 3218 
     java.lang.RuntimeException: Unable to start receiver com.marksoft.alarm.alarm.events.BusStopCheckReceiver: android.os.NetworkOnMainThreadException 
     at android.app.ActivityThread.handleReceiver(ActivityThread.java:3018) 
     at android.app.ActivityThread.-wrap18(ActivityThread.java) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1544) 
     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:866) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 
     Caused by: android.os.NetworkOnMainThreadException 
     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303) 
     at com.android.org.conscrypt.Platform.blockGuardOnNetwork(Platform.java:300) 
     at com.android.org.conscrypt.OpenSSLSocketImpl.shutdownAndFreeSslNative(OpenSSLSocketImpl.java:1194) 
     at com.android.org.conscrypt.OpenSSLSocketImpl.close(OpenSSLSocketImpl.java:1189) 
     at com.android.okhttp.Connection.closeIfOwnedBy(Connection.java:148) 
     at com.android.okhttp.OkHttpClient$1.closeIfOwnedBy(OkHttpClient.java:77) 
     at com.android.okhttp.internal.http.HttpConnection.closeIfOwnedBy(HttpConnection.java:137) 
     at com.android.okhttp.internal.http.HttpTransport.disconnect(HttpTransport.java:135) 
     at com.android.okhttp.internal.http.HttpEngine.disconnect(HttpEngine.java:573) 
     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.disconnect(HttpURLConnectionImpl.java:134) 
     at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.disconnect(DelegatingHttpsURLConnection.java:93) 
     at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.disconnect(HttpsURLConnectionImpl.java) 
     at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:99) 
     at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981) 
     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419) 
     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352) 
     at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469) 
     at com.marksoft.alarm.tfl.TflService.getBusStopArrivals(TflService.java:78) 
     at com.marksoft.alarm.alarm.events.BusStopCheckReceiver.shouldSoundAlarm(BusStopCheckReceiver.java:70) 
     at com.marksoft.alarm.alarm.events.BusStopCheckReceiver.onReceive(BusStopCheckReceiver.java:55) 
     at android.app.ActivityThread.handleReceiver(ActivityThread.java:3011) 
     at android.app.ActivityThread.-wrap18(ActivityThread.java)  
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1544)  
     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:866)  
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)  
+0

私たちは推測する必要がないので、コードを表示することができます –

+0

コードの最初のバージョンからスニペットを追加しました。ここでは、HTTP呼び出しを行い、 'BroadcastReceiver ' –

+0

tflService.getBusStopArrivalsとは何ですか? –

答えて

1

はいあなたはIntentServiceを開始することができ、この目的のサービスの完了時に、あなたが再びsendBroadCastでbroadcastReceiverを開始し、いくつかの余分なを入れて、そのonReceiveその方法が余分に取得することができますそれに合わせて音を鳴らしてください。 これにより、ネットワーク通話を同期してサウンドを再生することができます。

+0

これはあなたに役立つ答えです.. ?? –

関連する問題