Android 媒体播放器返回准备失败:状态=0x1,但在模拟器中运行



我正在尝试通过MediaPlayer播放来自远程httpuri的音频流。 如果我尝试在设备上播放,该代码似乎在模拟器音频流播放中工作正常(但上面有一些噪音(,.prepare()调用失败引发 IO 异常。消息报告:status=0x1。我发现与此错误相关的唯一文章在谈论对文件的读取/写入权限时,我认为情况并非如此,其他一些与错误的调用序列(.setDataSource,.prepare((,.start(((相关的文章都不应该是我的问题。

这是我正在使用的代码:

public class MainActivity extends AppCompatActivity {
public static final String KEY_ADDRESS = "address";
private static final int REQUEST_INTERNET = 21;
private ImageButton exit_button;
private ImageButton stop_button;
private ImageButton play_button;
private MediaPlayer media_player;
private String uri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
boolean _skip_init = false;
int check_internet = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.INTERNET);
if (check_internet != PackageManager.PERMISSION_GRANTED) {
Log.i(getClass().getName(), "asking for internet access permission");
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.INTERNET},
REQUEST_INTERNET);
_skip_init = true;
}
getSettings(this); // set uri 
exit_button = findViewById(R.id.exit_button);
play_button = findViewById(R.id.play_button);
stop_button = findViewById(R.id.stop_button);
exit_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
play_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//TODO: start play
if(media_player!=null) {
media_player.start();
disablePlay();
}
}
});
stop_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//TODO: stop play
if(media_player!=null){
media_player.stop();
media_player.reset();
initStreaming(uri);
enablePlay();
}
}
});
play_button.setEnabled(false);
stop_button.setEnabled(false);
play_button.setAlpha(0.5f);
stop_button.setAlpha(0.5f);
if(!_skip_init) {
initMediaPlayer(this);
initStreaming(uri);
}
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if ((requestCode == REQUEST_INTERNET) && (grantResults.length > 0)) {
for (int i = 0; i < permissions.length; i++)
if ((grantResults[i] == PackageManager.PERMISSION_GRANTED)) {
Log.i(getClass().getName(), permissions[i] + " permission granted");
if (Manifest.permission.INTERNET.equals(permissions[i])) {
initMediaPlayer(this);
initStreaming(uri);
}
}
}
}
private void initMediaPlayer(@NonNull final Context context) {
media_player = new MediaPlayer();
media_player.setAudioStreamType(AudioManager.STREAM_MUSIC);
media_player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
Log.d(getClass().getName(), "onPreparedListener");
play_button.setEnabled(true);
play_button.setAlpha(1f);
}
});
media_player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Log.d(getClass().getName(), "onCompletionListener");
Toast.makeText(context, getString(R.string.streaming_completed), Toast.LENGTH_LONG).show();
}
});
}
private void initStreaming(@NonNull final String uri) {
new Thread(
new Runnable() {
@Override
public void run() {
try {
media_player.setDataSource(uri);
media_player.prepareAsync();
} catch (Throwable e) {
Log.e(getClass().getName(), "Exception: " + e.getMessage());
}
}
}
).start();
}
@Override
protected void onDestroy() {
//TODO: stop and free resources?
Log.d(getClass().getName(), "onDestroy");
if(media_player!=null && media_player.isPlaying())
media_player.stop();
super.onDestroy();
}
private void enablePlay() {
play_button.setEnabled(true);
stop_button.setEnabled(false);
play_button.setAlpha(1f);
stop_button.setAlpha(0.5f);
}
private void disablePlay() {
play_button.setEnabled(false);
stop_button.setEnabled(true);
play_button.setAlpha(0.5f);
stop_button.setAlpha(1f);
}
}

错误在哪里?可以修复它吗?

为什么模拟器能够毫无错误地运行它?

---更新---

使用.prepareAsync()时出现相同的错误

---更新---

在完全相同的硬件配置(三星 Galaxy S9 库存(上,应用程序在通过 USB 链接adb上传时使用简单的修复程序工作,一旦应用程序登录发布变体,它就会停止工作,我再次收到上面报告的相同错误代码。 在华为P30等不同硬件上,它可以工作(作为签名版本.apk安装(。 这是否取决于防火墙规则?

显然,此条目解决了该问题:

android:usesCleartextTraffic="true"

AndroidManifest.xml文件(应用程序部分(中。

--更新--

实际上,问题是由一些异常的防火墙规则引起的,这些规则在给定的连续访问次数后拒绝来自同一主机的连接。

最新更新