Android MediaPlayer return Prepare failed.: status=0x1 on device but runs in emulator

Viewed 78

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?

1 Answers

Apparently the problem is fixed by this entry:

android:usesCleartextTraffic="true"

In AndroidManifest.xml file (application section).

-- UPDATE --

Actually the problem was given by some abnormal firewall rules that rejects connections from the same host after a give number of consecutive access.

Related