0

I want to play 6 different sounds triggered by 6 different buttons in background, so that if the app is on background the sound keeps playing. When one sound is already playing, pressing another button will stop it and play its own sound, Tapping the same button 2K times it stops, 2K+1 times: starts again.. (K is a non-null integer)

All of the code is done and seems to be working correctly, except that the player stops after one and a half minute. (This is not because of low memory) Can anyone please tell me what am I doing wrong?

public class PlayService extends Service {

    private MediaPlayer player;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {

        super.onCreate();
        player = new MediaPlayer();

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        int btnId = intent.getExtras().getInt("ID");

        Toast.makeText(this, "onStart service" + btnId, Toast.LENGTH_SHORT).show();

        selectResId(btnId);

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "Service destroyed", Toast.LENGTH_SHORT).show();
        if (player != null) {
            player.stop();
            player.release();
        }
        player = null;
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        Toast.makeText(this, "Low mem", Toast.LENGTH_SHORT).show();
    }

    private void selectResId(int resId){
        switch (resId){
            case 1: playMediaFromResource(R.raw.number_one);
            case 2: playMediaFromResource(R.raw.number_two);
            case 3: playMediaFromResource(R.raw.number_three);
            case 4: playMediaFromResource(R.raw.number_four);
            case 5: playMediaFromResource(R.raw.number_five);
            case 6: playMediaFromResource(R.raw.number_six);
            default: break;
        }
    }

    private void playMediaFromResource(int resId) {
        Uri mediaPath = Uri.parse("android.resource://" + getPackageName() + "/" + resId);
        try {
            player.setDataSource(getApplicationContext(), mediaPath);
            player.setLooping(true);
            player.prepare();
            player.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

And the MainActivity:

public class MainActivity extends AppCompatActivity {

    private Button btnStart1;
    private Button btnStart2;
    private Button btnStart3;
    private Button btnStart4;
    private Button btnStart5;
    private Button btnStart6;
    private Intent intent;

    private int previousID = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewsByIds();
        setOnClickListeners();

    }


    private void findViewsByIds() {

        btnStart1 = findViewById(R.id.btn_start_1);
        btnStart2 = findViewById(R.id.btn_start_2);
        btnStart3 = findViewById(R.id.btn_start_3);
        btnStart4 = findViewById(R.id.btn_start_4);
        btnStart5 = findViewById(R.id.btn_start_5);
        btnStart6 = findViewById(R.id.btn_start_6);

    }

    private void setOnClickListeners() {

        btnStart1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                checkIntentState(1);

            }
        });

        btnStart2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                checkIntentState(2);

            }
        });

        btnStart3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                checkIntentState(3);

            }
        });

        btnStart4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                checkIntentState(4);

            }
        });

        btnStart5.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                checkIntentState(5);

            }
        });

        btnStart6.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                checkIntentState(6);

            }
        });
    }

    private void checkIntentState(int ID) {
        if (intent == null) {
            createNewIntent(ID);
        } else {
            stopService(intent);
            intent = null;
            if (ID != previousID) {
                createNewIntent(ID);
            }
        }
    }


    private void createNewIntent(int ID) {
        intent = new Intent(MainActivity.this, PlayService.class);
        intent.putExtra("ID", ID);
        startService(intent);
        previousID = ID;

    }
}
Ara Mkrtchyan
  • 497
  • 6
  • 12
  • Possible duplicate of [Android - implementing startForeground for a service?](https://stackoverflow.com/questions/6397754/android-implementing-startforeground-for-a-service) – TheWanderer Jan 09 '19 at 21:20
  • Are you saying that I shall use a foreground service? Also, I want to understand what exactly is wrong here. – Ara Mkrtchyan Jan 09 '19 at 21:41
  • 1
    You need to use a foreground Service. Your Service is being killed. And if you don't use a foreground Service, your app will crash on Oreo devices. – TheWanderer Jan 09 '19 at 21:42

1 Answers1

0

I want to answer to my own question just in case anyone else runs into the problem. It turns out, that Android added some new features (restricted access to background resources for battery life improvement purposes since Oreo(i.e. Android 8.0+ || API level 26)).

As the documentation says: "Apps that are running in the background now have limits on how freely they can access background services."

So, in this case we will need to use foreground services.

Ara Mkrtchyan
  • 497
  • 6
  • 12