I'm trying to play an audio streaming from a remote http uri trough MediaPlayer.
The code seems to work fine in the emulator audio stream is played (but there's some noise over it) if I try to play on the device the .prepare() call fails throwing an IO exception. The message reports: status=0x1 . The only articles related with this error I found where talking about reading/writing permissions over files and I think this's not the case, some other where related to wrong sequence of calls (.setDataSource, .prepare(), .start()) neither this should be my problem.
This's the code I'm using:
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);
}
}
Where's the error? Is possible to fix it?
Why the emulator is able to run it without errors?
--- UPDATE ---
same error using .prepareAsync()
--- UPDATE ---
On the very same hardware configuration (Samsung Galaxy S9 stock), where the application worked with the simple fix when uploaded trough adb over usb link once the app is signed in release variant it stopped working and I got again the same error code reported above.
On different hardware like Huawei P30 it works (installed as a signed release .apk).
Can this depend on a firewall rule?