簡體   English   中英

使用服務從原始背景通過多個按鈕播放多個聲音

[英]Playing multiple sounds via multiple buttons from raw in background using service

我想播放6個不同的聲音,這些聲音是由背景中的6個不同的按鈕觸發的,因此,如果應用程序在背景中,聲音會繼續播放。 當一個聲音已經在播放時,按下另一個按鈕將停止它並播放自己的聲音,敲擊相同的按鈕2K次,停止2K + 1次:再次開始。(K為非零整數)

所有代碼均已完成,並且似乎正常工作,只是播放器在一個半分鍾后停止播放。 (這不是因為內存不足),誰能告訴我我在做什么錯?

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();
        }
    }
}

和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;

    }
}

我想回答我自己的問題,以防萬一其他人遇到問題。 事實證明,Android增加了一些新功能(自Oreo以來,出於提高電池壽命的目的,對后台資源的訪問受到限制(即Android 8.0+ || API級別26))。

正如文檔所述:“現在,在后台運行的應用程序在自由訪問后台服務方面受到限制。”

因此,在這種情況下,我們將需要使用前台服務。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM