私はアラームアプリケーションを作成しています。私は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)
私たちは推測する必要がないので、コードを表示することができます –
コードの最初のバージョンからスニペットを追加しました。ここでは、HTTP呼び出しを行い、 'BroadcastReceiver ' –
tflService.getBusStopArrivalsとは何ですか? –