Android: 在服务中测试 MediaPlayer
Android: Testing MediaPlayer inside a service
在我的应用程序中,有一项服务的工作是在启动时 play/stop 播放音频。为此,我正在使用 MediaPlayer
。
服务运行良好,现在我正在为其编写测试。
我正在使用 Robolectric 的 buildService
方法来创建服务。
问题是 mediaplayer
在我的例子中总是出现空值。
这是我的服务的 onStartCommand
方法:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (ACTION_START.equals(intent.getAction())) {
try {
mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.holdmusic);
} catch (Exception e) {
Log.e(TAG, "not able to prepare media player", e);
Toast.makeText(this, R.string.not_able_prepare_media_player, Toast.LENGTH_SHORT).show();
stopSelf();
return START_NOT_STICKY;
}
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mediaPlayer.setOnCompletionListener(mediaPlayer -> onStop()); // mediaplayer always comes out to be null here in my test
mediaPlayer.start();
mediaSession = new MediaSession(getApplicationContext(), getString(R.string.app_name));
showNotification();
return START_STICKY;
} else if (ACTION_STOP.equals(intent.getAction())) {
onStop();
return START_NOT_STICKY;
} else {
// called with unknown action, should not happen
stopSelf();
return START_NOT_STICKY;
}
}
这是我的测试:
@Test
public void testActionStart() {
Intent serviceIntent =
new Intent(ApplicationProvider.getApplicationContext(), MediaPlayerService.class);
serviceIntent.setAction(MediaPlayerService.ACTION_START);
MediaPlayerService service =
Robolectric.buildService(MediaPlayerService.class, serviceIntent)
.create()
.startCommand(0, 0)
.get();
ShadowService shadowService = Shadow.extract(service);
assertThat(service.isPlaying()).isTrue();
assertThat(shadowService.getLastForegroundNotification()).isNotNull();
}
谁能帮我理解为什么 mediaplayer 结果为空。我想可能是因为它使用了 robolectric 环境中不可用的本机方法。如果是这样,测试服务行为的最佳方法是什么?
经过 https://github.com/robolectric/robolectric/issues/3855 和调试一段时间后,我意识到我们必须手动填充 ShadowMediaPlayer
中的 MediaInfo
对象才能工作。
这是我所做的(现在效果很好):
在实例化播放器之前添加了这一行:
ShadowMediaPlayer.addMediaInfo(
DataSource.toDataSource(
"android.resource://"
+ getApplicationContext().getPackageName()
+ "/"
+ <resource id of audio file>),
new MediaInfo(17, 0));
在我的应用程序中,有一项服务的工作是在启动时 play/stop 播放音频。为此,我正在使用 MediaPlayer
。
服务运行良好,现在我正在为其编写测试。
我正在使用 Robolectric 的 buildService
方法来创建服务。
问题是 mediaplayer
在我的例子中总是出现空值。
这是我的服务的 onStartCommand
方法:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (ACTION_START.equals(intent.getAction())) {
try {
mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.holdmusic);
} catch (Exception e) {
Log.e(TAG, "not able to prepare media player", e);
Toast.makeText(this, R.string.not_able_prepare_media_player, Toast.LENGTH_SHORT).show();
stopSelf();
return START_NOT_STICKY;
}
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mediaPlayer.setOnCompletionListener(mediaPlayer -> onStop()); // mediaplayer always comes out to be null here in my test
mediaPlayer.start();
mediaSession = new MediaSession(getApplicationContext(), getString(R.string.app_name));
showNotification();
return START_STICKY;
} else if (ACTION_STOP.equals(intent.getAction())) {
onStop();
return START_NOT_STICKY;
} else {
// called with unknown action, should not happen
stopSelf();
return START_NOT_STICKY;
}
}
这是我的测试:
@Test
public void testActionStart() {
Intent serviceIntent =
new Intent(ApplicationProvider.getApplicationContext(), MediaPlayerService.class);
serviceIntent.setAction(MediaPlayerService.ACTION_START);
MediaPlayerService service =
Robolectric.buildService(MediaPlayerService.class, serviceIntent)
.create()
.startCommand(0, 0)
.get();
ShadowService shadowService = Shadow.extract(service);
assertThat(service.isPlaying()).isTrue();
assertThat(shadowService.getLastForegroundNotification()).isNotNull();
}
谁能帮我理解为什么 mediaplayer 结果为空。我想可能是因为它使用了 robolectric 环境中不可用的本机方法。如果是这样,测试服务行为的最佳方法是什么?
经过 https://github.com/robolectric/robolectric/issues/3855 和调试一段时间后,我意识到我们必须手动填充 ShadowMediaPlayer
中的 MediaInfo
对象才能工作。
这是我所做的(现在效果很好):
在实例化播放器之前添加了这一行:
ShadowMediaPlayer.addMediaInfo(
DataSource.toDataSource(
"android.resource://"
+ getApplicationContext().getPackageName()
+ "/"
+ <resource id of audio file>),
new MediaInfo(17, 0));